Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 371 Lines • ▼ Show 20 Lines | struct Workspace { | ||||
Workspace(const CTransactionRef &ptx, | Workspace(const CTransactionRef &ptx, | ||||
const uint32_t next_block_script_verify_flags) | const uint32_t next_block_script_verify_flags) | ||||
: m_ptx(ptx), | : m_ptx(ptx), | ||||
m_next_block_script_verify_flags(next_block_script_verify_flags) { | m_next_block_script_verify_flags(next_block_script_verify_flags) { | ||||
} | } | ||||
CTxMemPool::setEntries m_ancestors; | CTxMemPool::setEntries m_ancestors; | ||||
std::unique_ptr<CTxMemPoolEntry> m_entry; | std::unique_ptr<CTxMemPoolEntry> m_entry; | ||||
Amount m_fee_out; | Amount m_base_fees; | ||||
Amount m_modified_fees; | Amount m_modified_fees; | ||||
const CTransactionRef &m_ptx; | const CTransactionRef &m_ptx; | ||||
TxValidationState m_state; | TxValidationState m_state; | ||||
// ABC specific flags that are used in both PreChecks and | // ABC specific flags that are used in both PreChecks and | ||||
// ConsensusScriptChecks | // ConsensusScriptChecks | ||||
▲ Show 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | if (!CheckSequenceLocks(m_active_chainstate, m_pool, 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), | ||||
ws.m_fee_out)) { | ws.m_base_fees)) { | ||||
// state filled in by CheckTxInputs | // state filled in by CheckTxInputs | ||||
return false; | return false; | ||||
} | } | ||||
// Check for non-standard pay-to-script-hash in inputs | // Check for non-standard pay-to-script-hash in inputs | ||||
if (fRequireStandard && | if (fRequireStandard && | ||||
!AreInputsStandard(tx, m_view, ws.m_next_block_script_verify_flags)) { | !AreInputsStandard(tx, m_view, ws.m_next_block_script_verify_flags)) { | ||||
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, | return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, | ||||
"bad-txns-nonstandard-inputs"); | "bad-txns-nonstandard-inputs"); | ||||
} | } | ||||
// nModifiedFees includes any fee deltas from PrioritiseTransaction | // nModifiedFees includes any fee deltas from PrioritiseTransaction | ||||
nModifiedFees = ws.m_fee_out; | nModifiedFees = ws.m_base_fees; | ||||
m_pool.ApplyDelta(txid, nModifiedFees); | m_pool.ApplyDelta(txid, nModifiedFees); | ||||
// Keep track of transactions that spend a coinbase, which we re-scan | // Keep track of transactions that spend a coinbase, which we re-scan | ||||
// during reorgs to ensure COINBASE_MATURITY is still met. | // during reorgs to ensure COINBASE_MATURITY is still met. | ||||
bool fSpendsCoinbase = false; | bool fSpendsCoinbase = false; | ||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
const Coin &coin = m_view.AccessCoin(txin.prevout); | const Coin &coin = m_view.AccessCoin(txin.prevout); | ||||
if (coin.IsCoinBase()) { | if (coin.IsCoinBase()) { | ||||
Show All 20 Lines | bool MemPoolAccept::PreChecks(ATMPArgs &args, Workspace &ws) { | ||||
PrecomputedTransactionData txdata(tx); | PrecomputedTransactionData txdata(tx); | ||||
if (!CheckInputScripts(tx, state, m_view, scriptVerifyFlags, true, false, | if (!CheckInputScripts(tx, state, m_view, scriptVerifyFlags, true, false, | ||||
txdata, ws.m_sig_checks_standard)) { | txdata, ws.m_sig_checks_standard)) { | ||||
// State filled in by CheckInputScripts | // State filled in by CheckInputScripts | ||||
return false; | return false; | ||||
} | } | ||||
entry.reset(new CTxMemPoolEntry( | entry.reset(new CTxMemPoolEntry( | ||||
ptx, ws.m_fee_out, nAcceptTime, m_active_chainstate.m_chain.Height(), | ptx, ws.m_base_fees, nAcceptTime, m_active_chainstate.m_chain.Height(), | ||||
fSpendsCoinbase, ws.m_sig_checks_standard, lp)); | fSpendsCoinbase, ws.m_sig_checks_standard, lp)); | ||||
unsigned int nVirtualSize = entry->GetTxVirtualSize(); | unsigned int nVirtualSize = entry->GetTxVirtualSize(); | ||||
Amount mempoolRejectFee = | Amount mempoolRejectFee = | ||||
m_pool | m_pool | ||||
.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | .GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | ||||
1000000) | 1000000) | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
MempoolAcceptResult | MempoolAcceptResult | ||||
MemPoolAccept::AcceptSingleTransaction(const CTransactionRef &ptx, | MemPoolAccept::AcceptSingleTransaction(const CTransactionRef &ptx, | ||||
ATMPArgs &args) { | ATMPArgs &args) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// mempool "read lock" (held through | // mempool "read lock" (held through | ||||
// GetMainSignals().TransactionAddedToMempool()) | // GetMainSignals().TransactionAddedToMempool()) | ||||
LOCK(m_pool.cs); | LOCK(m_pool.cs); | ||||
Workspace workspace(ptx, GetNextBlockScriptFlags( | Workspace ws(ptx, GetNextBlockScriptFlags( | ||||
args.m_config.GetChainParams().GetConsensus(), | args.m_config.GetChainParams().GetConsensus(), | ||||
m_active_chainstate.m_chain.Tip())); | m_active_chainstate.m_chain.Tip())); | ||||
if (!PreChecks(args, workspace)) { | if (!PreChecks(args, ws)) { | ||||
return MempoolAcceptResult(workspace.m_state); | return MempoolAcceptResult(ws.m_state); | ||||
} | } | ||||
// Only compute the precomputed transaction data if we need to verify | // Only compute the precomputed transaction data if we need to verify | ||||
// scripts (ie, other policy checks pass). We perform the inexpensive | // scripts (ie, other policy checks pass). We perform the inexpensive | ||||
// checks first and avoid hashing and signature verification unless those | // checks first and avoid hashing and signature verification unless those | ||||
// checks pass, to mitigate CPU exhaustion denial-of-service attacks. | // checks pass, to mitigate CPU exhaustion denial-of-service attacks. | ||||
PrecomputedTransactionData txdata(*ptx); | PrecomputedTransactionData txdata(*ptx); | ||||
if (!ConsensusScriptChecks(args, workspace, txdata)) { | if (!ConsensusScriptChecks(args, ws, txdata)) { | ||||
return MempoolAcceptResult(workspace.m_state); | return MempoolAcceptResult(ws.m_state); | ||||
} | } | ||||
// Tx was accepted, but not added | // Tx was accepted, but not added | ||||
if (args.m_test_accept) { | if (args.m_test_accept) { | ||||
return MempoolAcceptResult(workspace.m_fee_out); | return MempoolAcceptResult(ws.m_base_fees); | ||||
} | } | ||||
if (!Finalize(args, workspace)) { | if (!Finalize(args, ws)) { | ||||
return MempoolAcceptResult(workspace.m_state); | return MempoolAcceptResult(ws.m_state); | ||||
} | } | ||||
GetMainSignals().TransactionAddedToMempool( | GetMainSignals().TransactionAddedToMempool( | ||||
ptx, m_pool.GetAndIncrementSequence()); | ptx, m_pool.GetAndIncrementSequence()); | ||||
return MempoolAcceptResult(workspace.m_fee_out); | return MempoolAcceptResult(ws.m_base_fees); | ||||
} | } | ||||
} // namespace | } // namespace | ||||
/** | /** | ||||
* (try to) add transaction to memory pool with a specified acceptance time. | * (try to) add transaction to memory pool with a specified acceptance time. | ||||
*/ | */ | ||||
static MempoolAcceptResult AcceptToMemoryPoolWithTime( | static MempoolAcceptResult AcceptToMemoryPoolWithTime( | ||||
▲ Show 20 Lines • Show All 5,574 Lines • Show Last 20 Lines |