Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 417 Lines • ▼ Show 20 Lines | |||||
static bool IsReplayProtectionEnabledForCurrentBlock(const Config &config) { | static bool IsReplayProtectionEnabledForCurrentBlock(const Config &config) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
return IsReplayProtectionEnabled(config, chainActive.Tip()); | return IsReplayProtectionEnabled(config, chainActive.Tip()); | ||||
} | } | ||||
// Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool | // Used to avoid mempool polluting consensus critical paths if CCoinsViewMempool | ||||
// were somehow broken and returning the wrong scriptPubKeys | // were somehow broken and returning the wrong scriptPubKeys | ||||
static bool | static bool CheckInputsFromMempoolAndCache( | ||||
CheckInputsFromMempoolAndCache(const CTransaction &tx, CValidationState &state, | const CTransaction &tx, CValidationState &state, | ||||
const CCoinsViewCache &view, CTxMemPool &pool, | const CCoinsViewCache &view, const CTxMemPool &pool, const uint32_t flags, | ||||
const uint32_t flags, bool cacheSigStore, | bool cacheSigStore, PrecomputedTransactionData &txdata) { | ||||
PrecomputedTransactionData &txdata) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
// pool.cs should be locked already, but go ahead and re-take the lock here | // pool.cs should be locked already, but go ahead and re-take the lock here | ||||
// to enforce that mempool doesn't change between when we check the view and | // to enforce that mempool doesn't change between when we check the view and | ||||
// when we actually call through to CheckInputs | // when we actually call through to CheckInputs | ||||
LOCK(pool.cs); | LOCK(pool.cs); | ||||
assert(!tx.IsCoinBase()); | assert(!tx.IsCoinBase()); | ||||
Show All 23 Lines | static bool CheckInputsFromMempoolAndCache( | ||||
return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, | return CheckInputs(tx, state, view, true, flags, cacheSigStore, true, | ||||
txdata); | txdata); | ||||
} | } | ||||
static bool AcceptToMemoryPoolWorker( | static bool AcceptToMemoryPoolWorker( | ||||
const Config &config, CTxMemPool &pool, CValidationState &state, | const Config &config, CTxMemPool &pool, CValidationState &state, | ||||
const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | const CTransactionRef &ptx, bool fLimitFree, bool *pfMissingInputs, | ||||
int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, | int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee, | ||||
std::vector<COutPoint> &coins_to_uncache) { | std::vector<COutPoint> &coins_to_uncache, bool test_accept) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const CTransaction &tx = *ptx; | const CTransaction &tx = *ptx; | ||||
const TxId txid = tx.GetId(); | const TxId txid = tx.GetId(); | ||||
// mempool "read lock" (held through | // mempool "read lock" (held through | ||||
// GetMainSignals().TransactionAddedToMempool()) | // GetMainSignals().TransactionAddedToMempool()) | ||||
LOCK(pool.cs); | LOCK(pool.cs); | ||||
▲ Show 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
__func__, txid.ToString(), FormatStateMessage(state)); | __func__, txid.ToString(), FormatStateMessage(state)); | ||||
} | } | ||||
LogPrintf("Warning: -promiscuousmempool flags set to not include " | LogPrintf("Warning: -promiscuousmempool flags set to not include " | ||||
"currently enforced soft forks, this may break mining or " | "currently enforced soft forks, this may break mining or " | ||||
"otherwise cause instability!\n"); | "otherwise cause instability!\n"); | ||||
} | } | ||||
if (test_accept) { | |||||
// Tx was accepted, but not added | |||||
return true; | |||||
} | |||||
// Store transaction in memory. | // Store transaction in memory. | ||||
pool.addUnchecked(txid, entry, setAncestors); | pool.addUnchecked(txid, entry, setAncestors); | ||||
// Trim mempool and check if tx was trimmed. | // Trim mempool and check if tx was trimmed. | ||||
if (!fOverrideMempoolLimit) { | if (!fOverrideMempoolLimit) { | ||||
pool.LimitSize( | pool.LimitSize( | ||||
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, | gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, | ||||
gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * | gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * | ||||
60); | 60); | ||||
if (!pool.exists(txid)) { | if (!pool.exists(txid)) { | ||||
return state.DoS(0, false, REJECT_INSUFFICIENTFEE, | return state.DoS(0, false, REJECT_INSUFFICIENTFEE, | ||||
"mempool full"); | "mempool full"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
GetMainSignals().TransactionAddedToMempool(ptx); | GetMainSignals().TransactionAddedToMempool(ptx); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* (try to) add transaction to memory pool with a specified acceptance time. | * (try to) add transaction to memory pool with a specified acceptance time. | ||||
*/ | */ | ||||
static bool AcceptToMemoryPoolWithTime( | static bool | ||||
const Config &config, CTxMemPool &pool, CValidationState &state, | AcceptToMemoryPoolWithTime(const Config &config, CTxMemPool &pool, | ||||
const CTransactionRef &tx, bool fLimitFree, bool *pfMissingInputs, | CValidationState &state, const CTransactionRef &tx, | ||||
int64_t nAcceptTime, bool fOverrideMempoolLimit, const Amount nAbsurdFee) { | bool fLimitFree, bool *pfMissingInputs, | ||||
int64_t nAcceptTime, bool fOverrideMempoolLimit, | |||||
const Amount nAbsurdFee, bool test_accept) { | |||||
std::vector<COutPoint> coins_to_uncache; | std::vector<COutPoint> coins_to_uncache; | ||||
bool res = AcceptToMemoryPoolWorker( | bool res = AcceptToMemoryPoolWorker( | ||||
config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, | config, pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, | ||||
fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache); | fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, test_accept); | ||||
if (!res) { | if (!res) { | ||||
for (const COutPoint &outpoint : coins_to_uncache) { | for (const COutPoint &outpoint : coins_to_uncache) { | ||||
pcoinsTip->Uncache(outpoint); | pcoinsTip->Uncache(outpoint); | ||||
} | } | ||||
} | } | ||||
// After we've (potentially) uncached entries, ensure our coins cache is | // After we've (potentially) uncached entries, ensure our coins cache is | ||||
// still within its size limits | // still within its size limits | ||||
CValidationState stateDummy; | CValidationState stateDummy; | ||||
FlushStateToDisk(config.GetChainParams(), stateDummy, | FlushStateToDisk(config.GetChainParams(), stateDummy, | ||||
FlushStateMode::PERIODIC); | FlushStateMode::PERIODIC); | ||||
return res; | return res; | ||||
} | } | ||||
bool AcceptToMemoryPool(const Config &config, CTxMemPool &pool, | bool AcceptToMemoryPool(const Config &config, CTxMemPool &pool, | ||||
CValidationState &state, const CTransactionRef &tx, | CValidationState &state, const CTransactionRef &tx, | ||||
bool fLimitFree, bool *pfMissingInputs, | bool fLimitFree, bool *pfMissingInputs, | ||||
bool fOverrideMempoolLimit, const Amount nAbsurdFee) { | bool fOverrideMempoolLimit, const Amount nAbsurdFee, | ||||
return AcceptToMemoryPoolWithTime(config, pool, state, tx, fLimitFree, | bool test_accept) { | ||||
pfMissingInputs, GetTime(), | return AcceptToMemoryPoolWithTime( | ||||
fOverrideMempoolLimit, nAbsurdFee); | config, pool, state, tx, fLimitFree, pfMissingInputs, GetTime(), | ||||
fOverrideMempoolLimit, nAbsurdFee, test_accept); | |||||
} | } | ||||
/** | /** | ||||
* Return transaction in txOut, and if it was found inside a block, its hash is | * Return transaction in txOut, and if it was found inside a block, its hash is | ||||
* placed in hashBlock. If blockIndex is provided, the transaction is fetched | * placed in hashBlock. If blockIndex is provided, the transaction is fetched | ||||
* from the corresponding block. | * from the corresponding block. | ||||
*/ | */ | ||||
bool GetTransaction(const Config &config, const TxId &txid, | bool GetTransaction(const Config &config, const TxId &txid, | ||||
▲ Show 20 Lines • Show All 4,743 Lines • ▼ Show 20 Lines | try { | ||||
Amount amountdelta = nFeeDelta * SATOSHI; | Amount amountdelta = nFeeDelta * SATOSHI; | ||||
if (amountdelta != Amount::zero()) { | if (amountdelta != Amount::zero()) { | ||||
g_mempool.PrioritiseTransaction(tx->GetId(), prioritydummy, | g_mempool.PrioritiseTransaction(tx->GetId(), prioritydummy, | ||||
amountdelta); | amountdelta); | ||||
} | } | ||||
CValidationState state; | CValidationState state; | ||||
if (nTime + nExpiryTimeout > nNow) { | if (nTime + nExpiryTimeout > nNow) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
AcceptToMemoryPoolWithTime(config, g_mempool, state, tx, | AcceptToMemoryPoolWithTime( | ||||
true /* fLimitFree */, | config, g_mempool, state, tx, true /* fLimitFree */, | ||||
nullptr /* pfMissingInputs */, nTime, | nullptr /* pfMissingInputs */, nTime, | ||||
false /* fOverrideMempoolLimit */, | false /* fOverrideMempoolLimit */, | ||||
Amount::zero() /* nAbsurdFee */); | Amount::zero() /* nAbsurdFee */, false /* test_accept */); | ||||
if (state.IsValid()) { | if (state.IsValid()) { | ||||
++count; | ++count; | ||||
} else { | } else { | ||||
++failed; | ++failed; | ||||
} | } | ||||
} else { | } else { | ||||
++skipped; | ++skipped; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 110 Lines • Show Last 20 Lines |