-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Chain notifier implementations to handle reorgs #410
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a dumb question, but isn't a reorg possible at a block that's not the latest? Should this call DisconnectTip
at each block height between the current currentHeight
and update.blockHeight
(inclusive)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btcd
and neutrino
reorgs both fire a disconnectblock
notification for each block disconnected in a reorg. Makes it more convenient to work with than bitcoind
's notifications, which only notify you of the latest block in such a situation.
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Admittedly I'm not totally familiar with how btcd callbacks fire, but if a reorg happens, I imagine that you'd probably get callbacks for new blocks and disconnected blocks around the same time. If the new block callback is processed first, won't this cause the block to get lost as the txConfNotifier doesn't know that a reorg has occurred, so will drop the update?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btcd
fires disconnectblock
notifications in reverse order, and then fires connectblock
for each new connected block in order. The same goes for neutrino
, which intentionally replicates the behavior.
01477de
to
63dd4ff
Compare
63dd4ff
to
dee1efe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good in my opinion!
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
notification
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be written
select {
case <-confirmed:
case <-time.After(1 * time.Second):
}
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe check that height is at miner2's height?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? Which height?
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add comment that this means the tx is unconfirmed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete instead?
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This if else statement needs some more comments, not obvious what's going on imho :P
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an explanation would be nice
038cb70
to
cc5a880
Compare
cc5a880
to
2eadbbb
Compare
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can eliminate the nesting here by inserting a continue
after the first case completes.
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment here about avoiding the nesting by using a continue
after the first clause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, technically true, but I don't think it makes sense in this context. The first block handles the case of a block connection, the second handles a block disconnection. The logic is symmetrical (like it would make sense if the if was !update.connect
and the blocks were flipped), so I'd rather have them at the same level of indentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the nesting will reduce the number of lines in the diff. It's not a block as it's mostly a style thing, but in the codebase we generally try to limit the degree of nesting in a given function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments (and also the code itself) can be re-flowed now to take advantage of the increased column limit due to the elimination of the nesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A similar nesting optimization can be made here: we'd instead check for !ok
above and continue if so.
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also close a quit channel localized to the TxConfNotifier
. All sends above would select on this quit channel to ensure things can be shutdown gracefully.
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment here to indicate that this means the transaction wasn't yet found in the mempool? Thanks!
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there's no need for an additional type in this case? As is, it'll just replicate the existing struct with a diff name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is right, but I kept it for symmetry with neutrinonotify. I don't believe there's any overhead to having this wrapper struct.
chainntnfs/interface_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First portion of sentence seems to be cut off?
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
e1af5da
to
a7a6e8a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nearly there, have one last round of comments.
I'll update one of my testnet nodes to start running this patch to see if any issues crop up over the next few days.
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, it seems like we shouldn't accept this block as it may cause us to miss notifications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a continue after this line. The TxConfNotifier would have returned an error anyway.
chainntnfs/btcdnotify/btcd.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping on comment about eliminating unnecessary nesting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I personally think the logic is less clear now, but it's your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the nesting will reduce the number of lines in the diff. It's not a block as it's mostly a style thing, but in the codebase we generally try to limit the degree of nesting in a given function.
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Master was recently updated to always log whenever a confirmation is dispatched. Ideally this patch replicates the existing set of logs exactly to mirror the prior operation.
chainntnfs/txconfnotifier.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified a great bit by using a second level of map which is based on the client ID.
chainntnfs/txconfnotifier_test.go
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments on these new added tests are virtually non existent.
Tests are failing for both btcd and neutrino notifiers.
This does not implement full handling of block disconnections, but ensures that all chain updates are processed in order.
All implementations of the ChainNotifier interface support registering notifications on transaction confirmations. This struct is intended to be used internally by ChainNotifier implementations to handle much of this logic.
Also fix overflow issue with reorg handling.
a4c5985
to
fa458c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👾
This refactors the transaction confirmation watching logic into a shared module and implements correct handling of chain reorganizations.
Depends on #360.