mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-10 10:52:31 -05:00
Separate reason for premature spends (coinbase/locktime)
This commit is contained in:
parent
54470e767b
commit
0ff1c2a838
4 changed files with 12 additions and 8 deletions
|
@ -172,7 +172,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
|
||||||
|
|
||||||
// If prev is coinbase, check that it's matured
|
// If prev is coinbase, check that it's matured
|
||||||
if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
|
if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
|
||||||
return state.Invalid(ValidationInvalidReason::TX_MISSING_INPUTS, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
|
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_INVALID, "bad-txns-premature-spend-of-coinbase",
|
||||||
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
|
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,8 @@ enum class ValidationInvalidReason {
|
||||||
BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints
|
BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints
|
||||||
// Only loose txn:
|
// Only loose txn:
|
||||||
TX_NOT_STANDARD, //!< didn't meet our local policy rules
|
TX_NOT_STANDARD, //!< didn't meet our local policy rules
|
||||||
TX_MISSING_INPUTS, //!< a transaction was missing some of its inputs (or its inputs were spent at < coinbase maturity height)
|
TX_MISSING_INPUTS, //!< a transaction was missing some of its inputs
|
||||||
|
TX_PREMATURE_SPEND, //!< transaction spends a coinbase too early, or violates locktime/sequence locks
|
||||||
/**
|
/**
|
||||||
* Transaction might be missing a witness, have a witness prior to SegWit
|
* Transaction might be missing a witness, have a witness prior to SegWit
|
||||||
* activation, or witness may have been malleated (which includes
|
* activation, or witness may have been malleated (which includes
|
||||||
|
@ -72,6 +73,7 @@ inline bool IsTransactionReason(ValidationInvalidReason r)
|
||||||
r == ValidationInvalidReason::CONSENSUS ||
|
r == ValidationInvalidReason::CONSENSUS ||
|
||||||
r == ValidationInvalidReason::RECENT_CONSENSUS_CHANGE ||
|
r == ValidationInvalidReason::RECENT_CONSENSUS_CHANGE ||
|
||||||
r == ValidationInvalidReason::TX_NOT_STANDARD ||
|
r == ValidationInvalidReason::TX_NOT_STANDARD ||
|
||||||
|
r == ValidationInvalidReason::TX_PREMATURE_SPEND ||
|
||||||
r == ValidationInvalidReason::TX_MISSING_INPUTS ||
|
r == ValidationInvalidReason::TX_MISSING_INPUTS ||
|
||||||
r == ValidationInvalidReason::TX_WITNESS_MUTATED ||
|
r == ValidationInvalidReason::TX_WITNESS_MUTATED ||
|
||||||
r == ValidationInvalidReason::TX_CONFLICT ||
|
r == ValidationInvalidReason::TX_CONFLICT ||
|
||||||
|
|
|
@ -1040,6 +1040,7 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
|
||||||
case ValidationInvalidReason::BLOCK_TIME_FUTURE:
|
case ValidationInvalidReason::BLOCK_TIME_FUTURE:
|
||||||
case ValidationInvalidReason::TX_NOT_STANDARD:
|
case ValidationInvalidReason::TX_NOT_STANDARD:
|
||||||
case ValidationInvalidReason::TX_MISSING_INPUTS:
|
case ValidationInvalidReason::TX_MISSING_INPUTS:
|
||||||
|
case ValidationInvalidReason::TX_PREMATURE_SPEND:
|
||||||
case ValidationInvalidReason::TX_WITNESS_MUTATED:
|
case ValidationInvalidReason::TX_WITNESS_MUTATED:
|
||||||
case ValidationInvalidReason::TX_CONFLICT:
|
case ValidationInvalidReason::TX_CONFLICT:
|
||||||
case ValidationInvalidReason::TX_MEMPOOL_POLICY:
|
case ValidationInvalidReason::TX_MEMPOOL_POLICY:
|
||||||
|
|
|
@ -596,7 +596,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
// block; we don't want our mempool filled up with transactions that can't
|
// block; we don't want our mempool filled up with transactions that can't
|
||||||
// be mined yet.
|
// be mined yet.
|
||||||
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
|
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
|
||||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "non-final");
|
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-final");
|
||||||
|
|
||||||
// is it already in the memory pool?
|
// is it already in the memory pool?
|
||||||
if (pool.exists(hash)) {
|
if (pool.exists(hash)) {
|
||||||
|
@ -685,7 +685,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
||||||
// Must keep pool.cs for this unless we change CheckSequenceLocks to take a
|
// Must keep pool.cs for this unless we change CheckSequenceLocks to take a
|
||||||
// CoinsViewCache instead of create its own
|
// CoinsViewCache instead of create its own
|
||||||
if (!CheckSequenceLocks(pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
|
if (!CheckSequenceLocks(pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
|
||||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "non-BIP68-final");
|
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-BIP68-final");
|
||||||
|
|
||||||
CAmount nFees = 0;
|
CAmount nFees = 0;
|
||||||
if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) {
|
if (!Consensus::CheckTxInputs(tx, state, view, GetSpendHeight(view), nFees)) {
|
||||||
|
@ -1965,13 +1965,14 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
{
|
{
|
||||||
CAmount txfee = 0;
|
CAmount txfee = 0;
|
||||||
if (!Consensus::CheckTxInputs(tx, state, view, pindex->nHeight, txfee)) {
|
if (!Consensus::CheckTxInputs(tx, state, view, pindex->nHeight, txfee)) {
|
||||||
if (state.GetReason() == ValidationInvalidReason::TX_MISSING_INPUTS) {
|
if (!IsBlockReason(state.GetReason())) {
|
||||||
// CheckTxInputs may return MISSING_INPUTS but we can't return that, as
|
// CheckTxInputs may return MISSING_INPUTS or
|
||||||
// it's not defined for a block, so we reset the reason flag to CONSENSUS here.
|
// 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.Invalid(ValidationInvalidReason::CONSENSUS, false,
|
||||||
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
|
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
|
||||||
}
|
}
|
||||||
assert(IsBlockReason(state.GetReason()));
|
|
||||||
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
|
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
|
||||||
}
|
}
|
||||||
nFees += txfee;
|
nFees += txfee;
|
||||||
|
|
Loading…
Add table
Reference in a new issue