aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuhas Daftuar <sdaftuar@gmail.com>2019-03-08 09:55:23 -0500
committerSuhas Daftuar <sdaftuar@gmail.com>2019-05-02 15:30:58 -0400
commit0ff1c2a838da9e8dc7f77609adc89124bbea3e2b (patch)
tree884d36c96434932ac1cf3866e48016f49f606b6a
parent54470e767bab37f9b7089782b1be73d5883bb244 (diff)
Separate reason for premature spends (coinbase/locktime)
-rw-r--r--src/consensus/tx_verify.cpp2
-rw-r--r--src/consensus/validation.h4
-rw-r--r--src/net_processing.cpp1
-rw-r--r--src/validation.cpp13
4 files changed, 12 insertions, 8 deletions
diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp
index c13a38cd6f..4b93cae848 100644
--- a/src/consensus/tx_verify.cpp
+++ b/src/consensus/tx_verify.cpp
@@ -172,7 +172,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
// If prev is coinbase, check that it's matured
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));
}
diff --git a/src/consensus/validation.h b/src/consensus/validation.h
index 3079f3b08c..2e23f4b3a4 100644
--- a/src/consensus/validation.h
+++ b/src/consensus/validation.h
@@ -49,7 +49,8 @@ enum class ValidationInvalidReason {
BLOCK_CHECKPOINT, //!< the block failed to meet one of our checkpoints
// Only loose txn:
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
* activation, or witness may have been malleated (which includes
@@ -72,6 +73,7 @@ inline bool IsTransactionReason(ValidationInvalidReason r)
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_WITNESS_MUTATED ||
r == ValidationInvalidReason::TX_CONFLICT ||
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 3319d3211a..71ebd72b83 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1040,6 +1040,7 @@ static bool MaybePunishNode(NodeId nodeid, const CValidationState& state, bool v
case ValidationInvalidReason::BLOCK_TIME_FUTURE:
case ValidationInvalidReason::TX_NOT_STANDARD:
case ValidationInvalidReason::TX_MISSING_INPUTS:
+ case ValidationInvalidReason::TX_PREMATURE_SPEND:
case ValidationInvalidReason::TX_WITNESS_MUTATED:
case ValidationInvalidReason::TX_CONFLICT:
case ValidationInvalidReason::TX_MEMPOOL_POLICY:
diff --git a/src/validation.cpp b/src/validation.cpp
index c29bff9d30..c394afd82a 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -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
// be mined yet.
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?
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
// CoinsViewCache instead of create its own
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;
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;
if (!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.GetHash().ToString(), FormatStateMessage(state));
}
nFees += txfee;