Code simplifications after CTransaction::GetHash() caching

This commit is contained in:
Pieter Wuille
2014-06-09 10:02:00 +02:00
parent 4949004d68
commit d38da59bf6
12 changed files with 67 additions and 78 deletions

View File

@@ -130,8 +130,8 @@ namespace {
namespace {
struct CMainSignals {
// Notifies listeners of updated transaction data (passing hash, transaction, and optionally the block it is found in.
boost::signals2::signal<void (const uint256 &, const CTransaction &, const CBlock *)> SyncTransaction;
// Notifies listeners of updated transaction data (transaction, and optionally the block it is found in.
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
// Notifies listeners of an erased transaction (currently disabled, requires transaction replacement).
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
// Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible).
@@ -146,7 +146,7 @@ struct CMainSignals {
}
void RegisterWallet(CWalletInterface* pwalletIn) {
g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
g_signals.SyncTransaction.connect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
g_signals.EraseTransaction.connect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
g_signals.UpdatedTransaction.connect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.SetBestChain.connect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
@@ -160,7 +160,7 @@ void UnregisterWallet(CWalletInterface* pwalletIn) {
g_signals.SetBestChain.disconnect(boost::bind(&CWalletInterface::SetBestChain, pwalletIn, _1));
g_signals.UpdatedTransaction.disconnect(boost::bind(&CWalletInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.EraseTransaction.disconnect(boost::bind(&CWalletInterface::EraseFromWallet, pwalletIn, _1));
g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2, _3));
g_signals.SyncTransaction.disconnect(boost::bind(&CWalletInterface::SyncTransaction, pwalletIn, _1, _2));
}
void UnregisterAllWallets() {
@@ -172,8 +172,8 @@ void UnregisterAllWallets() {
g_signals.SyncTransaction.disconnect_all_slots();
}
void SyncWithWallets(const uint256 &hash, const CTransaction &tx, const CBlock *pblock) {
g_signals.SyncTransaction(hash, tx, pblock);
void SyncWithWallets(const CTransaction &tx, const CBlock *pblock) {
g_signals.SyncTransaction(tx, pblock);
}
//////////////////////////////////////////////////////////////////////////////
@@ -952,7 +952,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
pool.addUnchecked(hash, entry);
}
g_signals.SyncTransaction(hash, tx, NULL);
g_signals.SyncTransaction(tx, NULL);
return true;
}
@@ -1479,7 +1479,7 @@ void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash)
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight)
{
bool ret;
// mark inputs spent
@@ -1494,7 +1494,7 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
}
// add outputs
ret = inputs.SetCoins(txhash, CCoins(tx, nHeight));
ret = inputs.SetCoins(tx.GetHash(), CCoins(tx, nHeight));
assert(ret);
}
@@ -1767,8 +1767,8 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
!((pindex->nHeight==91842 && pindex->GetBlockHash() == uint256("0x00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
(pindex->nHeight==91880 && pindex->GetBlockHash() == uint256("0x00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));
if (fEnforceBIP30) {
for (unsigned int i = 0; i < block.vtx.size(); i++) {
uint256 hash = block.GetTxHash(i);
BOOST_FOREACH(const CTransaction& tx, block.vtx) {
const uint256& hash = tx.GetHash();
if (view.HaveCoins(hash) && !view.GetCoins(hash).IsPruned())
return state.DoS(100, error("ConnectBlock() : tried to overwrite transaction"),
REJECT_INVALID, "bad-txns-BIP30");
@@ -1829,11 +1829,11 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
}
CTxUndo txundo;
UpdateCoins(tx, state, view, txundo, pindex->nHeight, block.GetTxHash(i));
UpdateCoins(tx, state, view, txundo, pindex->nHeight);
if (!tx.IsCoinBase())
blockundo.vtxundo.push_back(txundo);
vPos.push_back(std::make_pair(block.GetTxHash(i), pos));
vPos.push_back(std::make_pair(tx.GetHash(), pos));
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
}
int64_t nTime = GetTimeMicros() - nStart;
@@ -1892,13 +1892,13 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
assert(ret);
// Watch for transactions paying to me
for (unsigned int i = 0; i < block.vtx.size(); i++)
g_signals.SyncTransaction(block.GetTxHash(i), block.vtx[i], &block);
BOOST_FOREACH(const CTransaction& tx, block.vtx)
g_signals.SyncTransaction(tx, &block);
// Watch for changes to the previous coinbase transaction.
static uint256 hashPrevBestCoinBase;
g_signals.UpdatedTransaction(hashPrevBestCoinBase);
hashPrevBestCoinBase = block.GetTxHash(0);
hashPrevBestCoinBase = block.vtx[0].GetHash();
return true;
}
@@ -1996,7 +1996,7 @@ bool static DisconnectTip(CValidationState &state) {
// Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted:
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
SyncWithWallets(tx.GetHash(), tx, NULL);
SyncWithWallets(tx, NULL);
}
return true;
}
@@ -2036,11 +2036,11 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
// Tell wallet about transactions that went from mempool
// to conflicted:
BOOST_FOREACH(const CTransaction &tx, txConflicted) {
SyncWithWallets(tx.GetHash(), tx, NULL);
SyncWithWallets(tx, NULL);
}
// ... and about transactions that got confirmed:
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
SyncWithWallets(tx.GetHash(), tx, &block);
SyncWithWallets(tx, &block);
}
return true;
}
@@ -2381,16 +2381,11 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
if (!CheckTransaction(tx, state))
return error("CheckBlock() : CheckTransaction failed");
// Build the merkle tree already. We need it anyway later, and it makes the
// block cache the transaction hashes, which means they don't need to be
// recalculated many times during this block's validation.
block.BuildMerkleTree();
// Check for duplicate txids. This is caught by ConnectInputs(),
// but catching it earlier avoids a potential DoS attack:
set<uint256> uniqueTx;
for (unsigned int i = 0; i < block.vtx.size(); i++) {
uniqueTx.insert(block.GetTxHash(i));
BOOST_FOREACH(const CTransaction &tx, block.vtx) {
uniqueTx.insert(tx.GetHash());
}
if (uniqueTx.size() != block.vtx.size())
return state.DoS(100, error("CheckBlock() : duplicate transaction"),
@@ -2406,7 +2401,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
REJECT_INVALID, "bad-blk-sigops", true);
// Check merkle root
if (fCheckMerkleRoot && block.hashMerkleRoot != block.vMerkleTree.back())
if (fCheckMerkleRoot && block.hashMerkleRoot != block.BuildMerkleTree())
return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true);
@@ -2682,8 +2677,8 @@ CMerkleBlock::CMerkleBlock(const CBlock& block, CBloomFilter& filter)
for (unsigned int i = 0; i < block.vtx.size(); i++)
{
uint256 hash = block.vtx[i].GetHash();
if (filter.IsRelevantAndUpdate(block.vtx[i], hash))
const uint256& hash = block.vtx[i].GetHash();
if (filter.IsRelevantAndUpdate(block.vtx[i]))
{
vMatch.push_back(true);
vMatchedTxn.push_back(make_pair(i, hash));
@@ -3832,7 +3827,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
{
mempool.check(pcoinsTip);
RelayTransaction(tx, inv.hash);
RelayTransaction(tx);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
@@ -3862,7 +3857,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2))
{
LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
RelayTransaction(orphanTx, orphanHash);
RelayTransaction(orphanTx);
mapAlreadyAskedFor.erase(CInv(MSG_TX, orphanHash));
vWorkQueue.push_back(orphanHash);
vEraseQueue.push_back(orphanHash);
@@ -3947,7 +3942,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CTransaction tx;
bool fInMemPool = mempool.lookup(hash, tx);
if (!fInMemPool) continue; // another thread removed since queryHashes, maybe...
if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx, hash)) ||
if ((pfrom->pfilter && pfrom->pfilter->IsRelevantAndUpdate(tx)) ||
(!pfrom->pfilter))
vInv.push_back(inv);
if (vInv.size() == MAX_INV_SZ) {