mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
optimization: move duplicate checks outside of coinbase branch
`IsCoinBase` means single input with NULL prevout, so it makes sense to restrict duplicate check to non-coinbase transactions only. The behavior is the same as before, except that single-input-transactions aren't checked for duplicates anymore (~70-90% of the cases, see https://transactionfee.info/charts/transactions-1in). I've added braces to the conditions and loops to simplify review of followup commits. > cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/src/bench/bench_bitcoin -filter='CheckBlockBench|DuplicateInputs|ProcessTransactionBench' -min-time=10000 > C++ compiler .......................... AppleClang 16.0.0.16000026 | ns/block | block/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 335,917.12 | 2,976.92 | 1.3% | 11.01 | `CheckBlockBench` | ns/op | op/s | err% | total | benchmark |--------------------:|--------------------:|--------:|----------:|:---------- | 3,286,337.42 | 304.29 | 1.1% | 10.90 | `DuplicateInputs` | 9,561.02 | 104,591.35 | 0.2% | 11.02 | `ProcessTransactionBench`
This commit is contained in:
parent
7c4f0d045c
commit
c161ef8ac4
@ -38,22 +38,25 @@ bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
|
||||
// of a tx as spent, it does not check if the tx has duplicate inputs.
|
||||
// Failure to run this check will result in either a crash or an inflation bug, depending on the implementation of
|
||||
// the underlying coins database.
|
||||
std::set<COutPoint> vInOutPoints;
|
||||
for (const auto& txin : tx.vin) {
|
||||
if (!vInOutPoints.insert(txin.prevout).second)
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
|
||||
}
|
||||
if (tx.vin.size() == 1) {
|
||||
if (tx.IsCoinBase()) {
|
||||
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) {
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::set<COutPoint> vInOutPoints;
|
||||
for (const auto& txin : tx.vin) {
|
||||
if (!vInOutPoints.insert(txin.prevout).second) {
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
|
||||
}
|
||||
}
|
||||
|
||||
if (tx.IsCoinBase())
|
||||
{
|
||||
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& txin : tx.vin)
|
||||
if (txin.prevout.IsNull())
|
||||
for (const auto& txin : tx.vin) {
|
||||
if (txin.prevout.IsNull()) {
|
||||
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user