From: alex Date: Tue, 21 Jan 2014 04:33:18 +0000 (+0400) Subject: Transaction hash caching X-Git-Tag: v0.4.4.7-nvc-next-testing~12 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=cdef376f34dfbd06c8a8673fdb5625d5fefbc851 Transaction hash caching Use CBlock's vMerkleTree to cache transaction hashes, and pass them along as argument in more function calls. --- diff --git a/src/main.cpp b/src/main.cpp index c632ba7..f144a58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -130,7 +130,7 @@ void static EraseFromWallets(uint256 hash) } // make sure all wallets know about the given transaction, in the given block -void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect) +void SyncWithWallets(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fConnect) { if (!fConnect) { @@ -145,7 +145,7 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, } BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) - pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate); + pwallet->AddToWalletIfInvolvingMe(hash, tx, pblock, fUpdate); } // notify wallets about a new best chain @@ -1351,10 +1351,8 @@ unsigned int CTransaction::GetP2SHSigOpCount(CCoinsView& inputs) const return nSigOps; } -bool CTransaction::UpdateCoins(CCoinsView &inputs, CTxUndo &txundo, int nHeight, unsigned int nTimeStamp) const +bool CTransaction::UpdateCoins(CCoinsView &inputs, CTxUndo &txundo, int nHeight, unsigned int nTimeStamp, const uint256 &txhash) const { - uint256 hash = GetHash(); - // mark inputs spent if (!IsCoinBase()) { BOOST_FOREACH(const CTxIn &txin, vin) { @@ -1373,7 +1371,7 @@ bool CTransaction::UpdateCoins(CCoinsView &inputs, CTxUndo &txundo, int nHeight, } // add outputs - if (!inputs.SetCoins(hash, CCoins(*this, nHeight, nTimeStamp))) + if (!inputs.SetCoins(txhash, CCoins(*this, nHeight, nTimeStamp))) return error("UpdateCoins() : cannot update output"); return true; @@ -1653,8 +1651,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck bool fEnforceBIP30 = true; if (fEnforceBIP30) { - BOOST_FOREACH(CTransaction& tx, vtx) { - uint256 hash = tx.GetHash(); + for (unsigned int i=0; i MAX_BLOCK_SIGOPS) return DoS(100, error("ConnectBlock() : too many sigops")); @@ -1711,7 +1710,7 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck continue; CTxUndo txundo; - if (!tx.UpdateCoins(view, txundo, pindex->nHeight, pindex->nTime)) + if (!tx.UpdateCoins(view, txundo, pindex->nHeight, pindex->nTime, GetTxHash(i))) return error("ConnectBlock() : UpdateInputs failed"); if (!tx.IsCoinBase()) blockundo.vtxundo.push_back(txundo); @@ -1751,8 +1750,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsView &view, bool fJustCheck printf("ConnectBlock() : destroy=%s nFees=%"PRI64d"\n", FormatMoney(nFees).c_str(), nFees); // Watch for transactions paying to me - BOOST_FOREACH(CTransaction& tx, vtx) - SyncWithWallets(tx, this, true); + for (unsigned int i=0; i uniqueTx; - BOOST_FOREACH(const CTransaction& tx, vtx) - { - uniqueTx.insert(tx.GetHash()); + for (unsigned int i=0; i 0); // BuildMerkleTree must have been called first + assert(nIndex < vtx.size()); + return vMerkleTree[nIndex]; + } + std::vector GetMerkleBranch(int nIndex) const { if (vMerkleTree.empty()) diff --git a/src/miner.cpp b/src/miner.cpp index 756cf6f..7006cbe 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -313,9 +313,12 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) if (!tx.UpdateCoins(viewTemp, txundo, pindexPrev->nHeight+1, pblock->nTime)) continue; +*/ + // push changes from the second layer cache to the first one viewTemp.Flush(); -*/ + uint256 hash = tx.GetHash(); + // Added pblock->vtx.push_back(tx); nBlockSize += nTxSize; @@ -330,7 +333,6 @@ CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake) } // Add transactions that depend on this one to the priority queue - uint256 hash = tx.GetHash(); if (mapDependers.count(hash)) { BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index dc32217..90d1b8b 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -550,7 +550,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) // Not in block, but already in the memory pool; will drop // through to re-relay it. } else { - SyncWithWallets(tx, NULL, true); + SyncWithWallets(hashTx, tx, NULL, true); } RelayTransaction(tx, hashTx); diff --git a/src/wallet.cpp b/src/wallet.cpp index 55630af..025b6c9 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -520,9 +520,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) // Add a transaction to the wallet, or update it. // pblock is optional, but should be provided if the transaction is known to be in a block. // If fUpdate is true, existing transactions will be updated. -bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock) +bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock) { - uint256 hash = tx.GetHash(); { LOCK(cs_wallet); bool fExisted = mapWallet.count(hash); @@ -809,7 +808,7 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) block.ReadFromDisk(pindex, true); BOOST_FOREACH(CTransaction& tx, block.vtx) { - if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) + if (AddToWalletIfInvolvingMe(tx.GetHash(), tx, &block, fUpdate)) ret++; } pindex = pindex->pnext; diff --git a/src/wallet.h b/src/wallet.h index a3ead62..bacfd89 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -171,7 +171,7 @@ public: void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn); - bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); + bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); bool EraseFromWallet(uint256 hash); void WalletUpdateSpent(const CTransaction& prevout); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);