-
Notifications
You must be signed in to change notification settings - Fork 36.6k
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
validation: UTXO snapshot activation #19806
Conversation
19b7517
to
08a0861
Compare
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. |
08a0861
to
82ad09b
Compare
86355a1
to
2cb1f84
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.
Concept ACK
Just a few questions and comments from a first pass, code looks already in good shape. Will test soon.
src/txdb.cpp
Outdated
// progress= measure, but returning 0 would cause us to not be able to add | ||
// chain tips for the snapshot chainstate. This shouldn't happen and is |
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.
I assume it wouldn't work because of a divide by zero error in the progress function? Shouldn't that be rather dealt with at that layer?
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.
I assume it wouldn't work because of a divide by zero error in the progress function? Shouldn't that be rather dealt with at that layer?
Would agree that handling this in LoadBlockIndex would be preferable to having to hardcode 1's here and in ChainstateManager::GetSnapshotNChainTx
along with comments describing other layers of code. Both CCoinsViewDB::GetNChainTx
and ChainstateManager::GetSnapshotNChainTx
could return Optional<int>
to avoid the need to hardcode something
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.
Concept ACK 2cb1f84, but I had some approach questions. Didn't closely review, nor did I review the tests.
461a521
to
e7b1615
Compare
Code review ACK 1afc0e4 Reviewed changes since last review and confirmed they were due to rebasing or addressing review comments as discussed above. |
Code review ACK 1afc0e4 |
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.
Concept ACK. I left some style comment, questions, and found a bunch of crashes/UB.
@@ -8,7 +8,6 @@ | |||
#include <chainparamsseeds.h> | |||
#include <consensus/merkle.h> | |||
#include <hash.h> // for signet block challenge hash | |||
#include <tinyformat.h> |
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.
7a6c46b: why is this removed. This is needed for strprintf
//! | ||
//! It is also possible, though very unlikely, that a change in this | ||
//! construction could cause a previously invalid (and potentially malicious) | ||
//! UTXO snapshot to be considered valid. |
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.
7a6c46b: I don't understand this section. Does this assume that the way outputs are applied to the hash_obj is broken? In that case it doesn't require a "previously" invalid snapshot. Likely, any invalid snapshot can be generated/modified, so that it is considered valid.
If it assumes that the underlying hash function is broken, there is nothing we can do anyway and any invalid snapshot can be generated/modified to be valid, regardless of changing this construction.
@@ -20,6 +20,8 @@ | |||
#include <functional> | |||
#include <unordered_map> | |||
|
|||
class ChainstateManager; |
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.
f6e2da5: why is this needed?
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.
Removed in #21592
BOOST_CHECK(chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull()); | ||
BOOST_CHECK_EQUAL( | ||
chainman.ActiveChainstate().m_from_snapshot_blockhash, | ||
chainman.SnapshotBlockhash().value_or(uint256())); |
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.
4d8de04: Wouldn't it be better to check !chainman.SnapshotBlockhash()
? Otherwise it can incorrectly return a default constructed uint256 without this test noticing.
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.
Fixed in #21584
|
||
// Snapshot should refuse to load at this height. | ||
BOOST_REQUIRE(!CreateAndActivateUTXOSnapshot(m_node, m_path_root)); | ||
BOOST_CHECK(chainman.ActiveChainstate().m_from_snapshot_blockhash.IsNull()); |
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.
Wouldn't it be better to have the same interface as for the SnapshotBlockhash
member function? I.e. return nullopt when there is no hash instead of 0.
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.
Fixed in #21584
|
||
struct TestChain100DeterministicSetup : public TestChain100Setup { | ||
TestChain100DeterministicSetup() : TestChain100Setup(true) { } | ||
}; |
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.
Any need for this? Seems odd to have an option to make a test non-deterministic
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.
@@ -79,7 +79,6 @@ struct BasicTestingSetup { | |||
explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {}); | |||
~BasicTestingSetup(); | |||
|
|||
private: |
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.
Could use GetDataDir()
instead
(commit title and description of f6e2da5 doesn't match what it does) |
} | ||
|
||
assert(index); | ||
index->nChainTx = metadata.m_nchaintx; |
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.
metadata.m_nchaintx
is untrusted input, so this lets an attacker pick the value
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.
Oh, yeah, good catch. This is outdated, and should be ... = au_data.nChainTx
instead. This is an artifact from before we moved nChainTx into the hardcoded assumeutxo parameters.
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.
Fixed here: #21681
Thanks for finding this.
…hardcoded nChainTx 91d93aa validation: remove nchaintx from assumeutxo metadata (James O'Beirne) 931684b validation: fix ActivateSnapshot to use hardcoded nChainTx (James O'Beirne) Pull request description: This fixes an oversight from the move of nChainTx from the user-supplied snapshot metadata into the hardcoded assumeutxo chainparams. Since the nChainTx is now unused in the metadata, it should be removed in a future commit. See: bitcoin/bitcoin#19806 (comment) ACKs for top commit: Sjors: utACK 91d93aa ryanofsky: Code review ACK 91d93aa. No change to previous commit, just new commit removing now unused utxo snapshot field and updating tests. Tree-SHA512: 445bdd738faf007451f40bbcf360dd1fb4675e17a4c96546e6818c12e33dd336dadd95cf8d4b5f8df1d6ccfbc4bf5496864bb5528e416cea894857b6b732140c
Summary: This is a backport of [[bitcoin/bitcoin#21244 | core#21244]] [2/8] bitcoin/bitcoin@1add318 Note: due to out of order backport, I also had to remove `private:` in `setup_common.h` which is otherwise removed in [[bitcoin/bitcoin#19806 | core#19806]]. Depends on D10749 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D10750
Summary: This move/refactor is needed to set up a decent unittest for UTXO snapshot activation. This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [1/8] bitcoin/bitcoin@6606a4f Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11224
Summary: We can't support a reset of the dbwrapper object when in-memory configuration is used because it results in the permanent loss of coins. This only affects unittest configurations (since that's the only place we use in-memory CCoinsViewDB instances). This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [2/8] bitcoin/bitcoin@ad949ba Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11226
Summary: This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [3/8] bitcoin/bitcoin@31d2252 Note that the hash of the block in `TestChain100Setup` is different because Bitcoin ABC blocks have differences with Bitcoin Core blocks. I added a test that does nothing but initialize a `TestChain100DeterministicSetup` to demonstrate that the hash in the assertion is correct (changing something in that string makes the test fail). Test Plan: `ninja check` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11225
Summary: Values for mainnet and testnet will be specified in a follow-up PR that can be scrutinized accordingly. This structure is required for use in snapshot activation logic. This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [4/8] and [[bitcoin/bitcoin#21584 | core#21584]] [2 & 3/5] bitcoin/bitcoin@7a6c46b bitcoin/bitcoin@0000007 bitcoin/bitcoin@fa5668b (partial) Notes: - The new circular dependency was added by core in a later commit. We already need it here. - We also check the allowed hashes in a functional test reproducing the deterministic regtest chain and allowed hashes. Depends on D11328 Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11238
Summary: bitcoin/bitcoin@f6e2da5 > Don't return null snapshotblockhash values to avoid caller complexity/confusion. ---- bitcoin/bitcoin@931684b > validation: fix ActivateSnapshot to use hardcoded nChainTx > > This fixes an oversight from the move of nChainTx from the user-supplied > snapshot metadata into the hardcoded assumeutxo chainparams. > > Since the nChainTx is now unused in the metadata, it should be removed > in a future commit. ---- bitcoin/bitcoin@91d93aa > validation: remove nchaintx from assumeutxo metadata > > This value is no longer used and is instead specified statically > in chainparams. This change means that previously generated > snapshots will no longer be usable. ---- bitcoin/bitcoin@fa9b74f > Fix assumeutxo crash due to missing base_blockhash ---- bitcoin/bitcoin@fae33f9 > Fix assumeutxo crash due to invalid base_blockhash > > Can be reviewed with --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space ---- bitcoin/bitcoin@fa73ce6 > Fix assumeutxo crash due to truncated file ---- This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [5/8], core#21681 (partial), core#21582 (partial), core#21584 (partial) and core#21585 Notes: - The test related changes from core#21681, core#21582 and core#21584 are in D11241. This is because they depend on a missing (for now) test fixture for malleating the utxo snapshots. Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11239
Summary: This also tests the hashes added in D11238. This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [6/8] bitcoin/bitcoin@4d8de04 Depends on D11239 Test Plan: `ninja check` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D11240
Summary: bitcoin/bitcoin@769a1ef > test: Add tests with maleated snapshot data ---- https://github.com/bitcoin/bitcoin/pull/21681/files > validation: fix ActivateSnapshot to use hardcoded nChainTx > validation: remove nchaintx from assumeutxo metadata Only test related changes for these commits are in this revision ---- bitcoin/bitcoin@fa8fffe > refactor: Prefer clean assert over UB in coinstats ---- bitcoin/bitcoin@fa9b74f > Fix assumeutxo crash due to missing base_blockhash Only test related changes from this commit are in this revision. ---- bitcoin/bitcoin@fae33f9 > Fix assumeutxo crash due to invalid base_blockhash Only test related changes from this commit are in this revision. ---- This is a backport of [[bitcoin/bitcoin#19806 | core#19806]] [7/8] and test related changes from [[bitcoin/bitcoin#21681 | core#21681]], [[bitcoin/bitcoin#21582 | core#21582]] and [[bitcoin/bitcoin#21584 | core#21584]] Depends on D11240 Test Plan: `ninja check` With UBSAN: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11241
Summary: This concludes backport of [[bitcoin/bitcoin#19806 | core#19806]] [6/6] bitcoin/bitcoin@1afc0e4 Test Plan: NA Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Differential Revision: https://reviews.bitcoinabc.org/D11243
This is part of the assumeutxo project:
Parent PR: #15606
Issue: #15605
Specification: https://github.com/jamesob/assumeutxo-docs/tree/master/proposal
This change proposes logic for activating UTXO snapshots, which is unused at the moment aside from an included unittest. There are a few moveonyish/refactoring commits to allow for halfway decent unittests.
Basic structure is included for specifying and checking the assumeutxo hash values used to validate activated snapshots. Initially I had specified a few height/hash pairs for mainnet in this change, but because of the security-critical nature of those parameters, I figured it was better to leave their inclusion to a future PR that includes only that change - my intent being that reviewers will be more likely to verify those parameters firsthand in a dedicated PR.
Aside from that and the snapshot activation logic, there are a few related changes:
allow caching thenChainTx
value in the CCoinsViewDB; this is set during snapshot activation. Because we don't necessarily have access to the full chain at the time of snapshot load, this value is communicated through the snapshot metadata and must be cached within the chainstate to survive restarts.CreateUTXOSnapshot()
from dumptxoutset. This is essentially a move-only change to allow the reuse of snapshot creation logic from within unittests.The move-onlyish commit is most easily reviewed with
--color-moved=zebra
.