diff options
Diffstat (limited to 'src/validation.cpp')
-rw-r--r-- | src/validation.cpp | 41 |
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). |