Skip to content

Conversation

@jnewbery
Copy link
Contributor

@jnewbery jnewbery commented Nov 22, 2019

ConnectTrace was introduced in 6fdd43b
when the SyncTransactions signal needed to be fired outside the cs_main
scope. The CValidationInterface is now asynchronous and signals can be
fired while holding cs_main. Remove the ConnectTrace struct that needs
to be passed up and down the stack and just fire BlockConnected()
directly in ConnectTip().

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 22, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

No conflicts as of last run.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK.

Not sure about the wording of commit message, signals can be fired while holding cs_main, would say something more like callbacks can be scheduled while holding cs_main, at a later timer, the scheduler thread may execute them without regard to holding cs_main or not.

@jnewbery
Copy link
Contributor Author

Thanks @ariard . I agree with you about the commit message. I've reworded along the lines you suggested.

@jnewbery jnewbery force-pushed the 2019-11-remove-connect-trace branch from 6b04c24 to aa882b2 Compare November 26, 2019 14:21
@jnewbery jnewbery changed the title Validation: Remove ConnectTrace and PerBlockConnectTrace WIP: Validation: Remove ConnectTrace and PerBlockConnectTrace Jan 2, 2020
Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK.

Nice simplification and code removal that builds on the work in #17477.

Copy link
Member

@jonatack jonatack Jan 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you need to retouch this PR: perhaps add code documentation here like that for GetMainSignals().BlockDisconnected (or GetMainSignals().ChainStateFlushed or GetMainSignals().UpdatedBlockTip)

git grep -C1 "0-confirmed or conflicted"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fjahr
Copy link
Contributor

fjahr commented Jan 22, 2020

Concept ACK. Change seems fine but will wait with code review until #17477 is finalized and merged.

@jnewbery
Copy link
Contributor Author

Closing for now. No need for this to be open while #17477 is not yet merged. Will reopen when #17477 is merged.

@jnewbery jnewbery closed this Mar 13, 2020
ConnectTrace was introduced in 6fdd43b
when the SyncTransactions signal needed to be fired outside the cs_main
scope. The CValidationInterface is now asynchronous and callbacks can be
scheduled without holding cs_main. The scheduler thread can execute the
callback later without regard to cs_main.

Remove the ConnectTrace struct that needs to be passed up and down the
stack and just fire BlockConnected() directly in ConnectTip().
@jnewbery jnewbery reopened this Mar 19, 2020
@jnewbery jnewbery force-pushed the 2019-11-remove-connect-trace branch from aa882b2 to ab00be0 Compare March 19, 2020 20:46
@maflcko
Copy link
Member

maflcko commented Mar 19, 2020

Run ci

@maflcko maflcko closed this Mar 19, 2020
@maflcko maflcko reopened this Mar 19, 2020
@maflcko
Copy link
Member

maflcko commented Mar 19, 2020

There is a GitHub corruption: GitHub payload is missing a merge commit (mergeable_state: "blocked", merged: false)

@maflcko maflcko closed this Mar 19, 2020
@maflcko maflcko reopened this Mar 19, 2020
@maflcko
Copy link
Member

maflcko commented Mar 19, 2020

Ok, this was stupid. Ci is running now

Concept ACK

@jnewbery jnewbery changed the title WIP: Validation: Remove ConnectTrace and PerBlockConnectTrace Validation: Remove ConnectTrace and PerBlockConnectTrace Mar 22, 2020
@jnewbery
Copy link
Contributor Author

#17477 is now merged. Re-opened this PR and rebased it on master.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing code is fine, but I'd like to see the documentation updated a bit more. This will also explain why it is safe to reorganize the signals as a result of the changes in this pull request.

Concept ACK ab00be0, removing code is my favorite! Though, needs some doc updated, I think 🎌

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Concept ACK ab00be08e8e4371bf1483d139ecb50dacba40e0a, removing code is my favorite! Though, needs some doc updated, I think 🎌
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUi1Xwv8C0bXBK8kwoBLkKTv34M+YT29ESnNrB2kRI95LUZ1J/sXyzIR7nU39wZz
y+/w7cGwxVAITspBSctzKsu42BmrQLs9h4YVYLZLJEmoybHggrvm6c331xMwPexQ
Ktcozmee8qH5i+B0Pqyusk39Jnq/j6S2pm9ahgCh0woypucZWh27Rrjfg/YAgV6i
tbnhe0SY/FFffCH2d9vCFy/HPfPy+ZUSKQOLjY06P+DAJA7NBFzmddKMR7pOp+NB
jGA4RzcqYqACBmjh8WabTWoDf2hgYMyklMYe/HyaUE0Vg1WtYjJf3qapeeFtkMfx
iiGoO+HiASHvqi18Q0489o6nuDhWCIqpKkXl18+hdWvSbiNkySqd7KeWfPEU6s9G
SbEuImgxMJa7KbWkPlsjZxJKPStj8EP9zQr1NaVKt85E+MTCQAgrLj5kZL0/g9Ra
IOfg2RntWbOOqyE3AlT376IAk3sMvhzJZDxWQGhbRMQ4ew1ut+phojsylFGDNyVB
pJVLAPyQ
=fKV2
-----END PGP SIGNATURE-----

Timestamp of file with hash 33cca684633289f50bf74baf0a39711a82c5a0b6fcd6d62d0dc47653f74fa2fa -

// blocks are added after all the conflicted transactions have
// been filled in. Thus, the last entry should always be an empty
// one waiting for the transactions from the next block. We pop
// the last entry here to make sure the list we return is sane.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to other reviewers: This comment obviously no longer applies after 312d27b

* The block is added to connectTrace if connection succeeds.
*/
bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool)
bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, DisconnectedBlockTransactions &disconnectpool)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style-nit:

Suggested change
bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, DisconnectedBlockTransactions &disconnectpool)
bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, DisconnectedBlockTransactions& disconnectpool)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the wallet is using BlockConnected to determine when it is synced (BlockUntilSyncedToCurrentChain()). This is broken now.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK ab00be0

@MarcoFalke can you describe your point further ? IIRC BlockUntilSyncedToCurrentChain waits until scheduler queue being drained before letting the wallet moving forward. From where we shot BlockConnected shouldn't change anything ?

{
LOCK2(cs_main, ::mempool.cs); // Lock transaction pool for at least as long as it takes for connectTrace to be consumed
// Do not unlock cs_main or mempool until we've made forward
// progress (with the exception of shutdown due to hardware issues,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: define forward progress (chain tip is the valid most-work chain or most-work chain has been found invalid)


for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
assert(trace.pblock && trace.pindex);
GetMainSignals().BlockConnected(trace.pblock, trace.pindex);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it change anything for BlockConnected subscribers ? In case of block connections burst or reorgs, instead of receiving the diff at once after full validation, subscribers will now receive block connection after each individual validation in ConnectTip (assuming scheduler catch up). I think it's slightly better because discrepancy is shorter but likely a really marginal case.

@maflcko
Copy link
Member

maflcko commented Mar 31, 2020

@ariard If m_last_block_processed is the chain tip, it will not empty the scheduler queue, but return early, so it is going to miss tx updates in case of a reorg. Note that m_last_block_processed is set on blockConnected/Disconnected.

See also my second bullet point here: #17562 (review)

@ariard
Copy link

ariard commented Apr 1, 2020

https://doxygen.bitcoincore.org/class_c_validation_interface.html#a6de358ebc946cbd33ce73eef61993fe5 implies that mempool removal signals are ordered before block connection signals. After the changes in this pull request, this is no longer true. So an operation in a BlockConnected callback, that depends on an operation run in the TransactionRemovedFromMempool, might now fail.

This PR doesn't inverse mempool removal signals and block connection signals as far as I understand. Mempool removal are triggered in removeUnchecked which is indirectly called via removeForBlock in ConnectTip before new call emplacement of BlockConnected. This order holds same for DisconnectTip.

This order guarantee us than when wallet query the chain to know if it's behind (BlockUntilSyncedToCurrentChain) it's either wallet tip is equivalent to chain tip and there is not mempool update to wait for or wallet tip is lagging behind but catching up will only happen after TransactionsRemovedFromMempool has been drought out of the scheduler queue.

I read again wallet code, as far as I can tell, transactionsRemovedFromMempool only tweak mempool flag for wallet transactions which is only used at broadcast but not for block connection.

Or maybe I miss something, code isn't the clearest here ?

@maflcko
Copy link
Member

maflcko commented Apr 13, 2020

What about the ones in UpdateMempoolForReorg?

@DrahtBot DrahtBot mentioned this pull request Apr 14, 2020
18 tasks
@jnewbery
Copy link
Contributor Author

Thanks for pointing this out Marco. You're right that in a re-org, this changes the order of notification. If there's a one block diconnect/two block connect reorg, then before this PR:

  • Block A1 disconnected (txs added to disconnect pool)
    • BlockDisconnected notification for A1
  • Block A2 connected (block added to ConnectTrace)
    • TransactionRemovedFromMempool notifications for conflicted transactions
  • Block B2 connected (block added to ConnectTrace)
    • TransactionRemovedFromMempool notifications for conflicted transactions
  • UpdateMempoolForReorg called
    • TransactionRemovedFromMempool notifications for reorg-removed transactions
  • ActivateBestChainStep exits
    • BlockConnected notification for A2
    • BlockConnected notification for B2

After this PR

  • Block A1 disconnected (txs added to disconnect pool)
    • BlockDisconnected notification for A1
  • Block A2 connected (block added to ConnectTrace)
    • TransactionRemovedFromMempool notifications for conflicted transactions
    • BlockConnected notification for A2
  • Block B2 connected (block added to ConnectTrace)
    • TransactionRemovedFromMempool notifications for conflicted transactions
    • BlockConnected notification for B2
  • UpdateMempoolForReorg called
    • TransactionRemovedFromMempool notifications for reorg-removed transactions
  • ActivateBestChainStep exits

So at the point that BlockConnected is called for B2, the mempool is in an inconsistent state. As Marco points out, that should be ok since the validationinterface doesn't guarantee a consistent mempool when BlockConnected is fired. Listeners should use UpdatedBlockTip if they want that.

However, I'm going to close this PR since it's difficult to review. It should be possible to bring all of the notification firing into ActivateBestChainStep() in a future PR, but to minimize review burden I'll open an alternative that doesn't remove ConnectTrace but instead just simplifies it and improves commenting.

@jnewbery
Copy link
Contributor Author

Opened a PR to simplify ConnectTrace here: #18685

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants