From 2ceb6418e7ea10d0e17ec6fe53bc78ad1c959680 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Wed, 17 Jun 2015 22:19:51 -0400 Subject: [PATCH] Notify mined transactions before connected block. This allows clients watching for both to know when all mined transaction notifications for the block have been received. Otherwise, clients would be aware that there is a new block, see the exact same block hash/height in the next tx notifications, but never know when all txs from the block have been received and processed. This fixes a synchronization issue in btcwallet where the wallet would mark itself synced to some block height before any of those blocks' transactions were processed. If the RPC connection is lost between sending the blockconnected notification and receiving the last transaction notification, the wallet would not know of this and continue with missing transactions. --- docs/json_rpc_api.md | 2 +- rpcwebsocket.go | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index a46fd6d3..b331059f 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -680,7 +680,7 @@ user. Click the method name for further details such as parameter and return in |Method|notifyblocks| |Notifications|[blockconnected](#blockconnected) and [blockdisconnected](#blockdisconnected)| |Parameters|None| -|Description|Request notifications for whenever a block is connected or disconnected from the main (best) chain.| +|Description|Request notifications for whenever a block is connected or disconnected from the main (best) chain.
NOTE: If a client subscribes to both block and transaction (recvtx and redeemingtx) notifications, the blockconnected notification will be sent after all transaction notifications have been sent. This allows clients to know when all relevant transactions for a block have been received.| |Returns|Nothing| [Return to Overview](#ExtensionRequestOverview)
diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 665fda72..e97e9d22 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -293,20 +293,19 @@ out: switch n := n.(type) { case *notificationBlockConnected: block := (*btcutil.Block)(n) - if len(blockNotifications) != 0 { - m.notifyBlockConnected(blockNotifications, - block) - } // Skip iterating through all txs if no // tx notification requests exist. - if len(watchedOutPoints) == 0 && len(watchedAddrs) == 0 { - continue + if len(watchedOutPoints) != 0 || len(watchedAddrs) != 0 { + for _, tx := range block.Transactions() { + m.notifyForTx(watchedOutPoints, + watchedAddrs, tx, block) + } } - for _, tx := range block.Transactions() { - m.notifyForTx(watchedOutPoints, - watchedAddrs, tx, block) + if len(blockNotifications) != 0 { + m.notifyBlockConnected(blockNotifications, + block) } case *notificationBlockDisconnected: