Browse Source

Make AcceptToMemoryPool take CTransactionRef

0.14
Pieter Wuille 8 years ago
parent
commit
c44e4c467c
  1. 2
      src/bench/mempool_eviction.cpp
  2. 8
      src/net_processing.cpp
  3. 6
      src/rpc/rawtransaction.cpp
  4. 2
      src/test/test_bitcoin.cpp
  5. 2
      src/test/txvalidationcache_tests.cpp
  6. 10
      src/txmempool.cpp
  7. 3
      src/txmempool.h
  8. 16
      src/validation.cpp
  9. 4
      src/validation.h
  10. 4
      src/wallet/wallet.cpp

2
src/bench/mempool_eviction.cpp

@ -18,7 +18,7 @@ static void AddTx(const CTransaction& tx, const CAmount& nFee, CTxMemPool& pool)
unsigned int sigOpCost = 4; unsigned int sigOpCost = 4;
LockPoints lp; LockPoints lp;
pool.addUnchecked(tx.GetHash(), CTxMemPoolEntry( pool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(
tx, nFee, nTime, dPriority, nHeight, pool.HasNoInputsOf(tx), MakeTransactionRef(tx), nFee, nTime, dPriority, nHeight, pool.HasNoInputsOf(tx),
tx.GetValueOut(), spendsCoinbase, sigOpCost, lp)); tx.GetValueOut(), spendsCoinbase, sigOpCost, lp));
} }

8
src/net_processing.cpp

@ -1596,7 +1596,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
deque<COutPoint> vWorkQueue; deque<COutPoint> vWorkQueue;
vector<uint256> vEraseQueue; vector<uint256> vEraseQueue;
CTransaction tx(deserialize, vRecv); CTransactionRef ptx;
vRecv >> ptx;
const CTransaction& tx = *ptx;
CInv inv(MSG_TX, tx.GetHash()); CInv inv(MSG_TX, tx.GetHash());
pfrom->AddInventoryKnown(inv); pfrom->AddInventoryKnown(inv);
@ -1609,7 +1611,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
pfrom->setAskFor.erase(inv.hash); pfrom->setAskFor.erase(inv.hash);
mapAlreadyAskedFor.erase(inv.hash); mapAlreadyAskedFor.erase(inv.hash);
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs)) {
mempool.check(pcoinsTip); mempool.check(pcoinsTip);
RelayTransaction(tx, connman); RelayTransaction(tx, connman);
for (unsigned int i = 0; i < tx.vout.size(); i++) { for (unsigned int i = 0; i < tx.vout.size(); i++) {
@ -1646,7 +1648,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (setMisbehaving.count(fromPeer)) if (setMisbehaving.count(fromPeer))
continue; continue;
if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) { if (AcceptToMemoryPool(mempool, stateDummy, MakeTransactionRef(orphanTx), true, &fMissingInputs2)) {
LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
RelayTransaction(orphanTx, connman); RelayTransaction(orphanTx, connman);
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) { for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {

6
src/rpc/rawtransaction.cpp

@ -883,8 +883,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
CMutableTransaction mtx; CMutableTransaction mtx;
if (!DecodeHexTx(mtx, request.params[0].get_str())) if (!DecodeHexTx(mtx, request.params[0].get_str()))
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
CTransaction tx(std::move(mtx)); CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
uint256 hashTx = tx.GetHash(); const uint256& hashTx = tx->GetHash();
bool fLimitFree = false; bool fLimitFree = false;
CAmount nMaxRawTxFee = maxTxFee; CAmount nMaxRawTxFee = maxTxFee;
@ -899,7 +899,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
// push to local node and sync with wallets // push to local node and sync with wallets
CValidationState state; CValidationState state;
bool fMissingInputs; bool fMissingInputs;
if (!AcceptToMemoryPool(mempool, state, tx, fLimitFree, &fMissingInputs, false, nMaxRawTxFee)) { if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, false, nMaxRawTxFee)) {
if (state.IsInvalid()) { if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason())); throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else { } else {

2
src/test/test_bitcoin.cpp

@ -151,7 +151,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPo
// Hack to assume either its completely dependent on other mempool txs or not at all // Hack to assume either its completely dependent on other mempool txs or not at all
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0; CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight, return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, dPriority, nHeight,
hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp); hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp);
} }

2
src/test/txvalidationcache_tests.cpp

@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx)
LOCK(cs_main); LOCK(cs_main);
CValidationState state; CValidationState state;
return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0); return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, NULL, true, 0);
} }
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)

10
src/txmempool.cpp

@ -20,22 +20,22 @@
using namespace std; using namespace std;
CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight, int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
bool poolHasNoInputsOf, CAmount _inChainInputValue, bool poolHasNoInputsOf, CAmount _inChainInputValue,
bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp): bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp):
tx(MakeTransactionRef(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight),
hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue), hadNoDependencies(poolHasNoInputsOf), inChainInputValue(_inChainInputValue),
spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp) spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp)
{ {
nTxWeight = GetTransactionWeight(_tx); nTxWeight = GetTransactionWeight(*tx);
nModSize = _tx.CalculateModifiedSize(GetTxSize()); nModSize = tx->CalculateModifiedSize(GetTxSize());
nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx);
nCountWithDescendants = 1; nCountWithDescendants = 1;
nSizeWithDescendants = GetTxSize(); nSizeWithDescendants = GetTxSize();
nModFeesWithDescendants = nFee; nModFeesWithDescendants = nFee;
CAmount nValueIn = _tx.GetValueOut()+nFee; CAmount nValueIn = tx->GetValueOut()+nFee;
assert(inChainInputValue <= nValueIn); assert(inChainInputValue <= nValueIn);
feeDelta = 0; feeDelta = 0;

3
src/txmempool.h

@ -111,10 +111,11 @@ private:
int64_t nSigOpCostWithAncestors; int64_t nSigOpCostWithAncestors;
public: public:
CTxMemPoolEntry(const CTransaction& _tx, const CAmount& _nFee, CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
int64_t _nTime, double _entryPriority, unsigned int _entryHeight, int64_t _nTime, double _entryPriority, unsigned int _entryHeight,
bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase, bool poolHasNoInputsOf, CAmount _inChainInputValue, bool spendsCoinbase,
int64_t nSigOpsCost, LockPoints lp); int64_t nSigOpsCost, LockPoints lp);
CTxMemPoolEntry(const CTxMemPoolEntry& other); CTxMemPoolEntry(const CTxMemPoolEntry& other);
const CTransaction& GetTx() const { return *this->tx; } const CTransaction& GetTx() const { return *this->tx; }

16
src/validation.cpp

@ -525,10 +525,11 @@ std::string FormatStateMessage(const CValidationState &state)
state.GetRejectCode()); state.GetRejectCode());
} }
bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree, bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree,
bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee,
std::vector<uint256>& vHashTxnToUncache) std::vector<uint256>& vHashTxnToUncache)
{ {
const CTransaction& tx = *ptx;
const uint256 hash = tx.GetHash(); const uint256 hash = tx.GetHash();
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
if (pfMissingInputs) if (pfMissingInputs)
@ -691,7 +692,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
} }
} }
CTxMemPoolEntry entry(tx, nFees, nAcceptTime, dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp); CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, chainActive.Height(), pool.HasNoInputsOf(tx), inChainInputValue, fSpendsCoinbase, nSigOpsCost, lp);
unsigned int nSize = entry.GetTxSize(); unsigned int nSize = entry.GetTxSize();
// Check that the transaction doesn't have an excessive number of // Check that the transaction doesn't have an excessive number of
@ -955,7 +956,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
return true; return true;
} }
bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
{ {
std::vector<uint256> vHashTxToUncache; std::vector<uint256> vHashTxToUncache;
@ -970,7 +971,7 @@ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const
return res; return res;
} }
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee) bool* pfMissingInputs, bool fOverrideMempoolLimit, const CAmount nAbsurdFee)
{ {
return AcceptToMemoryPoolWithTime(pool, state, tx, fLimitFree, pfMissingInputs, GetTime(), fOverrideMempoolLimit, nAbsurdFee); return AcceptToMemoryPoolWithTime(pool, state, tx, fLimitFree, pfMissingInputs, GetTime(), fOverrideMempoolLimit, nAbsurdFee);
@ -2116,7 +2117,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara
const CTransaction& tx = *it; const CTransaction& tx = *it;
// ignore validation errors in resurrected transactions // ignore validation errors in resurrected transactions
CValidationState stateDummy; CValidationState stateDummy;
if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, tx, false, NULL, true)) { if (tx.IsCoinBase() || !AcceptToMemoryPool(mempool, stateDummy, it, false, NULL, true)) {
mempool.removeRecursive(tx); mempool.removeRecursive(tx);
} else if (mempool.exists(tx.GetHash())) { } else if (mempool.exists(tx.GetHash())) {
vHashUpdate.push_back(tx.GetHash()); vHashUpdate.push_back(tx.GetHash());
@ -4054,15 +4055,16 @@ bool LoadMempool(void)
file >> num; file >> num;
double prioritydummy = 0; double prioritydummy = 0;
while (num--) { while (num--) {
CTransactionRef tx;
int64_t nTime; int64_t nTime;
int64_t nFeeDelta; int64_t nFeeDelta;
CTransaction tx(deserialize, file); file >> tx;
file >> nTime; file >> nTime;
file >> nFeeDelta; file >> nFeeDelta;
CAmount amountdelta = nFeeDelta; CAmount amountdelta = nFeeDelta;
if (amountdelta) { if (amountdelta) {
mempool.PrioritiseTransaction(tx.GetHash(), tx.GetHash().ToString(), prioritydummy, amountdelta); mempool.PrioritiseTransaction(tx->GetHash(), tx->GetHash().ToString(), prioritydummy, amountdelta);
} }
CValidationState state; CValidationState state;
if (nTime + nExpiryTimeout > nNow) { if (nTime + nExpiryTimeout > nNow) {

4
src/validation.h

@ -309,11 +309,11 @@ void FlushStateToDisk();
void PruneAndFlush(); void PruneAndFlush();
/** (try to) add transaction to memory pool **/ /** (try to) add transaction to memory pool **/
bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
bool* pfMissingInputs, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); bool* pfMissingInputs, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0);
/** (try to) add transaction to memory pool with a specified acceptance time **/ /** (try to) add transaction to memory pool with a specified acceptance time **/
bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree, bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree,
bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0); bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0);
/** Convert CValidationState to a human-readable message for logging */ /** Convert CValidationState to a human-readable message for logging */

4
src/wallet/wallet.cpp

@ -2563,7 +2563,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
// Lastly, ensure this tx will pass the mempool's chain limits // Lastly, ensure this tx will pass the mempool's chain limits
LockPoints lp; LockPoints lp;
CTxMemPoolEntry entry(txNew, 0, 0, 0, 0, false, 0, false, 0, lp); CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, 0, false, 0, false, 0, lp);
CTxMemPool::setEntries setAncestors; CTxMemPool::setEntries setAncestors;
size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
@ -3782,5 +3782,5 @@ int CMerkleTx::GetBlocksToMaturity() const
bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state) bool CMerkleTx::AcceptToMemoryPool(const CAmount& nAbsurdFee, CValidationState& state)
{ {
return ::AcceptToMemoryPool(mempool, state, *this, true, NULL, false, nAbsurdFee); return ::AcceptToMemoryPool(mempool, state, tx, true, NULL, false, nAbsurdFee);
} }

Loading…
Cancel
Save