Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | if (lp->maxInputBlock) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// LockPoints still valid | // LockPoints still valid | ||||
return true; | return true; | ||||
} | } | ||||
bool CheckSequenceLocks(CChainState &active_chainstate, const CTxMemPool &pool, | bool CheckSequenceLocks(CBlockIndex *tip, const CCoinsView &coins_view, | ||||
const CTransaction &tx, int flags, LockPoints *lp, | const CTransaction &tx, int flags, LockPoints *lp, | ||||
bool useExistingLockPoints) { | bool useExistingLockPoints) { | ||||
AssertLockHeld(cs_main); | |||||
AssertLockHeld(pool.cs); | |||||
CBlockIndex *tip = active_chainstate.m_chain.Tip(); | |||||
assert(tip != nullptr); | assert(tip != nullptr); | ||||
CBlockIndex index; | CBlockIndex index; | ||||
index.pprev = tip; | index.pprev = tip; | ||||
// CheckSequenceLocks() uses active_chainstate.m_chain.Height()+1 to | // CheckSequenceLocks() uses active_chainstate.m_chain.Height()+1 to | ||||
// evaluate height based locks because when SequenceLocks() is called within | // evaluate height based locks because when SequenceLocks() is called within | ||||
// ConnectBlock(), the height of the block *being* evaluated is what is | // 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* | // 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() | // block, we need to use one more than active_chainstate.m_chain.Height() | ||||
index.nHeight = tip->nHeight + 1; | index.nHeight = tip->nHeight + 1; | ||||
std::pair<int, int64_t> lockPair; | std::pair<int, int64_t> lockPair; | ||||
if (useExistingLockPoints) { | if (useExistingLockPoints) { | ||||
assert(lp); | assert(lp); | ||||
lockPair.first = lp->height; | lockPair.first = lp->height; | ||||
lockPair.second = lp->time; | lockPair.second = lp->time; | ||||
} else { | } else { | ||||
// CoinsTip() contains the UTXO set for active_chainstate.m_chain.Tip() | |||||
CCoinsViewMemPool viewMemPool(&active_chainstate.CoinsTip(), pool); | |||||
std::vector<int> prevheights; | std::vector<int> prevheights; | ||||
prevheights.resize(tx.vin.size()); | prevheights.resize(tx.vin.size()); | ||||
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { | ||||
const CTxIn &txin = tx.vin[txinIndex]; | const CTxIn &txin = tx.vin[txinIndex]; | ||||
Coin coin; | Coin coin; | ||||
if (!viewMemPool.GetCoin(txin.prevout, coin)) { | if (!coins_view.GetCoin(txin.prevout, coin)) { | ||||
return error("%s: Missing input", __func__); | return error("%s: Missing input", __func__); | ||||
} | } | ||||
if (coin.GetHeight() == MEMPOOL_HEIGHT) { | if (coin.GetHeight() == MEMPOOL_HEIGHT) { | ||||
// Assume all mempool transaction confirm in the next block | // Assume all mempool transaction confirm in the next block | ||||
prevheights[txinIndex] = tip->nHeight + 1; | prevheights[txinIndex] = tip->nHeight + 1; | ||||
} else { | } else { | ||||
prevheights[txinIndex] = coin.GetHeight(); | prevheights[txinIndex] = coin.GetHeight(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 303 Lines • ▼ Show 20 Lines | bool MemPoolAccept::PreChecks(ATMPArgs &args, Workspace &ws) { | ||||
// we have all inputs cached now, so switch back to dummy (to protect | // we have all inputs cached now, so switch back to dummy (to protect | ||||
// against bugs where we pull more inputs from disk that miss being | // against bugs where we pull more inputs from disk that miss being | ||||
// added to coins_to_uncache) | // added to coins_to_uncache) | ||||
m_view.SetBackend(m_dummy); | m_view.SetBackend(m_dummy); | ||||
// Only accept BIP68 sequence locked transactions that can be mined in | // Only accept BIP68 sequence locked transactions that can be mined in | ||||
// the next block; we don't want our mempool filled up with transactions | // the next block; we don't want our mempool filled up with transactions | ||||
// that can't be mined yet. Must keep pool.cs for this unless we change | // that can't be mined yet. | ||||
// CheckSequenceLocks to take a CoinsViewCache instead of create its | // Pass in m_view which has all of the relevant inputs cached. Note that, | ||||
// own. | // since m_view's backend was removed, it no longer pulls coins from the | ||||
if (!CheckSequenceLocks(m_active_chainstate, m_pool, tx, | // mempool. | ||||
if (!CheckSequenceLocks(m_active_chainstate.m_chain.Tip(), m_view, tx, | |||||
STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) { | STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) { | ||||
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, | return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, | ||||
"non-BIP68-final"); | "non-BIP68-final"); | ||||
} | } | ||||
if (!Consensus::CheckTxInputs( | if (!Consensus::CheckTxInputs( | ||||
tx, state, m_view, | tx, state, m_view, | ||||
m_active_chainstate.m_blockman.GetSpendHeight(m_view), | m_active_chainstate.m_blockman.GetSpendHeight(m_view), | ||||
▲ Show 20 Lines • Show All 5,553 Lines • Show Last 20 Lines |