Skip to content

Commit

Permalink
validation: Pass in chainstate to ::CheckSequenceLocks
Browse files Browse the repository at this point in the history
Summary:
This is a backport of [[bitcoin/bitcoin#20750 | core#20750]] [6/17]
bitcoin/bitcoin@4c15942

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D11192
  • Loading branch information
dongcarl authored and PiRK committed Mar 17, 2022
1 parent 6be9984 commit 3e47401
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 15 deletions.
3 changes: 2 additions & 1 deletion src/test/miner_tests.cpp
Expand Up @@ -37,7 +37,8 @@ struct MinerTestingSetup : public TestingSetup {
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs);
bool TestSequenceLocks(const CTransaction &tx, int flags)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, m_node.mempool->cs) {
return CheckSequenceLocks(*m_node.mempool, tx, flags);
return CheckSequenceLocks(::ChainstateActive(), *m_node.mempool, tx,
flags);
}
BlockAssembler AssemblerForTest(const CChainParams &params);
};
Expand Down
3 changes: 2 additions & 1 deletion src/txmempool.cpp
Expand Up @@ -587,7 +587,8 @@ void CTxMemPool::removeForReorg(const Config &config,
if (!ContextualCheckTransactionForCurrentBlock(
::ChainActive().Tip(), config.GetChainParams().GetConsensus(),
tx, state, flags) ||
!CheckSequenceLocks(*this, tx, flags, &lp, validLP)) {
!CheckSequenceLocks(::ChainstateActive(), *this, tx, flags, &lp,
validLP)) {
// Note if CheckSequenceLocks fails the LockPoints may still be
// invalid. So it's critical that we remove the tx and not depend on
// the LockPoints.
Expand Down
26 changes: 15 additions & 11 deletions src/validation.cpp
Expand Up @@ -199,21 +199,24 @@ bool TestLockPointValidity(const LockPoints *lp) {
return true;
}

bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx,
int flags, LockPoints *lp, bool useExistingLockPoints) {
bool CheckSequenceLocks(CChainState &active_chainstate, const CTxMemPool &pool,
const CTransaction &tx, int flags, LockPoints *lp,
bool useExistingLockPoints) {
AssertLockHeld(cs_main);
AssertLockHeld(pool.cs);
assert(std::addressof(::ChainstateActive()) ==
std::addressof(active_chainstate));

CBlockIndex *tip = ::ChainActive().Tip();
CBlockIndex *tip = active_chainstate.m_chain.Tip();
assert(tip != nullptr);

CBlockIndex index;
index.pprev = tip;
// CheckSequenceLocks() uses ::ChainActive().Height()+1 to evaluate height
// based locks because when SequenceLocks() is called within ConnectBlock(),
// the height of the block *being* evaluated is what is used. Thus if we
// want to know if a transaction can be part of the *next* block, we need to
// use one more than ::ChainActive().Height()
// CheckSequenceLocks() uses active_chainstate.m_chain.Height()+1 to
// evaluate height based locks because when SequenceLocks() is called within
// ConnectBlock(), the height of the block *being* evaluated is what is
// used. Thus if we want to know if a transaction can be part of the *next*
// block, we need to use one more than active_chainstate.m_chain.Height()
index.nHeight = tip->nHeight + 1;

std::pair<int, int64_t> lockPair;
Expand All @@ -222,8 +225,8 @@ bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx,
lockPair.first = lp->height;
lockPair.second = lp->time;
} else {
// CoinsTip() contains the UTXO set for ::ChainActive().Tip()
CCoinsViewMemPool viewMemPool(&::ChainstateActive().CoinsTip(), pool);
// CoinsTip() contains the UTXO set for active_chainstate.m_chain.Tip()
CCoinsViewMemPool viewMemPool(&active_chainstate.CoinsTip(), pool);
std::vector<int> prevheights;
prevheights.resize(tx.vin.size());
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
Expand Down Expand Up @@ -546,7 +549,8 @@ bool MemPoolAccept::PreChecks(ATMPArgs &args, Workspace &ws) {
// that can't be mined yet. Must keep pool.cs for this unless we change
// CheckSequenceLocks to take a CoinsViewCache instead of create its
// own.
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) {
if (!CheckSequenceLocks(::ChainstateActive(), m_pool, tx,
STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) {
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND,
"non-BIP68-final");
}
Expand Down
5 changes: 3 additions & 2 deletions src/validation.h
Expand Up @@ -437,8 +437,9 @@ bool TestLockPointValidity(const LockPoints *lp)
*
* See consensus/consensus.h for flag definitions.
*/
bool CheckSequenceLocks(const CTxMemPool &pool, const CTransaction &tx,
int flags, LockPoints *lp = nullptr,
bool CheckSequenceLocks(CChainState &active_chainstate, const CTxMemPool &pool,
const CTransaction &tx, int flags,
LockPoints *lp = nullptr,
bool useExistingLockPoints = false)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs);

Expand Down

0 comments on commit 3e47401

Please sign in to comment.