aboutsummaryrefslogtreecommitdiff
path: root/src/validation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/validation.cpp')
-rw-r--r--src/validation.cpp126
1 files changed, 24 insertions, 102 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 8241cb159f..2585345dee 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -22,7 +22,6 @@
#include <logging/timer.h>
#include <node/ui_interface.h>
#include <optional.h>
-#include <policy/fees.h>
#include <policy/policy.h>
#include <policy/settings.h>
#include <pow.h>
@@ -148,8 +147,6 @@ arith_uint256 nMinimumChainWork;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
-CBlockPolicyEstimator feeEstimator;
-
// Internal stuff
namespace {
CBlockIndex* pindexBestInvalid = nullptr;
@@ -449,7 +446,7 @@ namespace {
class MemPoolAccept
{
public:
- MemPoolAccept(CTxMemPool& mempool) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&::ChainstateActive().CoinsTip(), m_pool),
+ explicit MemPoolAccept(CTxMemPool& mempool) : m_pool(mempool), m_view(&m_dummy), m_viewmempool(&::ChainstateActive().CoinsTip(), m_pool),
m_limit_ancestors(gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT)),
m_limit_ancestor_size(gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000),
m_limit_descendants(gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT)),
@@ -482,7 +479,7 @@ private:
// All the intermediate state that gets passed between the various levels
// of checking a given transaction.
struct Workspace {
- Workspace(const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
+ explicit Workspace(const CTransactionRef& ptx) : m_ptx(ptx), m_hash(ptx->GetHash()) {}
std::set<uint256> m_conflicts;
CTxMemPool::setEntries m_all_conflicting;
CTxMemPool::setEntries m_ancestors;
@@ -505,13 +502,13 @@ private:
// Run the script checks using our policy flags. As this can be slow, we should
// only invoke this on transactions that have otherwise passed policy checks.
- bool PolicyScriptChecks(ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Re-run the script checks, using consensus flags, and try to cache the
// result in the scriptcache. This should be done after
// PolicyScriptChecks(). This requires that all inputs either be in our
// utxo set or in the mempool.
- bool ConsensusScriptChecks(ATMPArgs& args, Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
+ bool ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData &txdata) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Try to add the transaction to the mempool, removing any conflicts first.
// Returns true if the transaction is in the mempool after any size
@@ -696,7 +693,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs");
}
- // Check for non-standard witness in P2WSH
+ // Check for non-standard witnesses.
if (tx.HasWitness() && fRequireStandard && !IsWitnessStandard(tx, m_view))
return state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, "bad-witness-nonstandard");
@@ -921,7 +918,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
return true;
}
-bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
+bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
{
const CTransaction& tx = *ws.m_ptx;
@@ -948,7 +945,7 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, Workspace& ws, Precompute
return true;
}
-bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, Workspace& ws, PrecomputedTransactionData& txdata)
+bool MemPoolAccept::ConsensusScriptChecks(ATMPArgs& args, const Workspace& ws, PrecomputedTransactionData& txdata)
{
const CTransaction& tx = *ws.m_ptx;
const uint256& hash = ws.m_hash;
@@ -1312,8 +1309,6 @@ bool CChainState::IsInitialBlockDownload() const
return false;
}
-static CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
-
static void AlertNotify(const std::string& strMessage)
{
uiInterface.NotifyAlertChanged();
@@ -1339,73 +1334,16 @@ static void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
AssertLockHeld(cs_main);
// Before we get past initial download, we cannot reliably alert about forks
// (we assume we don't get stuck on a fork before finishing our initial sync)
- if (::ChainstateActive().IsInitialBlockDownload())
+ if (::ChainstateActive().IsInitialBlockDownload()) {
return;
-
- // If our best fork is no longer within 72 blocks (+/- 12 hours if no one mines it)
- // of our head, drop it
- if (pindexBestForkTip && ::ChainActive().Height() - pindexBestForkTip->nHeight >= 72)
- pindexBestForkTip = nullptr;
-
- if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > ::ChainActive().Tip()->nChainWork + (GetBlockProof(*::ChainActive().Tip()) * 6)))
- {
- if (!GetfLargeWorkForkFound() && pindexBestForkBase)
- {
- std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") +
- pindexBestForkBase->phashBlock->ToString() + std::string("'");
- AlertNotify(warning);
- }
- if (pindexBestForkTip && pindexBestForkBase)
- {
- LogPrintf("%s: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", __func__,
- pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(),
- pindexBestForkTip->nHeight, pindexBestForkTip->phashBlock->ToString());
- SetfLargeWorkForkFound(true);
- }
- else
- {
- LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
- SetfLargeWorkInvalidChainFound(true);
- }
- }
- else
- {
- SetfLargeWorkForkFound(false);
- SetfLargeWorkInvalidChainFound(false);
}
-}
-static void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
-{
- AssertLockHeld(cs_main);
- // If we are on a fork that is sufficiently large, set a warning flag
- CBlockIndex* pfork = pindexNewForkTip;
- CBlockIndex* plonger = ::ChainActive().Tip();
- while (pfork && pfork != plonger)
- {
- while (plonger && plonger->nHeight > pfork->nHeight)
- plonger = plonger->pprev;
- if (pfork == plonger)
- break;
- pfork = pfork->pprev;
- }
-
- // We define a condition where we should warn the user about as a fork of at least 7 blocks
- // with a tip within 72 blocks (+/- 12 hours if no one mines it) of ours
- // We use 7 blocks rather arbitrarily as it represents just under 10% of sustained network
- // hash rate operating on the fork.
- // or a chain that is entirely longer than ours and invalid (note that this should be detected by both)
- // We define it this way because it allows us to only store the highest fork tip (+ base) which meets
- // the 7-block condition and from this always have the most-likely-to-cause-warning fork
- if (pfork && (!pindexBestForkTip || pindexNewForkTip->nHeight > pindexBestForkTip->nHeight) &&
- pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) &&
- ::ChainActive().Height() - pindexNewForkTip->nHeight < 72)
- {
- pindexBestForkTip = pindexNewForkTip;
- pindexBestForkBase = pfork;
+ if (pindexBestInvalid && pindexBestInvalid->nChainWork > ::ChainActive().Tip()->nChainWork + (GetBlockProof(*::ChainActive().Tip()) * 6)) {
+ LogPrintf("%s: Warning: Found invalid chain at least ~6 blocks longer than our best chain.\nChain state database corruption likely.\n", __func__);
+ SetfLargeWorkInvalidChainFound(true);
+ } else {
+ SetfLargeWorkInvalidChainFound(false);
}
-
- CheckForkWarningConditions();
}
// Called both upon regular invalid block discovery *and* InvalidateBlock
@@ -2457,9 +2395,7 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
}
bilingual_str warning_messages;
- int num_unexpected_version = 0;
- if (!::ChainstateActive().IsInitialBlockDownload())
- {
+ if (!::ChainstateActive().IsInitialBlockDownload()) {
const CBlockIndex* pindex = pindexNew;
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) {
WarningBitsConditionChecker checker(bit);
@@ -2473,14 +2409,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
}
}
}
- // Check the version of the last 100 blocks to see if we need to upgrade:
- for (int i = 0; i < 100 && pindex != nullptr; i++)
- {
- int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus());
- if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0)
- ++num_unexpected_version;
- pindex = pindex->pprev;
- }
}
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
@@ -2488,10 +2416,6 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
FormatISO8601DateTime(pindexNew->GetBlockTime()),
GuessVerificationProgress(chainParams.TxData(), pindexNew), ::ChainstateActive().CoinsTip().DynamicMemoryUsage() * (1.0 / (1<<20)), ::ChainstateActive().CoinsTip().GetCacheSize(),
!warning_messages.empty() ? strprintf(" warning='%s'", warning_messages.original) : "");
-
- if (num_unexpected_version > 0) {
- LogPrint(BCLog::VALIDATION, "%d of last 100 blocks have unexpected version\n", num_unexpected_version);
- }
}
/** Disconnect m_chain's tip.
@@ -2746,8 +2670,8 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
- const CBlockIndex *pindexOldTip = m_chain.Tip();
- const CBlockIndex *pindexFork = m_chain.FindFork(pindexMostWork);
+ const CBlockIndex* pindexOldTip = m_chain.Tip();
+ const CBlockIndex* pindexFork = m_chain.FindFork(pindexMostWork);
// Disconnect active blocks which are no longer in the best chain.
bool fBlocksDisconnected = false;
@@ -2767,7 +2691,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
fBlocksDisconnected = true;
}
- // Build list of new blocks to connect.
+ // Build list of new blocks to connect (in descending height order).
std::vector<CBlockIndex*> vpindexToConnect;
bool fContinue = true;
int nHeight = pindexFork ? pindexFork->nHeight : -1;
@@ -2777,7 +2701,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
int nTargetHeight = std::min(nHeight + 32, pindexMostWork->nHeight);
vpindexToConnect.clear();
vpindexToConnect.reserve(nTargetHeight - nHeight);
- CBlockIndex *pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
+ CBlockIndex* pindexIter = pindexMostWork->GetAncestor(nTargetHeight);
while (pindexIter && pindexIter->nHeight != nHeight) {
vpindexToConnect.push_back(pindexIter);
pindexIter = pindexIter->pprev;
@@ -2785,7 +2709,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
nHeight = nTargetHeight;
// Connect new blocks.
- for (CBlockIndex *pindexConnect : reverse_iterate(vpindexToConnect)) {
+ for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) {
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
if (state.IsInvalid()) {
// The block violates a consensus rule.
@@ -2821,11 +2745,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
}
m_mempool.check(&CoinsTip());
- // Callbacks/notifications for a new best chain.
- if (fInvalidFound)
- CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
- else
- CheckForkWarningConditions();
+ CheckForkWarningConditions();
return true;
}
@@ -5084,7 +5004,7 @@ bool LoadMempool(CTxMemPool& pool)
pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
}
TxValidationState state;
- if (nTime + nExpiryTimeout > nNow) {
+ if (nTime > nNow - nExpiryTimeout) {
LOCK(cs_main);
AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, nTime,
nullptr /* plTxnReplaced */, false /* bypass_limits */,
@@ -5187,7 +5107,9 @@ bool DumpMempool(const CTxMemPool& pool)
if (!FileCommit(file.Get()))
throw std::runtime_error("FileCommit failed");
file.fclose();
- RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat");
+ if (!RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat")) {
+ throw std::runtime_error("Rename failed");
+ }
int64_t last = GetTimeMicros();
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*MICRO, (last-mid)*MICRO);
} catch (const std::exception& e) {