diff --git a/src/main.cpp b/src/main.cpp index 9016fe42a0..bc49d09fe7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -92,7 +92,7 @@ void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); * in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards. */ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams); -static void CheckBlockIndex(); +static void CheckBlockIndex(const Consensus::Params& consensusParams); /** Constant stuff for coinbase transactions we create: */ CScript COINBASE_FLAGS; @@ -998,7 +998,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa } /** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ -bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow) +bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; @@ -1044,7 +1044,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock if (pindexSlow) { CBlock block; - if (ReadBlockFromDisk(block, pindexSlow)) { + if (ReadBlockFromDisk(block, pindexSlow, consensusParams)) { BOOST_FOREACH(const CTransaction &tx, block.vtx) { if (tx.GetHash() == hash) { txOut = tx; @@ -1089,7 +1089,7 @@ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHea return true; } -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams) { block.SetNull(); @@ -1107,15 +1107,15 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) + if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return true; } -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex) +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) { - if (!ReadBlockFromDisk(block, pindex->GetBlockPos())) + if (!ReadBlockFromDisk(block, pindex->GetBlockPos(), consensusParams)) return false; if (block.GetHash() != pindex->GetBlockHash()) return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", @@ -2064,13 +2064,14 @@ void static UpdateTip(CBlockIndex *pindexNew) { } /** Disconnect chainActive's tip. You want to manually re-limit mempool size after this */ -bool static DisconnectTip(CValidationState &state) { +bool static DisconnectTip(CValidationState& state, const Consensus::Params& consensusParams) +{ CBlockIndex *pindexDelete = chainActive.Tip(); assert(pindexDelete); mempool.check(pcoinsTip); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete)) + if (!ReadBlockFromDisk(block, pindexDelete, consensusParams)) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); @@ -2125,13 +2126,14 @@ static int64_t nTimePostConnect = 0; * corresponding to pindexNew, to bypass loading it again from disk. */ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, const CBlock *pblock) { + const CChainParams& chainparams = Params(); assert(pindexNew->pprev == chainActive.Tip()); mempool.check(pcoinsTip); // Read block from disk. int64_t nTime1 = GetTimeMicros(); CBlock block; if (!pblock) { - if (!ReadBlockFromDisk(block, pindexNew)) + if (!ReadBlockFromDisk(block, pindexNew, chainparams.GetConsensus())) return AbortNode(state, "Failed to read block"); pblock = █ } @@ -2257,6 +2259,7 @@ static void PruneBlockIndexCandidates() { * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. */ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMostWork, const CBlock *pblock) { + const CChainParams& chainparams = Params(); AssertLockHeld(cs_main); bool fInvalidFound = false; const CBlockIndex *pindexOldTip = chainActive.Tip(); @@ -2265,7 +2268,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo // Disconnect active blocks which are no longer in the best chain. bool fBlocksDisconnected = false; while (chainActive.Tip() && chainActive.Tip() != pindexFork) { - if (!DisconnectTip(state)) + if (!DisconnectTip(state, chainparams.GetConsensus())) return false; fBlocksDisconnected = true; } @@ -2333,7 +2336,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexMostWork = NULL; - const CChainParams& chainParams = Params(); + const CChainParams& chainparams = Params(); do { boost::this_thread::interruption_point(); @@ -2360,7 +2363,7 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { // Relay inventory, but don't relay old inventory during initial block download. int nBlockEstimate = 0; if (fCheckpointsEnabled) - nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainParams.Checkpoints()); + nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); { LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) @@ -2372,7 +2375,7 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { uiInterface.NotifyBlockTip(hashNewTip); } } while(pindexMostWork != chainActive.Tip()); - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); // Write changes periodically to disk, after relay. if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { @@ -2382,7 +2385,8 @@ bool ActivateBestChain(CValidationState &state, const CBlock *pblock) { return true; } -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { +bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex) +{ AssertLockHeld(cs_main); // Mark the block itself as invalid. @@ -2397,7 +2401,7 @@ bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex) { setBlockIndexCandidates.erase(pindexWalk); // ActivateBestChain considers blocks already in chainActive // unconditionally valid already, so force disconnect away from it. - if (!DisconnectTip(state)) { + if (!DisconnectTip(state, consensusParams)) { return false; } } @@ -2904,6 +2908,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos *dbp) { + const CChainParams& chainparams = Params(); // Preliminary checks bool checked = CheckBlock(*pblock, state); @@ -2921,7 +2926,7 @@ bool ProcessNewBlock(CValidationState &state, const CNode* pfrom, const CBlock* if (pindex && pfrom) { mapBlockSource[pindex->GetBlockHash()] = pfrom->GetId(); } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); if (!ret) return error("%s: AcceptBlock FAILED", __func__); } @@ -3253,6 +3258,7 @@ CVerifyDB::~CVerifyDB() bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth) { + const CChainParams& chainparams = Params(); LOCK(cs_main); if (chainActive.Tip() == NULL || chainActive.Tip()->pprev == NULL) return true; @@ -3277,7 +3283,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth break; CBlock block; // check level 0: read from disk - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) @@ -3317,7 +3323,7 @@ bool CVerifyDB::VerifyDB(CCoinsView *coinsview, int nCheckLevel, int nCheckDepth uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; - if (!ReadBlockFromDisk(block, pindex)) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); if (!ConnectBlock(block, state, pindex, coins)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -3490,7 +3496,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) std::pair::iterator, std::multimap::iterator> range = mapBlocksUnknownParent.equal_range(head); while (range.first != range.second) { std::multimap::iterator it = range.first; - if (ReadBlockFromDisk(block, it->second)) + if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus())) { LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(), head.ToString()); @@ -3517,9 +3523,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp) return nLoaded > 0; } -void static CheckBlockIndex() +void static CheckBlockIndex(const Consensus::Params& consensusParams) { - const Consensus::Params& consensusParams = Params().GetConsensus(); if (!fCheckBlockIndex) { return; } @@ -3801,7 +3806,7 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) return true; } -void static ProcessGetData(CNode* pfrom) +void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams) { std::deque::iterator it = pfrom->vRecvGetData.begin(); @@ -3856,7 +3861,7 @@ void static ProcessGetData(CNode* pfrom) { // Send block from disk CBlock block; - if (!ReadBlockFromDisk(block, (*mi).second)) + if (!ReadBlockFromDisk(block, (*mi).second, consensusParams)) assert(!"cannot load block from disk"); if (inv.type == MSG_BLOCK) pfrom->PushMessage("block", block); @@ -4248,7 +4253,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); } @@ -4514,7 +4519,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage("getheaders", chainActive.GetLocator(pindexLast), uint256()); } - CheckBlockIndex(); + CheckBlockIndex(chainparams.GetConsensus()); } else if (strCommand == "block" && !fImporting && !fReindex) // Ignore blocks received while importing @@ -4798,6 +4803,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // requires LOCK(cs_vRecvMsg) bool ProcessMessages(CNode* pfrom) { + const CChainParams& chainparams = Params(); //if (fDebug) // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size()); @@ -4812,7 +4818,7 @@ bool ProcessMessages(CNode* pfrom) bool fOk = true; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom); + ProcessGetData(pfrom, chainparams.GetConsensus()); // this maintains the order of responses if (!pfrom->vRecvGetData.empty()) return fOk; @@ -4839,7 +4845,7 @@ bool ProcessMessages(CNode* pfrom) it++; // Scan for message start - if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) { + if (memcmp(msg.hdr.pchMessageStart, chainparams.MessageStart(), MESSAGE_START_SIZE) != 0) { LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id); fOk = false; break; @@ -4847,7 +4853,7 @@ bool ProcessMessages(CNode* pfrom) // Read header CMessageHeader& hdr = msg.hdr; - if (!hdr.IsValid(Params().MessageStart())) + if (!hdr.IsValid(chainparams.MessageStart())) { LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id); continue; diff --git a/src/main.h b/src/main.h index 273a450867..c7dad10ca3 100644 --- a/src/main.h +++ b/src/main.h @@ -192,7 +192,7 @@ bool IsInitialBlockDownload(); /** Format a string that describes several potential problems detected by the core */ std::string GetWarnings(const std::string& strFor); /** Retrieve a transaction (from memory pool, or from disk, if possible) */ -bool GetTransaction(const uint256 &hash, CTransaction &tx, uint256 &hashBlock, bool fAllowSlow = false); +bool GetTransaction(const uint256 &hash, CTransaction &tx, const Consensus::Params& params, uint256 &hashBlock, bool fAllowSlow = false); /** Find the best known block, and make it the tip of the block chain */ bool ActivateBestChain(CValidationState &state, const CBlock *pblock = NULL); CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); @@ -353,9 +353,8 @@ public: /** Functions for disk access for blocks */ bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); -bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos); -bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); - +bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos, const Consensus::Params& consensusParams); +bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); /** Functions for validating blocks and updating the block tree */ @@ -381,8 +380,7 @@ bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex /** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */ bool AcceptBlock(const CBlock& block, CValidationState& state, CBlockIndex **pindex, bool fRequested, CDiskBlockPos* dbp); -bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex **ppindex= NULL); - +bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex **ppindex= NULL); class CBlockFileInfo @@ -451,7 +449,7 @@ public: CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator); /** Mark a block as invalid. */ -bool InvalidateBlock(CValidationState& state, CBlockIndex *pindex); +bool InvalidateBlock(CValidationState& state, const Consensus::Params& consensusParams, CBlockIndex *pindex); /** Remove invalidity status from a block and its descendants. */ bool ReconsiderBlock(CValidationState& state, CBlockIndex *pindex); diff --git a/src/rest.cpp b/src/rest.cpp index c46d7a8bd2..5d69542a91 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "chain.h" +#include "chainparams.h" #include "primitives/block.h" #include "primitives/transaction.h" #include "main.h" @@ -223,7 +224,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex)) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -360,7 +361,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransaction tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 146eb3905a..9c0e78f772 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -405,7 +405,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)"); - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); if (!fVerbose) @@ -824,7 +824,7 @@ UniValue invalidateblock(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlockIndex* pblockindex = mapBlockIndex[hash]; - InvalidateBlock(state, pblockindex); + InvalidateBlock(state, Params().GetConsensus(), pblockindex); } if (state.IsValid()) { diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 5f3363d097..11d9a6f2bb 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -186,7 +186,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) CTransaction tx; uint256 hashBlock; - if (!GetTransaction(hash, tx, hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); string strHex = EncodeHexTx(tx); @@ -256,7 +256,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) if (pblockindex == NULL) { CTransaction tx; - if (!GetTransaction(oneTxid, tx, hashBlock, false) || hashBlock.IsNull()) + if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); if (!mapBlockIndex.count(hashBlock)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); @@ -264,7 +264,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) } CBlock block; - if(!ReadBlockFromDisk(block, pblockindex)) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); unsigned int ntxFound = 0; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index cce3e40f38..d51b8ddaef 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1078,7 +1078,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100)))); CBlock block; - ReadBlockFromDisk(block, pindex); + ReadBlockFromDisk(block, pindex, Params().GetConsensus()); BOOST_FOREACH(CTransaction& tx, block.vtx) { if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 4c3eb8f2d9..ac788843eb 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "chainparams.h" #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" @@ -142,11 +143,12 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { LogPrint("zmq", "Publish raw block %s\n", pindex->GetBlockHash().GetHex()); + const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); CBlock block; - if(!ReadBlockFromDisk(block, pindex)) + if(!ReadBlockFromDisk(block, pindex, consensusParams)) { zmqError("Can't read block from disk"); return false;