Skip to content

Commit 0ff1c2a

Browse files
committed
Separate reason for premature spends (coinbase/locktime)
1 parent 54470e7 commit 0ff1c2a

File tree

4 files changed

+12
-8
lines changed

4 files changed

+12
-8
lines changed

src/consensus/tx_verify.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
172172

173173
// If prev is coinbase, check that it's matured
174174
if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
175-
return state.Invalid(ValidationInvalidReason::TX_MISSING_INPUTS, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
175+
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
176176
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
177177
}
178178

src/consensus/validation.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ enum class ValidationInvalidReason {
4949
BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints
5050
// Only loose txn:
5151
TX_NOT_STANDARD, //!< didn't meet our local policy rules
52-
TX_MISSING_INPUTS, //!< a transaction was missing some of its inputs (or its inputs were spent at < coinbase maturity height)
52+
TX_MISSING_INPUTS, //!< a transaction was missing some of its inputs
53+
TX_PREMATURE_SPEND, //!< transaction spends a coinbase too early, or violates locktime/sequence locks
5354
/**
5455
* Transaction might be missing a witness, have a witness prior to SegWit
5556
* activation, or witness may have been malleated (which includes
@@ -72,6 +73,7 @@ inline bool IsTransactionReason(ValidationInvalidReason r)
7273
r == ValidationInvalidReason::CONSENSUS ||
7374
r == ValidationInvalidReason::RECENT_CONSENSUS_CHANGE ||
7475
r == ValidationInvalidReason::TX_NOT_STANDARD ||
76+
r == ValidationInvalidReason::TX_PREMATURE_SPEND ||
7577
r == ValidationInvalidReason::TX_MISSING_INPUTS ||
7678
r == ValidationInvalidReason::TX_WITNESS_MUTATED ||
7779
r == ValidationInvalidReason::TX_CONFLICT ||

src/net_processing.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,7 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
10401040
case ValidationInvalidReason::BLOCK_TIME_FUTURE:
10411041
case ValidationInvalidReason::TX_NOT_STANDARD:
10421042
case ValidationInvalidReason::TX_MISSING_INPUTS:
1043+
case ValidationInvalidReason::TX_PREMATURE_SPEND:
10431044
case ValidationInvalidReason::TX_WITNESS_MUTATED:
10441045
case ValidationInvalidReason::TX_CONFLICT:
10451046
case ValidationInvalidReason::TX_MEMPOOL_POLICY:

src/validation.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
596596
// block; we don't want our mempool filled up with transactions that can't
597597
// be mined yet.
598598
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
599-
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "non-final");
599+
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-final");
600600

601601
// is it already in the memory pool?
602602
if (pool.exists(hash)) {
@@ -685,7 +685,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
685685
// Must keep pool.cs for this unless we change CheckSequenceLocks to take a
686686
// CoinsViewCache instead of create its own
687687
if (!CheckSequenceLocks(pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
688-
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "non-BIP68-final");
688+
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-BIP68-final");
689689

690690
CAmount nFees = 0;
691691
if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) {
@@ -1965,13 +1965,14 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
19651965
{
19661966
CAmount txfee = 0;
19671967
if (!Consensus::CheckTxInputs(tx, state, view, pindex->nHeight, txfee)) {
1968-
if (state.GetReason() == ValidationInvalidReason::TX_MISSING_INPUTS) {
1969-
// CheckTxInputs may return MISSING_INPUTS but we can't return that, as
1970-
// it's not defined for a block, so we reset the reason flag to CONSENSUS here.
1968+
if (!IsBlockReason(state.GetReason())) {
1969+
// CheckTxInputs may return MISSING_INPUTS or
1970+
// PREMATURE_SPEND but we can't return that, as it's not
1971+
// defined for a block, so we reset the reason flag to
1972+
// CONSENSUS here.
19711973
state.Invalid(ValidationInvalidReason::CONSENSUS, false,
19721974
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
19731975
}
1974-
assert(IsBlockReason(state.GetReason()));
19751976
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
19761977
}
19771978
nFees += txfee;

0 commit comments

Comments
 (0)