Sanity assert GetAncestor() != nullptr where appropriate#24804
Sanity assert GetAncestor() != nullptr where appropriate#24804maflcko merged 1 commit intobitcoin:masterfrom
Conversation
There was a problem hiding this comment.
A couple of initial comments. Minor detail, please don't use @-usernames in the PR description.
|
Concept ACK with some suggestions for the lines touched here suggested diff for your perusal
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index 4f00d6e094..eb731ba205 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -76,7 +80,7 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags
assert(ancestor != nullptr);
- int64_t nCoinTime = ancestor->GetMedianTimePast();
+ const int64_t nCoinTime = ancestor->GetMedianTimePast();
// NOTE: Subtract 1 to maintain nLockTime semantics
diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h
index 1209c0faa5..1386b029f5 100644
--- a/src/consensus/tx_verify.h
+++ b/src/consensus/tx_verify.h
@@ -446,17 +446,16 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK(!TestSequenceLocks(CTransaction{tx})); // Sequence locks fail
- const int SEQUENCE_LOCK_TIME = 512; // Sequence locks pass 512 seconds later
- for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
- m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; //Trick the MedianTimePast
-
- {
+ const int SEQUENCE_LOCK_TIME{512}; // Sequence locks pass 512 seconds later
+ for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
+ m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
- BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); // Sequence locks pass 512 seconds later
+ BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip)));
}
- for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
- m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= SEQUENCE_LOCK_TIME; //undo tricked MTP
+ for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
+ m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= SEQUENCE_LOCK_TIME; // undo tricked MTP
+ }
// absolute height locked
@@ -501,9 +500,9 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), 3U);
- // However if we advance height by 1 and time by 512, all of them should be mined
- for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
- {
+ // However, if we advance height by 1 and time by SEQUENCE_LOCK_TIME, all of
+ // them should be mined.
+ for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
CBlockIndex* ancestor = m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i);
assert(ancestor != nullptr);
ancestor->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast
diff --git a/src/versionbits.cpp b/src/versionbits.cpp
index 9218c6bf26..934bfb015f 100644
--- a/src/versionbits.cpp
+++ b/src/versionbits.cpp
@@ -109,10 +109,6 @@ BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockI
// Find how many blocks are in the current period
int blocks_in_period = 1 + (pindex->nHeight % stats.period);
- // Find beginning of period
- const CBlockIndex* pindexEndOfPrevPeriod = pindex->GetAncestor(pindex->nHeight - ((pindex->nHeight + 1) % stats.period));
- assert(pindexEndOfPrevPeriod != nullptr);
- stats.elapsed = pindex->nHeight - pindexEndOfPrevPeriod->nHeight;
// Reset signalling_blocks |
d297649 to
dcaae44
Compare
|
Thank you for your review @jonatack, I have addressed your comments. |
44f4141 to
e3250c5
Compare
e3250c5 to
93e516d
Compare
There was a problem hiding this comment.
A few suggestions
index a8701cc9aa..c03e975c03 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -75,7 +75,7 @@ std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags
int nCoinHeight = prevHeights[txinIndex];
if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) {
- const int64_t nCoinTime = Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast();
+ const int64_t nCoinTime{Assert(block.GetAncestor(std::max(nCoinHeight - 1, 0)))->GetMedianTimePast()};
// NOTE: Subtract 1 to maintain nLockTime semantics
// BIP 68 relative lock times have the semantics of calculating
// the first block or time at which the transaction would be
diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp
index 78bc93c3d4..1d7eb80d78 100644
--- a/src/test/miner_tests.cpp
+++ b/src/test/miner_tests.cpp
@@ -448,14 +448,17 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
const int SEQUENCE_LOCK_TIME = 512; // Sequence locks pass 512 seconds later
for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
- m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; //Trick the MedianTimePast
+ m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime += SEQUENCE_LOCK_TIME; // Trick the MedianTimePast
{
CBlockIndex* active_chain_tip = m_node.chainman->ActiveChain().Tip();
- BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip))); // Sequence locks pass 512 seconds later
+ BOOST_CHECK(SequenceLocks(CTransaction(tx), flags, prevheights, CreateBlockIndex(active_chain_tip->nHeight + 1, active_chain_tip)));
}
- for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i)
- m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i)->nTime -= SEQUENCE_LOCK_TIME; //undo tricked MTP
+ for (int i = 0; i < CBlockIndex::nMedianTimeSpan; ++i) {
+ CBlockIndex* ancestor = m_node.chainman->ActiveChain().Tip()->GetAncestor(m_node.chainman->ActiveChain().Tip()->nHeight - i);
+ assert(ancestor != nullptr);
+ ancestor->nTime -= SEQUENCE_LOCK_TIME; // undo tricked MTP
+ }
// absolute height locked
tx.vin[0].prevout.hash = txFirst[2]->GetHash();9f9361f to
977b6b1
Compare
|
Seems like there is a bug in the CI? I ran the tests on my fork and passed all tests |
|
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. |
|
ACK 977b6b1874942474006d5d3c257b18b77c882af1 |
…function and NONFATAL_UNREACHABLE macro ee02c8b util/check: Add CHECK_NONFATAL identity function, NONFATAL_UNREACHABLE AND UNREACHABLE macros (Aurèle Oulès) Pull request description: This PR replaces the macro `CHECK_NONFATAL` with an identity function. I simplified the usage of `CHECK_NONFATAL` where applicable in `src/rpc`. This function is useful in sanity checks for RPC and command-line interfaces. Context: bitcoin/bitcoin#24804 (comment). Also adds `UNREACHABLE_NONFATAL` macro. ACKs for top commit: jonatack: ACK ee02c8b MarcoFalke: ACK ee02c8b 🍨 Tree-SHA512: 3cba09223cd7b22e62fe5d0b46c4a024c1d9957d4268ba6d3fb07fcc0a5854fc0886bb3266184e6a7df5df91373b3e84edd6adf6999c4e934aeef8c043b01aa2
977b6b1 to
54070a5
Compare
9075d79 to
a06141f
Compare
There was a problem hiding this comment.
LGTM, modulo since the commit is authored by @adamjonas, you could change the first "Co-Authored-By:" in the commit message to yourself.
a06141f to
c0fcbb7
Compare
|
ACK c0fcbb7506e0b5a49549a1615e48781151cb4687 If you have to retouch, maybe consider --- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -1619,8 +1619,8 @@ static RPCHelpMan getchaintxstats()
const CBlockIndex& past_block{*CHECK_NONFATAL(pindex->GetAncestor(pindex->nHeight - blockcount))};
- int nTimeDiff = pindex->GetMedianTimePast() - past_block.GetMedianTimePast();
- int nTxDiff = pindex->nChainTx - past_block.nChainTx;
+ const int64_t nTimeDiff{pindex->GetMedianTimePast() - past_block.GetMedianTimePast()};
+ const int nTxDiff = pindex->nChainTx - past_block.nChainTx;
@@ -1772,8 +1772,8 @@ static RPCHelpMan getblockstats()
- const CBlock block = GetBlockChecked(chainman.m_blockman, &pindex);
- const CBlockUndo blockUndo = GetUndoChecked(chainman.m_blockman, &pindex);
+ const CBlock& block = GetBlockChecked(chainman.m_blockman, &pindex);
+ const CBlockUndo& blockUndo = GetUndoChecked(chainman.m_blockman, &pindex); |
b0c9d04 to
260a05d
Compare
jonatack
left a comment
There was a problem hiding this comment.
ACK 260a05ddafd9d62aa478637a8d58d67ff4dbacc6 with a couple more suggestions
Add sanity asserts for return value of `CBlockIndex::GetAncestor()` where appropriate. In validation.cpp `CheckSequenceLocks`, check the return value of `tip->GetAncestor(maxInputHeight)` stored into `lp->maxInputBlock`. If it ever returns `nullptr` because the ancestor isn't found, it's going to be a bad bug to keep going, since a `LockPoints` object with the `maxInputBlock` member set to `nullptr` signifies no relative lock time. In the other places, the added asserts would prevent accidental dereferencing of a null pointer which is undefined behavior. Co-Authored-By: Aurèle Oulès <[email protected]> Co-Authored-By: danra <[email protected]>
260a05d to
308dd2e
Compare
|
ACK 308dd2e |
Summary: Add sanity asserts for return value of `CBlockIndex::GetAncestor()` where appropriate. In validation.cpp `CheckSequenceLocks`, check the return value of `tip->GetAncestor(maxInputHeight)` stored into `lp->maxInputBlock`. If it ever returns `nullptr` because the ancestor isn't found, it's going to be a bad bug to keep going, since a `LockPoints` object with the `maxInputBlock` member set to `nullptr` signifies no relative lock time. In the other places, the added asserts would prevent accidental dereferencing of a null pointer which is undefined behavior. Co-Authored-By: Aurèle Oulès <[email protected]> Co-Authored-By: danra <[email protected]> This is a backport of [[bitcoin/bitcoin#24804 | core#24804]] Test Plan: `ninja all check-all` Reviewers: #bitcoin_abc, Fabien Reviewed By: #bitcoin_abc, Fabien Subscribers: Fabien Differential Revision: https://reviews.bitcoinabc.org/D13242
Re-opening #17232. I have rebased the PR and addressed jonatack's nit suggestions.
Add sanity asserts for return value of
CBlockIndex::GetAncestor()where appropriate.In validation.cpp
CheckSequenceLocks, check the return value oftip->GetAncestor(maxInputHeight)stored intolp->maxInputBlock. If it ever returnsnullptrbecause the ancestor isn't found, it's going to be a bad bug to keep going, since aLockPointsobject with themaxInputBlockmember set tonullptrsignifies no relative lock time.In the other places, the added asserts would prevent accidental dereferencing of a null pointer which is undefined behavior.
Co-Authored-By: Adam Jonas [email protected]
Co-Authored-By: danra [email protected]