diff --git a/blockchain/chain.go b/blockchain/chain.go index 389bcaec..eaf8b49f 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -1380,7 +1380,6 @@ func New(config *Config) (*BlockChain, error) { db: config.DB, chainParams: params, timeSource: config.TimeSource, - notifications: make([]NotificationCallback, 0), sigCache: config.SigCache, indexManager: config.IndexManager, minRetargetTimespan: targetTimespan / adjustmentFactor, diff --git a/blockchain/notifications.go b/blockchain/notifications.go index 728b2224..25cc4f1f 100644 --- a/blockchain/notifications.go +++ b/blockchain/notifications.go @@ -71,12 +71,11 @@ func (b *BlockChain) Subscribe(callback NotificationCallback) { // caller requested notifications by providing a callback function in the call // to New. func (b *BlockChain) sendNotification(typ NotificationType, data interface{}) { - b.notificationsLock.RLock() - defer b.notificationsLock.RUnlock() - // Generate and send the notification. n := Notification{Type: typ, Data: data} + b.notificationsLock.RLock() for _, callback := range b.notifications { callback(&n) } + b.notificationsLock.RUnlock() } diff --git a/blockchain/notifications_test.go b/blockchain/notifications_test.go index 0e708fc6..672f61b8 100644 --- a/blockchain/notifications_test.go +++ b/blockchain/notifications_test.go @@ -11,7 +11,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" ) -// Test that notification callbacks are fired on events. +// TestNotifications ensures that notification callbacks are fired on events. func TestNotifications(t *testing.T) { blocks, err := loadBlocks("blk_0_to_4.dat.bz2") if err != nil { @@ -19,33 +19,34 @@ func TestNotifications(t *testing.T) { } // Create a new database and chain instance to run tests against. - chain, teardownFunc, err := - chainSetup("notifications", &chaincfg.MainNetParams) + chain, teardownFunc, err := chainSetup("notifications", + &chaincfg.MainNetParams) if err != nil { t.Fatalf("Failed to setup chain instance: %v", err) } defer teardownFunc() notificationCount := 0 - callback := func(notification *blockchain.Notification) { if notification.Type == blockchain.NTBlockAccepted { notificationCount++ } } - // Register callback 3 times then assert it is called three times - chain.Subscribe(callback) - chain.Subscribe(callback) - chain.Subscribe(callback) + // Register callback multiple times then assert it is called that many + // times. + const numSubscribers = 3 + for i := 0; i < numSubscribers; i++ { + chain.Subscribe(callback) + } _, _, err = chain.ProcessBlock(blocks[1], blockchain.BFNone) if err != nil { t.Fatalf("ProcessBlock fail on block 1: %v\n", err) } - if notificationCount != 3 { - t.Fatalf("Expected notification callback to be executed 3 times, found %d", - notificationCount) + if notificationCount != numSubscribers { + t.Fatalf("Expected notification callback to be executed %d "+ + "times, found %d", numSubscribers, notificationCount) } }