-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Add ChainstateManager, remove BlockManager global #17737
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
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
ce74d24 to
2328317
Compare
maflcko
left a comment
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.
ACK 0226408, did not read the tests 🔲
Show signature and timestamp
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
ACK 0226408999, did not read the tests 🔲
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYEACgkQzit1aX5p
pUixgQv9ELRmdepH+VtXfc0mvkvHjZZAGrvdNEAGLqlEK+nbDy0YtUnZtECto3aJ
K/fFg7heGCu3/pRgx25GGDnaRNrOPc+q56kWXUjSS7lweiyx1JYw4V8sVlgas3Ih
4Cxbgy3GxmPL88e1mRBpqBdyKxGi3cPxpPjew63/sllo9ZDPBMsA5g0NcpUwIC2H
TMgdLJbffnHCgCKkIH5/lXah8W7fF6Tt/wyzK4RaijwcxjVrdFheJTv0kLiBJDAG
AmHMVhKDQTBeZFn5CydqeupqV90u7rdFd/S6MliuawQGwtlobeqKqs7jxeR23+Yx
AfAAk6nKLhQFQ5x998j/rGamIcYO7RCRE0be0dZC1KGdhTwIY1LOsSKHlJAn64Ik
XKNJXDbg8o1vnBgAEmzslunwooaOoF2oSyEB4crt++JNYLl38imrOdZ+0kdlQ/BC
GCRJWD/y2WSNRxCrkyJZ6uxTkUf7KmEbh8qwOavXby2DR2rOSOGE9nM9ewXgqbsK
BDO3176X
=Ygdp
-----END PGP SIGNATURE-----
Timestamp of file with hash c4bdc7880969f1e6719cf25c6f715a20e103935d1147395578a097e3179189ff -
ariard
left a comment
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.
7eac28c to
9a6fb54
Compare
9a6fb54 to
4cab02a
Compare
4cab02a to
ec64f5c
Compare
|
Bringing in this IRC comment, if helpful: "recent utxo snapshots for testing are available here: #15606 (comment)" |
|
ACK 16d20d9 only, will continue review later on 🚀 Show signature and timestampSignature: Timestamp of file with hash |
ec64f5c to
1c17381
Compare
maflcko
left a comment
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.
ACK e7bc059 only, have not reviewed later commits closely 🕧
Show signature and timestamp
Signature:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
ACK e7bc059491d51919f676b35b6843d1c395d452a6 only, have not reviewed later commits closely 🕧
-----BEGIN PGP SIGNATURE-----
iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjKXwwApeBAJd4ix/yrfHo9bHi30caJGej5Xk3cCvsbTorNmxVgMjJdbcALeADr
AbWHnVntgHiI7oLtzbKrFlKTGi826+stmRIy2VPyVs31L/z7k2pLKJsRFtYO+kzv
ATQ4POaLd58wzFI4bxGtSLBu7I+91f6iLzdtdINYDVJj6g89eBd74ICseFoQjM6x
lAugPzMXzrL8kh71IFBumNpQKq3rNZ9Wb/6oqVCBiZUGUnW4qC3a5aVDhwfnBnKX
YQia7Cej4Ex22+FAxh+4LUl8nO6I+UMH53TASaMG/ZoHUrXpHouWyo9vmUAwBMyp
gqN9AX/V5Hv7YCk3hehviw6p9ZI+Gvs3hrXYlU2FLUFTGXJfQz5yM6jSipnK5tZC
vqx46MazAjQ7x2de/HJIfwf+uEFpZkohauhobu5pMGss0tuVSiWVcofIoS8I5zei
mlEZ6atiGucuEMZmiC8+z3g4TbGo5kztOB00YOVVbY1+jDmuOOs+T220p4FtrDTl
B6J3CRmr
=Ik+8
-----END PGP SIGNATURE-----
Timestamp of file with hash fe215ba014f43a48217fc4a11afdd4fb671d3ccd7e48f8bed366d49affae1228 -
|
ACK 1c17381, but it looks like the tests fail 🍢 Show signature and timestampSignature: Timestamp of file with hash |
ryanofsky
left a comment
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.
Code review ACK 1c17381. I did have a bunch of questions and suggestions below, but the suggestions aren't important, and if the questions don't point to real problems, I think this looks good to merge as is.
src/validation.h
Outdated
| * *Background validation chainstate*: an IBD chainstate for which the | ||
| * IBD process is happening in the background while use of the | ||
| * active chainstate allows the rest of the system to 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.
In commit "validation: introduce unused ChainstateManager" (10837ab)
The "Background validation chainstate" term seems a little awkward to me, where I guess every background validation chainstate is an IBD chainstate, but an IBD chainstate isn't a background validation chainstate until a separate snapshot chainstate has been loaded.
It seems like if you replaced the IsBackgroundValidationChainstate() method with plainer ChainStateManger::IsIBD(chainstate) and ChainStateManager::HasSnapshot() methods you could drop the "background validation chainstate" term and method and make things easier to follow.
Or if having the term is more useful, maybe call it a "background IBD chainstate" instead of "background validation chainstate" to be more obvious it's always refers to the IBD chain.
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 gets kind of confusing here is that chainstates created from snapshots still technically go through IBD, since by the time the snapshot is actually used to create a chainstate, it's far enough behind the tip that it technically undergoes IBD (albeit an abbreviated one). So I think referring to what I now call the background validation chainstate as the IBD chainstate might be confusing in that sense.
But I agree with you that the naming here isn't ideal. Definitely open to changing this if you have other good ideas.
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.
re: #17737 (comment)
I guess I see that but it would seem more like a reason to avoid the term "IBD chainstate" entirely.
Since chain state manager only has a snapshot chainstate and a non snapshot chainstate, I like the idea of just referring to the two chainstates with the same names consistently, and not muddying the water with other chainstate names and definitions. "IBD chainstate" is what you call the non-snapshot chainstate everywhere except in this one method and comment, which is my why first suggestion is delete "background validation chainstate" comment and have separate methods replacing IsBackgroundValidationChainstate. Switching to "Background IBD chainstate" was just a runner up suggestion.
I guess also I don't find the "IBD chainstate" name to be too confusing because I take IBD chainstate to mean chainstate generated entirely from IBD, not a state with some UTXOs that happened to come from IBD. But for another naming suggestion, maybe an alternative would be to use "snapshot chainstate" and "blocksonly chainstate" instead of "snapshot chainstate" and "IBD chainstate"
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.
Partially (?) fixed by changing IsBackgroundValidationChainstate() to IsBackgroundIBD(). I think blocksonly is somewhat confusing because there'd be a confusing overlap with the P2P definition of blocksonly, which I think is different or unrelated.
| BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr)); | ||
|
|
||
| BOOST_CHECK(manager.IsSnapshotActive()); | ||
| BOOST_CHECK(!manager.IsSnapshotValidated()); |
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 commit "test: add basic tests for ChainstateManager" (997bf7f)
No test for the case where IsSnapshotValidated returns true, I guess. Understandable if it would make the test setup too complicated
|
Thanks for the good reviews! I'll be following up shortly with corresponding changes. |
1c17381 to
94ca1e0
Compare
|
I've incorporated most if not all of the feedback from @MarcoFalke and @ryanofsky which has nicely reduced the size of the diff. Changes include:
|
This allows us to easily initialize multiple chainstates on startup in future commits. It retires the g_chainstate global in lieu of g_chainman.
Feedback incorporated from Russell Yanofsky. Co-authored-by: MarcoFalke <[email protected]>
I'd previously attempted to create a specialized lock for ChainstateManager, but it turns out that because that lock would be required for functions like ChainActive() and ChainstateActive(), it created irreconcilable lock inversions since those functions are used so broadly throughout the codebase. Instead, I'm just using cs_main to protect the contents of g_chainman. Co-authored-by: Russell Yanofsky <[email protected]>
abfc152 to
c9017ce
Compare
fjahr
left a comment
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.
Code Review ACK abfc152
Had a few nits that can well be ignored or addressed in next PR in the assume-utxo series.
General note: I was not sure about some of the ChainstateManager API, some of the methods seemed like they could be private (IsSnapshotValidated() seems to be only used internally) and others are not used at all (IsSnapshotValidated and SnapshotBlockhash for example) so they could have been included in the next PRs when they are needed. But I can wait and see how they are used in the next PR. :)
| std::string leveldb_name) | ||
| { | ||
| if (!m_from_snapshot_blockhash.IsNull()) { | ||
| leveldb_name += "_" + m_from_snapshot_blockhash.ToString(); |
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.
nit: Do you anticipate more than one snapshot to be present? From the rest of the code it seems to me that this will not be the case. Then I think naming the db just "snapshot" or so is more intuitive.
|
|
||
| to_modify.reset(new CChainState(snapshot_blockhash)); | ||
|
|
||
| // Snapshot chainstates and initial IBD chaintates always become active. |
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.
typo: chaintates
| } | ||
| } | ||
|
|
||
| // scan for better chains in the block chain database, that are not yet connected in the active best chain |
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.
nit: That comment is still relevant to the code below but because of the empty line it seems detached.
|
Code Review Re-ACK abfc152 |
|
re-ACK c9017ce 📙 Only changes since my last review:
Show signature and timestampSignature: Timestamp of file with hash |
|
@fjahr It looks like your commit hash is the same in the re-ACK |
ariard
left a comment
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.
Code Review ACK c9017ce
Side-node: there is a g_chainman access in LoadBlockIndex (src/validation.cpp L4577), not an issue right now because caller already holds cs_main but if function is moved in the future a AssertLockHeld would be better.
|
|
||
| CChain& ChainActive() | ||
| { | ||
| LOCK(::cs_main); |
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.
Is this LOCK really necessary given we call ::ChainstateActive() just after ? Doesn't hurt because we use recursive_mutex but still..
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.
re: #17737 (comment)
Is this LOCK really necessary given we call
::ChainstateActive()just after ? Doesn't hurt because we use recursive_mutex but still..
Agree it's definitely not necessary (but harmless)
ryanofsky
left a comment
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.
Code review ACK c9017ce. No changes since last review other than a straight rebase
| }; | ||
|
|
||
| extern ChainstateManager g_chainman; | ||
| extern ChainstateManager g_chainman GUARDED_BY(::cs_main); |
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.
re: #17737 (comment)
If understand well the new lock model,
g_chainmancontent is undercs_mainbut notCChainState. If yes, why someGetAllaccess in init.cpp don't use lock for access ?
I don't think this is true. Maybe it was resolved? You can add EXCLUSIVE_LOCKS_REQUIRED(cs_main) to the GetAll declaration, and it will only fail in test code using a local chain state manager not tied to the cs_main global
|
|
||
| CChain& ChainActive() | ||
| { | ||
| LOCK(::cs_main); |
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.
re: #17737 (comment)
Is this LOCK really necessary given we call
::ChainstateActive()just after ? Doesn't hurt because we use recursive_mutex but still..
Agree it's definitely not necessary (but harmless)
|
This tip has accumulated a good number of code ACKs, so I'm hesitant to address nits here. If anyone thinks that's the right move though I'm happy to. Edit: and thanks for the reviews, everyone! |
I think we can merge this after the 0.20 branch off. |
This is part of the assumeutxo project:
Parent PR: #15606
Issue: #15605
Specification: https://github.com/jamesob/assumeutxo-docs/tree/master/proposal
This changeset introduces
ChainstateManager, which is responsible for creating and managing access to multiple chainstates. Until we allow chainstate creation from UTXO snapshots (next assumeutxo PR?) it's basically unnecessary, but it is a prerequisite for background IBD support.Changes are also made to the initialization process to make use of
g_chainmanand thus clear the way for multiple chainstates being loaded on startup.One immediate benefit of this change is that we no longer have the
g_blockmanglobal, but instead have the ChainstateManager inject a reference of its shared BlockManager into any chainstate it creates.Another immediate benefit is that uses of
ChainActive()andChainstateActive()are now covered by lock annotations. Because use ofg_chainmanis annotated to require cs_main, these two functions subsequently follow.Because of whitespace changes, this diff looks bigger than it is. E.g., 4813167 is most easily reviewed with