diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 118 |
1 files changed, 34 insertions, 84 deletions
diff --git a/src/main.cpp b/src/main.cpp index 6c1c7166a..5a5c70057 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -391,72 +391,19 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals) nodeSignals.FinalizeNode.disconnect(&FinalizeNode); } -////////////////////////////////////////////////////////////////////////////// -// -// CChain implementation -// - -CBlockIndex *CChain::SetTip(CBlockIndex *pindex) { - if (pindex == NULL) { - vChain.clear(); - return NULL; - } - vChain.resize(pindex->nHeight + 1); - while (pindex && vChain[pindex->nHeight] != pindex) { - vChain[pindex->nHeight] = pindex; - pindex = pindex->pprev; - } - return pindex; -} - -CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { - int nStep = 1; - std::vector<uint256> vHave; - vHave.reserve(32); - - if (!pindex) - pindex = Tip(); - while (pindex) { - vHave.push_back(pindex->GetBlockHash()); - // Stop when we have added the genesis block. - if (pindex->nHeight == 0) - break; - // Exponentially larger steps back, plus the genesis block. - int nHeight = std::max(pindex->nHeight - nStep, 0); - if (Contains(pindex)) { - // Use O(1) CChain index if possible. - pindex = (*this)[nHeight]; - } else { - // Otherwise, use O(log n) skiplist. - pindex = pindex->GetAncestor(nHeight); - } - if (vHave.size() > 10) - nStep *= 2; - } - - return CBlockLocator(vHave); -} - -CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const { +CBlockIndex* FindForkInGlobalIndex(const CChain& chain, const CBlockLocator& locator) +{ // Find the first block the caller has in the main chain BOOST_FOREACH(const uint256& hash, locator.vHave) { BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; - if (Contains(pindex)) + if (chain.Contains(pindex)) return pindex; } } - return Genesis(); -} - -const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { - if (pindex->nHeight > Height()) - pindex = pindex->GetAncestor(Height()); - while (pindex && !Contains(pindex)) - pindex = pindex->pprev; - return pindex; + return chain.Genesis(); } CCoinsViewCache *pcoinsTip = NULL; @@ -781,7 +728,7 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) REJECT_INVALID, "bad-txns-oversize"); // Check for negative or overflow output values - int64_t nValueOut = 0; + CAmount nValueOut = 0; BOOST_FOREACH(const CTxOut& txout, tx.vout) { if (txout.nValue < 0) @@ -823,19 +770,19 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) return true; } -int64_t GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) +CAmount GetMinRelayFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree) { { LOCK(mempool.cs); uint256 hash = tx.GetHash(); double dPriorityDelta = 0; - int64_t nFeeDelta = 0; + CAmount nFeeDelta = 0; mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta); if (dPriorityDelta > 0 || nFeeDelta > 0) return 0; } - int64_t nMinFee = ::minRelayTxFee.GetFee(nBytes); + CAmount nMinFee = ::minRelayTxFee.GetFee(nBytes); if (fAllowFree) { @@ -898,7 +845,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa CCoinsView dummy; CCoinsViewCache view(dummy); - int64_t nValueIn = 0; + CAmount nValueIn = 0; { LOCK(pool.cs); CCoinsViewMemPool viewMemPool(*pcoinsTip, pool); @@ -950,15 +897,15 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa hash.ToString(), nSigOps, MAX_TX_SIGOPS), REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); - int64_t nValueOut = tx.GetValueOut(); - int64_t nFees = nValueIn-nValueOut; + CAmount nValueOut = tx.GetValueOut(); + CAmount nFees = nValueIn-nValueOut; double dPriority = view.GetPriority(tx, chainActive.Height()); CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height()); unsigned int nSize = entry.GetTxSize(); // Don't accept it if it can't get into a block - int64_t txMinFee = GetMinRelayFee(tx, nSize, true); + CAmount txMinFee = GetMinRelayFee(tx, nSize, true); if (fLimitFree && nFees < txMinFee) return state.DoS(0, error("AcceptToMemoryPool : not enough fees %s, %d < %d", hash.ToString(), nFees, txMinFee), @@ -1082,7 +1029,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) { // Open history file to append - CAutoFile fileout = CAutoFile(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); + CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); if (!fileout) return error("WriteBlockToDisk : OpenBlockFile failed"); @@ -1110,7 +1057,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) block.SetNull(); // Open history file to read - CAutoFile filein = CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); + CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); if (!filein) return error("ReadBlockFromDisk : OpenBlockFile failed"); @@ -1178,7 +1125,7 @@ void static PruneOrphanBlocks() mapOrphanBlocks.erase(hash); } -int64_t GetBlockValue(int nHeight, int64_t nFees) +CAmount GetBlockValue(int nHeight, const CAmount& nFees) { int64_t nSubsidy = 50 * COIN; int halvings = nHeight / Params().SubsidyHalvingInterval(); @@ -1351,12 +1298,13 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach bool ret; // mark inputs spent if (!tx.IsCoinBase()) { - BOOST_FOREACH(const CTxIn &txin, tx.vin) { + txundo.vprevout.reserve(tx.vin.size()); + for (unsigned int i = 0; i < tx.vin.size(); i++) { + const CTxIn &txin = tx.vin[i]; CCoins &coins = inputs.GetCoins(txin.prevout.hash); - CTxInUndo undo; - ret = coins.Spend(txin.prevout, undo); + txundo.vprevout.push_back(CTxInUndo()); + ret = coins.Spend(txin.prevout, txundo.vprevout.back()); assert(ret); - txundo.vprevout.push_back(undo); } } @@ -1388,8 +1336,8 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi // This is also true for mempool checks. CBlockIndex *pindexPrev = mapBlockIndex.find(inputs.GetBestBlock())->second; int nSpendHeight = pindexPrev->nHeight + 1; - int64_t nValueIn = 0; - int64_t nFees = 0; + CAmount nValueIn = 0; + CAmount nFees = 0; for (unsigned int i = 0; i < tx.vin.size(); i++) { const COutPoint &prevout = tx.vin[i].prevout; @@ -1417,7 +1365,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi REJECT_INVALID, "bad-txns-in-belowout"); // Tally transaction fees - int64_t nTxFee = nValueIn - tx.GetValueOut(); + CAmount nTxFee = nValueIn - tx.GetValueOut(); if (nTxFee < 0) return state.DoS(100, error("CheckInputs() : %s nTxFee < 0", tx.GetHash().ToString()), REJECT_INVALID, "bad-txns-fee-negative"); @@ -1657,12 +1605,13 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C CCheckQueueControl<CScriptCheck> control(fScriptChecks && nScriptCheckThreads ? &scriptcheckqueue : NULL); int64_t nTimeStart = GetTimeMicros(); - int64_t nFees = 0; + CAmount nFees = 0; int nInputs = 0; unsigned int nSigOps = 0; CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())); std::vector<std::pair<uint256, CDiskTxPos> > vPos; vPos.reserve(block.vtx.size()); + blockundo.vtxundo.reserve(block.vtx.size() - 1); for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction &tx = block.vtx[i]; @@ -1698,10 +1647,11 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C control.Add(vChecks); } - CTxUndo txundo; - UpdateCoins(tx, state, view, txundo, pindex->nHeight); - if (!tx.IsCoinBase()) - blockundo.vtxundo.push_back(txundo); + CTxUndo undoDummy; + if (i > 0) { + blockundo.vtxundo.push_back(CTxUndo()); + } + UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight); vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); @@ -3706,7 +3656,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LOCK(cs_main); // Find the last block the caller has in the main chain - CBlockIndex* pindex = chainActive.FindFork(locator); + CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator); // Send the rest of the chain if (pindex) @@ -3753,7 +3703,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else { // Find the last block the caller has in the main chain - pindex = chainActive.FindFork(locator); + pindex = FindForkInGlobalIndex(chainActive, locator); if (pindex) pindex = chainActive.Next(pindex); } @@ -4500,7 +4450,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to append - CAutoFile fileout = CAutoFile(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); + CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); if (!fileout) return error("CBlockUndo::WriteToDisk : OpenUndoFile failed"); @@ -4532,7 +4482,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to read - CAutoFile filein = CAutoFile(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); + CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); if (!filein) return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed"); |