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.
This commit is contained in:
Josh Rickmar 2015-06-17 22:19:51 -04:00
parent a1bd15e7c2
commit 2ceb6418e7
2 changed files with 9 additions and 10 deletions

View file

@ -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.<br />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)<br />

View file

@ -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: