diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -175,7 +175,7 @@ if (coin.IsCoinBase() && nSpendHeight - coin.GetHeight() < COINBASE_MATURITY) { return state.Invalid( - ValidationInvalidReason::TX_MISSING_INPUTS, false, + ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase", strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.GetHeight())); diff --git a/src/consensus/validation.h b/src/consensus/validation.h --- a/src/consensus/validation.h +++ b/src/consensus/validation.h @@ -55,9 +55,11 @@ // Only loose txn: //! didn't meet our local policy rules TX_NOT_STANDARD, - //! a transaction was missing some of its inputs (or its inputs were spent - //! at < coinbase maturity height) + //! a transaction was missing some of its inputs TX_MISSING_INPUTS, + //! transaction spends a coinbase too early, or violates locktime/sequence + //! locks + TX_PREMATURE_SPEND, /** * Tx already in mempool or conflicts with a tx in the chain * TODO: Currently this is only used if the transaction already exists in @@ -75,6 +77,7 @@ r == ValidationInvalidReason::CONSENSUS || r == ValidationInvalidReason::RECENT_CONSENSUS_CHANGE || r == ValidationInvalidReason::TX_NOT_STANDARD || + r == ValidationInvalidReason::TX_PREMATURE_SPEND || r == ValidationInvalidReason::TX_MISSING_INPUTS || r == ValidationInvalidReason::TX_CONFLICT || r == ValidationInvalidReason::TX_MEMPOOL_POLICY; diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1276,6 +1276,7 @@ case ValidationInvalidReason::BLOCK_TIME_FUTURE: case ValidationInvalidReason::TX_NOT_STANDARD: case ValidationInvalidReason::TX_MISSING_INPUTS: + case ValidationInvalidReason::TX_PREMATURE_SPEND: case ValidationInvalidReason::TX_CONFLICT: case ValidationInvalidReason::TX_MEMPOOL_POLICY: break; diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -375,7 +375,7 @@ consensusParams, tx, ctxState, STANDARD_LOCKTIME_VERIFY_FLAGS)) { // We copy the state from a dummy to ensure we don't increase the // ban score of peer for transaction that could be valid in the future. - return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, + return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, ctxState.GetRejectReason(), ctxState.GetDebugMessage()); } @@ -456,7 +456,7 @@ // own. if (!CheckSequenceLocks(pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) { - return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, + return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-BIP68-final"); } @@ -1700,17 +1700,15 @@ Amount txfee = Amount::zero(); if (!isCoinBase && !Consensus::CheckTxInputs(tx, state, view, pindex->nHeight, txfee)) { - if (state.GetReason() == - ValidationInvalidReason::TX_MISSING_INPUTS) { - // CheckTxInputs may return MISSING_INPUTS but we can't return - // that, as it's not defined for a block, so we reset the reason - // flag to CONSENSUS here. + if (!IsBlockReason(state.GetReason())) { + // CheckTxInputs may return MISSING_INPUTS or PREMATURE_SPEND + // but we can't return that, as it's not defined for a block, so + // we reset the reason flag to CONSENSUS here. state.Invalid(ValidationInvalidReason::CONSENSUS, false, state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage()); } - assert(IsBlockReason(state.GetReason())); return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetId().ToString(), FormatStateMessage(state)); }