aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp41
1 files changed, 23 insertions, 18 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 12d29c8d5e..035b5783c3 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -915,12 +915,15 @@ bool MemPoolAccept::ReplacementChecks(Workspace& ws)
TxValidationState& state = ws.m_state;
CFeeRate newFeeRate(ws.m_modified_fees, ws.m_vsize);
- // It's possible that the replacement pays more fees than its direct conflicts but not more
- // than all conflicts (i.e. the direct conflicts have high-fee descendants). However, if the
- // replacement doesn't pay more fees than its direct conflicts, then we can be sure it's not
- // more economically rational to mine. Before we go digging through the mempool for all
- // transactions that would need to be removed (direct conflicts and all descendants), check
- // that the replacement transaction pays more than its direct conflicts.
+ // The replacement transaction must have a higher feerate than its direct conflicts.
+ // - The motivation for this check is to ensure that the replacement transaction is preferable for
+ // block-inclusion, compared to what would be removed from the mempool.
+ // - This logic predates ancestor feerate-based transaction selection, which is why it doesn't
+ // consider feerates of descendants.
+ // - Note: Ancestor feerate-based transaction selection has made this comparison insufficient to
+ // guarantee that this is incentive-compatible for miners, because it is possible for a
+ // descendant transaction of a direct conflict to pay a higher feerate than the transaction that
+ // might replace them, under these rules.
if (const auto err_string{PaysMoreThanConflicts(ws.m_iters_conflicting, newFeeRate, hash)}) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "insufficient fee", *err_string);
}
@@ -1318,7 +1321,7 @@ PackageMempoolAcceptResult MemPoolAccept::AcceptPackage(const Package& package,
// we know is that the inputs aren't available.
if (m_pool.exists(GenTxid::Wtxid(wtxid))) {
// Exact transaction already exists in the mempool.
- auto iter = m_pool.GetIter(wtxid);
+ auto iter = m_pool.GetIter(txid);
assert(iter != std::nullopt);
results.emplace(wtxid, MempoolAcceptResult::MempoolTx(iter.value()->GetTxSize(), iter.value()->GetFee()));
} else if (m_pool.exists(GenTxid::Txid(txid))) {
@@ -1923,7 +1926,10 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
{
AssertLockHeld(cs_main);
assert(pindex);
- assert(*pindex->phashBlock == block.GetHash());
+
+ uint256 block_hash{block.GetHash()};
+ assert(*pindex->phashBlock == block_hash);
+
int64_t nTimeStart = GetTimeMicros();
// Check it again in case a previous version let a bad block in
@@ -1957,7 +1963,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
- if (block.GetHash() == m_params.GetConsensus().hashGenesisBlock) {
+ if (block_hash == m_params.GetConsensus().hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
@@ -2214,12 +2220,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime5 - nTime4), nTimeIndex * MICRO, nTimeIndex * MILLI / nBlocksTotal);
TRACE6(validation, block_connected,
- block.GetHash().data(),
+ block_hash.data(),
pindex->nHeight,
block.vtx.size(),
nInputs,
nSigOpsCost,
- GetTimeMicros() - nTimeStart // in microseconds (µs)
+ nTime5 - nTimeStart // in microseconds (µs)
);
return true;
@@ -2370,14 +2376,13 @@ bool CChainState::FlushStateToDisk(
return AbortNode(state, "Failed to write to coin database");
nLastFlush = nNow;
full_flush_completed = true;
+ TRACE5(utxocache, flush,
+ (int64_t)(GetTimeMicros() - nNow.count()), // in microseconds (µs)
+ (u_int32_t)mode,
+ (u_int64_t)coins_count,
+ (u_int64_t)coins_mem_usage,
+ (bool)fFlushForPrune);
}
- TRACE6(utxocache, flush,
- (int64_t)(GetTimeMicros() - nNow.count()), // in microseconds (µs)
- (u_int32_t)mode,
- (u_int64_t)coins_count,
- (u_int64_t)coins_mem_usage,
- (bool)fFlushForPrune,
- (bool)fDoFullFlush);
}
if (full_flush_completed) {
// Update best block in wallet (so we can detect restored wallets).