aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp92
1 files changed, 53 insertions, 39 deletions
diff --git a/src/main.cpp b/src/main.cpp
index a6b717d57f..4f4926eb40 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,6 +56,7 @@ bool fHavePruned = false;
bool fPruneMode = false;
bool fIsBareMultisigStd = true;
bool fCheckBlockIndex = false;
+bool fCheckpointsEnabled = true;
unsigned int nCoinCacheSize = 5000;
uint64_t nPruneTarget = 0;
@@ -142,8 +143,9 @@ namespace {
uint32_t nBlockSequenceId = 1;
/**
- * Sources of received blocks, to be able to send them reject messages or ban
- * them, if processing happens afterwards. Protected by cs_main.
+ * Sources of received blocks, saved to be able to send them reject
+ * messages or ban them when processing happens afterwards. Protected by
+ * cs_main.
*/
map<uint256, NodeId> mapBlockSource;
@@ -389,7 +391,7 @@ void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBl
}
// If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
- // of their current tip anymore. Go back enough to fix that.
+ // of its current tip anymore. Go back enough to fix that.
state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
return;
@@ -941,7 +943,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// do all inputs exist?
// Note that this does not check for the presence of actual outputs (see the next check for that),
- // only helps filling in pfMissingInputs (to determine missing vs spent).
+ // and only helps with filling in pfMissingInputs (to determine missing vs spent).
BOOST_FOREACH(const CTxIn txin, tx.vin) {
if (!view.HaveCoins(txin.prevout.hash)) {
if (pfMissingInputs)
@@ -1204,8 +1206,11 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees)
bool IsInitialBlockDownload()
{
+ const CChainParams& chainParams = Params();
LOCK(cs_main);
- if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate())
+ if (fImporting || fReindex)
+ return true;
+ if (fCheckpointsEnabled && chainActive.Height() < Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()))
return true;
static bool lockIBDState = false;
if (lockIBDState)
@@ -1277,8 +1282,8 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip)
pfork = pfork->pprev;
}
- // We define a condition which we should warn the user about as a fork of at least 7 blocks
- // who's tip is within 72 blocks (+/- 12 hours if no one mines it) of ours
+ // 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)
@@ -1709,7 +1714,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
return true;
}
- bool fScriptChecks = pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate();
+ bool fScriptChecks = (!fCheckpointsEnabled || pindex->nHeight >= Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()));
// Do not allow blocks that contain transactions which 'overwrite' older transactions,
// unless those are already completely spent.
@@ -1719,9 +1724,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
// See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
// This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
// already refuses previously-known transaction ids entirely.
- // This rule was originally applied all blocks whose timestamp was after March 15, 2012, 0:00 UTC.
+ // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC.
// Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
- // two in the chain that violate it. This prevents exploiting the issue against nodes in their
+ // two in the chain that violate it. This prevents exploiting the issue against nodes during their
// initial block download.
bool fEnforceBIP30 = (!pindex->phashBlock) || // Enforce on CreateNewBlock invocations which don't have a hash.
!((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256S("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
@@ -1954,6 +1959,7 @@ void PruneAndFlush() {
/** Update chainActive and related internal data structures. */
void static UpdateTip(CBlockIndex *pindexNew) {
+ const CChainParams& chainParams = Params();
chainActive.SetTip(pindexNew);
// New best block
@@ -1963,7 +1969,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
LogPrintf("%s: new best=%s height=%d log2_work=%.8g tx=%lu date=%s progress=%f cache=%u\n", __func__,
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
- Checkpoints::GuessVerificationProgress(chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
+ Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip()), (unsigned int)pcoinsTip->GetCacheSize());
cvBlockChange.notify_all();
@@ -1984,7 +1990,7 @@ void static UpdateTip(CBlockIndex *pindexNew) {
if (nUpgraded > 100/2)
{
// strMiscWarning is read by GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
- strMiscWarning = _("Warning: This version is obsolete, upgrade required!");
+ strMiscWarning = _("Warning: This version is obsolete; upgrade required!");
CAlert::Notify(strMiscWarning, true);
fWarned = true;
}
@@ -2247,6 +2253,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
CBlockIndex *pindexNewTip = NULL;
CBlockIndex *pindexMostWork = NULL;
+ const CChainParams& chainParams = Params();
do {
boost::this_thread::interruption_point();
@@ -2271,7 +2278,9 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
if (!fInitialDownload) {
uint256 hashNewTip = pindexNewTip->GetBlockHash();
// Relay inventory, but don't relay old inventory during initial block download.
- int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
+ int nBlockEstimate = 0;
+ if (fCheckpointsEnabled)
+ nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints());
// Don't relay blocks if pruning -- could cause a peer to try to download, resulting
// in a stalled download if the block file is pruned before the request.
if (nLocalServices & NODE_NETWORK) {
@@ -2315,7 +2324,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) {
}
// The resulting new best tip may not be in setBlockIndexCandidates anymore, so
- // add them again.
+ // add it again.
BlockMap::iterator it = mapBlockIndex.begin();
while (it != mapBlockIndex.end()) {
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->nChainTx && !setBlockIndexCandidates.value_comp()(it->second, chainActive.Tip())) {
@@ -2601,7 +2610,8 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev)
{
- const Consensus::Params& consensusParams = Params().GetConsensus();
+ const CChainParams& chainParams = Params();
+ const Consensus::Params& consensusParams = chainParams.GetConsensus();
uint256 hash = block.GetHash();
if (hash == consensusParams.hashGenesisBlock)
return true;
@@ -2611,7 +2621,7 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
int nHeight = pindexPrev->nHeight+1;
// Check proof of work
- if (block.nBits != GetNextWorkRequired(pindexPrev, &block, Params().GetConsensus()))
+ if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.DoS(100, error("%s: incorrect proof of work", __func__),
REJECT_INVALID, "bad-diffbits");
@@ -2620,25 +2630,28 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return state.Invalid(error("%s: block's timestamp is too early", __func__),
REJECT_INVALID, "time-too-old");
- // Check that the block chain matches the known block chain up to a checkpoint
- if (!Checkpoints::CheckBlock(nHeight, hash))
- return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
- REJECT_CHECKPOINT, "checkpoint mismatch");
+ if(fCheckpointsEnabled)
+ {
+ // Check that the block chain matches the known block chain up to a checkpoint
+ if (!Checkpoints::CheckBlock(chainParams.Checkpoints(), nHeight, hash))
+ return state.DoS(100, error("%s: rejected by checkpoint lock-in at %d", __func__, nHeight),
+ REJECT_CHECKPOINT, "checkpoint mismatch");
- // Don't accept any forks from the main chain prior to last checkpoint
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && nHeight < pcheckpoint->nHeight)
- return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
+ // Don't accept any forks from the main chain prior to last checkpoint
+ CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(chainParams.Checkpoints());
+ if (pcheckpoint && nHeight < pcheckpoint->nHeight)
+ return state.DoS(100, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight));
+ }
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority()))
+ if (block.nVersion < 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
{
return state.Invalid(error("%s: rejected nVersion=1 block", __func__),
REJECT_OBSOLETE, "bad-version");
}
// Reject block.nVersion=2 blocks when 95% (75% on testnet) of the network has upgraded:
- if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, Params().RejectBlockOutdatedMajority()))
+ if (block.nVersion < 3 && IsSuperMajority(3, pindexPrev, consensusParams.nMajorityRejectBlockOutdated))
{
return state.Invalid(error("%s : rejected nVersion=2 block", __func__),
REJECT_OBSOLETE, "bad-version");
@@ -3025,6 +3038,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash)
bool static LoadBlockIndexDB()
{
+ const CChainParams& chainparams = Params();
if (!pblocktree->LoadBlockIndexGuts())
return false;
@@ -3127,7 +3141,7 @@ bool static LoadBlockIndexDB()
LogPrintf("%s: hashBestChain=%s height=%d date=%s progress=%f\n", __func__,
chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(),
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
- Checkpoints::GuessVerificationProgress(chainActive.Tip()));
+ Checkpoints::GuessVerificationProgress(chainparams.Checkpoints(), chainActive.Tip()));
return true;
}
@@ -3733,7 +3747,7 @@ void static ProcessGetData(CNode* pfrom)
pfrom->PushMessage("merkleblock", merkleBlock);
// CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
// This avoids hurting performance by pointlessly requiring a round-trip
- // Note that there is currently no way for a node to request any single transactions we didnt send here -
+ // Note that there is currently no way for a node to request any single transactions we didn't send here -
// they must either disconnect and retry or request the full block.
// Thus, the protocol spec specified allows for us to provide duplicate txn here,
// however we MUST always provide at least what the remote peer needs
@@ -3746,7 +3760,7 @@ void static ProcessGetData(CNode* pfrom)
// no response
}
- // Trigger them to send a getblocks request for the next batch of inventory
+ // Trigger the peer node to send a getblocks request for the next batch of inventory
if (inv.hash == pfrom->hashContinue)
{
// Bypass PushInventory, this must send even if redundant,
@@ -4060,7 +4074,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (inv.type == MSG_BLOCK) {
UpdateBlockAvailability(pfrom->GetId(), inv.hash);
if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
- // First request the headers preceeding the announced block. In the normal fully-synced
+ // First request the headers preceding the announced block. In the normal fully-synced
// case where a new block is announced that succeeds the current tip (no reorganization),
// there are no such headers.
// Secondly, and only when we are close to being synced, we request the announced block directly,
@@ -4142,8 +4156,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
if (--nLimit <= 0)
{
- // When this block is requested, we'll send an inv that'll make them
- // getblocks the next batch of inventory.
+ // When this block is requested, we'll send an inv that'll
+ // trigger the peer to getblocks the next batch of inventory.
LogPrint("net", " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
pfrom->hashContinue = pindex->GetBlockHash();
break;
@@ -4380,9 +4394,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// This asymmetric behavior for inbound and outbound connections was introduced
// to prevent a fingerprinting attack: an attacker can send specific fake addresses
- // to users' AddrMan and later request them by sending getaddr messages.
- // Making users (which are behind NAT and can only make outgoing connections) ignore
- // getaddr message mitigates the attack.
+ // to users' AddrMan and later request them by sending getaddr messages.
+ // Making nodes which are behind NAT and can only make outgoing connections ignore
+ // the getaddr message mitigates the attack.
else if ((strCommand == "getaddr") && (pfrom->fInbound))
{
pfrom->vAddrToSend.clear();
@@ -4467,7 +4481,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
// Nonce mismatches are normal when pings are overlapping
sProblem = "Nonce mismatch";
if (nonce == 0) {
- // This is most likely a bug in another implementation somewhere, cancel this ping
+ // This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Nonce zero";
}
@@ -4476,7 +4490,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
sProblem = "Unsolicited pong without ping";
}
} else {
- // This is most likely a bug in another implementation somewhere, cancel this ping
+ // This is most likely a bug in another implementation somewhere; cancel this ping
bPingFinished = true;
sProblem = "Short payload";
}
@@ -4735,7 +4749,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
{
const Consensus::Params& consensusParams = Params().GetConsensus();
{
- // Don't send anything until we get their version message
+ // Don't send anything until we get its version message
if (pto->nVersion == 0)
return true;
@@ -4919,7 +4933,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
// In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
// (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
// timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
- // being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
+ // being saturated. We only count validated in-flight blocks so peers can't advertise non-existing block hashes
// to unreasonably increase our timeout.
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * consensusParams.nPowTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);