mempool: Reduce ERROR logging for mempool rejects

Continues "Make logging for validation optional" from #6519.

The idea there was to remove all ERROR logging of rejected transaction,
and move it to one message in the class 'mempoolrej' which logs the
state message (and debug info). The superfluous ERRORs in the log
"terrify" users, see for example issue #5794.

Unfortunately a lot of new logging was introduced in #6871 (RBF) and
 #7287 (misc refactoring). This pull updates that new code.
This commit is contained in:
Wladimir J. van der Laan 2016-02-24 18:34:37 +01:00
parent 317462123f
commit 8fc81e0983

View File

@ -947,7 +947,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
*pfMissingInputs = false; *pfMissingInputs = false;
if (!CheckTransaction(tx, state)) if (!CheckTransaction(tx, state))
return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); return false; // state filled in by CheckTransaction
// Coinbase is only valid in a block, not as a loose transaction // Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase()) if (tx.IsCoinBase())
@ -1160,10 +1160,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
if (setConflicts.count(hashAncestor)) if (setConflicts.count(hashAncestor))
{ {
return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s", return state.DoS(10, false,
REJECT_INVALID, "bad-txns-spends-conflicting-tx", false,
strprintf("%s spends conflicting transaction %s",
hash.ToString(), hash.ToString(),
hashAncestor.ToString()), hashAncestor.ToString()));
REJECT_INVALID, "bad-txns-spends-conflicting-tx");
} }
} }
@ -1200,11 +1201,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// that we don't spend too much time walking descendants. // that we don't spend too much time walking descendants.
// This should be rare. // This should be rare.
if (mi->IsDirty()) { if (mi->IsDirty()) {
return state.DoS(0, return state.DoS(0, false,
error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants", REJECT_NONSTANDARD, "too many potential replacements", false,
strprintf("too many potential replacements: rejecting replacement %s; cannot replace tx %s with untracked descendants",
hash.ToString(), hash.ToString(),
mi->GetTx().GetHash().ToString()), mi->GetTx().GetHash().ToString()));
REJECT_NONSTANDARD, "too many potential replacements");
} }
// Don't allow the replacement to reduce the feerate of the // Don't allow the replacement to reduce the feerate of the
@ -1226,12 +1227,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
if (newFeeRate <= oldFeeRate) if (newFeeRate <= oldFeeRate)
{ {
return state.DoS(0, return state.DoS(0, false,
error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s", REJECT_INSUFFICIENTFEE, "insufficient fee", false,
strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
hash.ToString(), hash.ToString(),
newFeeRate.ToString(), newFeeRate.ToString(),
oldFeeRate.ToString()), oldFeeRate.ToString()));
REJECT_INSUFFICIENTFEE, "insufficient fee");
} }
BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin) BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin)
@ -1255,12 +1256,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
nConflictingSize += it->GetTxSize(); nConflictingSize += it->GetTxSize();
} }
} else { } else {
return state.DoS(0, return state.DoS(0, false,
error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n", REJECT_NONSTANDARD, "too many potential replacements", false,
strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
hash.ToString(), hash.ToString(),
nConflictingCount, nConflictingCount,
maxDescendantsToVisit), maxDescendantsToVisit));
REJECT_NONSTANDARD, "too many potential replacements");
} }
for (unsigned int j = 0; j < tx.vin.size(); j++) for (unsigned int j = 0; j < tx.vin.size(); j++)
@ -1275,9 +1276,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// it's cheaper to just check if the new input refers to a // it's cheaper to just check if the new input refers to a
// tx that's in the mempool. // tx that's in the mempool.
if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end())
return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d", return state.DoS(0, false,
hash.ToString(), j), REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false,
REJECT_NONSTANDARD, "replacement-adds-unconfirmed"); strprintf("replacement %s adds unconfirmed input, idx %d",
hash.ToString(), j));
} }
} }
@ -1286,9 +1288,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// transactions would not be paid for. // transactions would not be paid for.
if (nModifiedFees < nConflictingFees) if (nModifiedFees < nConflictingFees)
{ {
return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", return state.DoS(0, false,
hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), REJECT_INSUFFICIENTFEE, "insufficient fee", false,
REJECT_INSUFFICIENTFEE, "insufficient fee"); strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)));
} }
// Finally in addition to paying more fees than the conflicts the // Finally in addition to paying more fees than the conflicts the
@ -1296,19 +1299,19 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
CAmount nDeltaFees = nModifiedFees - nConflictingFees; CAmount nDeltaFees = nModifiedFees - nConflictingFees;
if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) if (nDeltaFees < ::minRelayTxFee.GetFee(nSize))
{ {
return state.DoS(0, return state.DoS(0, false,
error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s", REJECT_INSUFFICIENTFEE, "insufficient fee", false,
strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
hash.ToString(), hash.ToString(),
FormatMoney(nDeltaFees), FormatMoney(nDeltaFees),
FormatMoney(::minRelayTxFee.GetFee(nSize))), FormatMoney(::minRelayTxFee.GetFee(nSize))));
REJECT_INSUFFICIENTFEE, "insufficient fee");
} }
} }
// Check against previous transactions // Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks. // This is done last to help prevent CPU exhaustion denial-of-service attacks.
if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); return false; // state filled in by CheckInputs
// Check again against just the consensus-critical mandatory script // Check again against just the consensus-critical mandatory script
// verification flags, in case of bugs in the standard flags that cause // verification flags, in case of bugs in the standard flags that cause