Browse Source

Introduce convenience type CTransactionRef

0.14
Pieter Wuille 8 years ago
parent
commit
b4e4ba475a
  1. 2
      src/blockencodings.cpp
  2. 12
      src/blockencodings.h
  3. 2
      src/chainparams.cpp
  4. 14
      src/main.cpp
  5. 4
      src/miner.cpp
  6. 2
      src/primitives/block.h
  7. 6
      src/primitives/transaction.h
  8. 18
      src/test/blockencodings_tests.cpp
  9. 8
      src/test/mempool_tests.cpp
  10. 4
      src/test/merkle_tests.cpp
  11. 6
      src/test/miner_tests.cpp
  12. 2
      src/test/pmt_tests.cpp
  13. 8
      src/test/policyestimator_tests.cpp
  14. 2
      src/test/test_bitcoin.cpp
  15. 14
      src/txmempool.cpp
  16. 16
      src/txmempool.h

2
src/blockencodings.cpp

@ -142,7 +142,7 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
return txn_available[index] ? true : false; return txn_available[index] ? true : false;
} }
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<std::shared_ptr<const CTransaction>>& vtx_missing) const { ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) const {
assert(!header.IsNull()); assert(!header.IsNull());
block = header; block = header;
block.vtx.resize(txn_available.size()); block.vtx.resize(txn_available.size());

12
src/blockencodings.h

@ -14,9 +14,9 @@ class CTxMemPool;
// Dumb helper to handle CTransaction compression at serialize-time // Dumb helper to handle CTransaction compression at serialize-time
struct TransactionCompressor { struct TransactionCompressor {
private: private:
std::shared_ptr<const CTransaction>& tx; CTransactionRef& tx;
public: public:
TransactionCompressor(std::shared_ptr<const CTransaction>& txIn) : tx(txIn) {} TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {}
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -72,7 +72,7 @@ class BlockTransactions {
public: public:
// A BlockTransactions message // A BlockTransactions message
uint256 blockhash; uint256 blockhash;
std::vector<std::shared_ptr<const CTransaction>> txn; std::vector<CTransactionRef> txn;
BlockTransactions() {} BlockTransactions() {}
BlockTransactions(const BlockTransactionsRequest& req) : BlockTransactions(const BlockTransactionsRequest& req) :
@ -104,7 +104,7 @@ struct PrefilledTransaction {
// Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs, // Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs,
// as a proper transaction-in-block-index in PartiallyDownloadedBlock // as a proper transaction-in-block-index in PartiallyDownloadedBlock
uint16_t index; uint16_t index;
std::shared_ptr<const CTransaction> tx; CTransactionRef tx;
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -193,7 +193,7 @@ public:
class PartiallyDownloadedBlock { class PartiallyDownloadedBlock {
protected: protected:
std::vector<std::shared_ptr<const CTransaction> > txn_available; std::vector<CTransactionRef> txn_available;
size_t prefilled_count = 0, mempool_count = 0; size_t prefilled_count = 0, mempool_count = 0;
CTxMemPool* pool; CTxMemPool* pool;
public: public:
@ -202,7 +202,7 @@ public:
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock); ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock);
bool IsTxAvailable(size_t index) const; bool IsTxAvailable(size_t index) const;
ReadStatus FillBlock(CBlock& block, const std::vector<std::shared_ptr<const CTransaction>>& vtx_missing) const; ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) const;
}; };
#endif #endif

2
src/chainparams.cpp

@ -31,7 +31,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
genesis.nBits = nBits; genesis.nBits = nBits;
genesis.nNonce = nNonce; genesis.nNonce = nNonce;
genesis.nVersion = nVersion; genesis.nVersion = nVersion;
genesis.vtx.push_back(std::make_shared<const CTransaction>(std::move(txNew))); genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis.hashPrevBlock.SetNull(); genesis.hashPrevBlock.SetNull();
genesis.hashMerkleRoot = BlockMerkleRoot(genesis); genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
return genesis; return genesis;

14
src/main.cpp

@ -233,7 +233,7 @@ namespace {
int nPeersWithValidatedDownloads = 0; int nPeersWithValidatedDownloads = 0;
/** Relay map, protected by cs_main. */ /** Relay map, protected by cs_main. */
typedef std::map<uint256, std::shared_ptr<const CTransaction>> MapRelay; typedef std::map<uint256, CTransactionRef> MapRelay;
MapRelay mapRelay; MapRelay mapRelay;
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */ /** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration; std::deque<std::pair<int64_t, MapRelay::iterator>> vRelayExpiration;
@ -1639,7 +1639,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::P
LOCK(cs_main); LOCK(cs_main);
std::shared_ptr<const CTransaction> ptx = mempool.get(hash); CTransactionRef ptx = mempool.get(hash);
if (ptx) if (ptx)
{ {
txOut = *ptx; txOut = *ptx;
@ -2845,7 +2845,7 @@ static int64_t nTimePostConnect = 0;
* Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock * Connect a new block to chainActive. pblock is either NULL or a pointer to a CBlock
* corresponding to pindexNew, to bypass loading it again from disk. * corresponding to pindexNew, to bypass loading it again from disk.
*/ */
bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock, std::vector<std::shared_ptr<const CTransaction>> &txConflicted, std::vector<std::tuple<std::shared_ptr<const CTransaction>,CBlockIndex*,int>> &txChanged) bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const CBlock* pblock, std::vector<CTransactionRef> &txConflicted, std::vector<std::tuple<CTransactionRef,CBlockIndex*,int>> &txChanged)
{ {
assert(pindexNew->pprev == chainActive.Tip()); assert(pindexNew->pprev == chainActive.Tip());
// Read block from disk. // Read block from disk.
@ -2968,7 +2968,7 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block. * Try to make some progress towards making pindexMostWork the active block.
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork. * pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
*/ */
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock, bool& fInvalidFound, std::vector<std::shared_ptr<const CTransaction>>& txConflicted, std::vector<std::tuple<std::shared_ptr<const CTransaction>,CBlockIndex*,int>>& txChanged) static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock, bool& fInvalidFound, std::vector<CTransactionRef>& txConflicted, std::vector<std::tuple<CTransactionRef,CBlockIndex*,int>>& txChanged)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
const CBlockIndex *pindexOldTip = chainActive.Tip(); const CBlockIndex *pindexOldTip = chainActive.Tip();
@ -3069,7 +3069,7 @@ static void NotifyHeaderTip() {
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) {
CBlockIndex *pindexMostWork = NULL; CBlockIndex *pindexMostWork = NULL;
CBlockIndex *pindexNewTip = NULL; CBlockIndex *pindexNewTip = NULL;
std::vector<std::tuple<std::shared_ptr<const CTransaction>,CBlockIndex*,int>> txChanged; std::vector<std::tuple<CTransactionRef,CBlockIndex*,int>> txChanged;
if (pblock) if (pblock)
txChanged.reserve(pblock->vtx.size()); txChanged.reserve(pblock->vtx.size());
do { do {
@ -3079,7 +3079,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
break; break;
const CBlockIndex *pindexFork; const CBlockIndex *pindexFork;
std::vector<std::shared_ptr<const CTransaction>> txConflicted; std::vector<CTransactionRef> txConflicted;
bool fInitialDownload; bool fInitialDownload;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -3523,7 +3523,7 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
tx.wit.vtxinwit.resize(1); tx.wit.vtxinwit.resize(1);
tx.wit.vtxinwit[0].scriptWitness.stack.resize(1); tx.wit.vtxinwit[0].scriptWitness.stack.resize(1);
tx.wit.vtxinwit[0].scriptWitness.stack[0] = nonce; tx.wit.vtxinwit[0].scriptWitness.stack[0] = nonce;
block.vtx[0] = std::make_shared<const CTransaction>(std::move(tx)); block.vtx[0] = MakeTransactionRef(std::move(tx));
} }
} }

4
src/miner.cpp

@ -178,7 +178,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus()); coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
pblock->vtx[0] = std::make_shared<const CTransaction>(std::move(coinbaseTx)); pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx));
pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus());
pblocktemplate->vTxFees[0] = -nFees; pblocktemplate->vTxFees[0] = -nFees;
@ -605,6 +605,6 @@ void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned
txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS; txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
assert(txCoinbase.vin[0].scriptSig.size() <= 100); assert(txCoinbase.vin[0].scriptSig.size() <= 100);
pblock->vtx[0] = std::make_shared<const CTransaction>(std::move(txCoinbase)); pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
} }

2
src/primitives/block.h

@ -73,7 +73,7 @@ class CBlock : public CBlockHeader
{ {
public: public:
// network and disk // network and disk
std::vector<std::shared_ptr<const CTransaction>> vtx; std::vector<CTransactionRef> vtx;
// memory only // memory only
mutable bool fChecked; mutable bool fChecked;

6
src/primitives/transaction.h

@ -475,6 +475,12 @@ struct CMutableTransaction
uint256 GetHash() const; uint256 GetHash() const;
}; };
typedef std::shared_ptr<const CTransaction> CTransactionRef;
static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
static inline CTransactionRef MakeTransactionRef(const CTransactionRef& txIn) { return txIn; }
static inline CTransactionRef MakeTransactionRef(CTransactionRef&& txIn) { return std::move(txIn); }
/** Compute the weight of a transaction, as defined by BIP 141 */ /** Compute the weight of a transaction, as defined by BIP 141 */
int64_t GetTransactionWeight(const CTransaction &tx); int64_t GetTransactionWeight(const CTransaction &tx);

18
src/test/blockencodings_tests.cpp

@ -26,21 +26,21 @@ static CBlock BuildBlockTestCase() {
tx.vout[0].nValue = 42; tx.vout[0].nValue = 42;
block.vtx.resize(3); block.vtx.resize(3);
block.vtx[0] = std::make_shared<const CTransaction>(tx); block.vtx[0] = MakeTransactionRef(tx);
block.nVersion = 42; block.nVersion = 42;
block.hashPrevBlock = GetRandHash(); block.hashPrevBlock = GetRandHash();
block.nBits = 0x207fffff; block.nBits = 0x207fffff;
tx.vin[0].prevout.hash = GetRandHash(); tx.vin[0].prevout.hash = GetRandHash();
tx.vin[0].prevout.n = 0; tx.vin[0].prevout.n = 0;
block.vtx[1] = std::make_shared<const CTransaction>(tx); block.vtx[1] = MakeTransactionRef(tx);
tx.vin.resize(10); tx.vin.resize(10);
for (size_t i = 0; i < tx.vin.size(); i++) { for (size_t i = 0; i < tx.vin.size(); i++) {
tx.vin[i].prevout.hash = GetRandHash(); tx.vin[i].prevout.hash = GetRandHash();
tx.vin[i].prevout.n = 0; tx.vin[i].prevout.n = 0;
} }
block.vtx[2] = std::make_shared<const CTransaction>(tx); block.vtx[2] = MakeTransactionRef(tx);
bool mutated; bool mutated;
block.hashMerkleRoot = BlockMerkleRoot(block, &mutated); block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
@ -80,12 +80,12 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
std::vector<std::shared_ptr<const CTransaction>> removed; std::vector<CTransactionRef> removed;
pool.removeRecursive(*block.vtx[2], &removed); pool.removeRecursive(*block.vtx[2], &removed);
BOOST_CHECK_EQUAL(removed.size(), 1); BOOST_CHECK_EQUAL(removed.size(), 1);
CBlock block2; CBlock block2;
std::vector<std::shared_ptr<const CTransaction>> vtx_missing; std::vector<CTransactionRef> vtx_missing;
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
vtx_missing.push_back(block.vtx[2]); // Wrong transaction vtx_missing.push_back(block.vtx[2]); // Wrong transaction
@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
CBlock block2; CBlock block2;
std::vector<std::shared_ptr<const CTransaction>> vtx_missing; std::vector<CTransactionRef> vtx_missing;
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
vtx_missing.push_back(block.vtx[1]); // Wrong transaction vtx_missing.push_back(block.vtx[1]); // Wrong transaction
@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
CBlock block2; CBlock block2;
std::vector<std::shared_ptr<const CTransaction>> vtx_missing; std::vector<CTransactionRef> vtx_missing;
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
bool mutated; bool mutated;
@ -266,7 +266,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
CBlock block; CBlock block;
block.vtx.resize(1); block.vtx.resize(1);
block.vtx[0] = std::make_shared<const CTransaction>(std::move(coinbase)); block.vtx[0] = MakeTransactionRef(std::move(coinbase));
block.nVersion = 42; block.nVersion = 42;
block.hashPrevBlock = GetRandHash(); block.hashPrevBlock = GetRandHash();
block.nBits = 0x207fffff; block.nBits = 0x207fffff;
@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
BOOST_CHECK(partialBlock.IsTxAvailable(0)); BOOST_CHECK(partialBlock.IsTxAvailable(0));
CBlock block2; CBlock block2;
std::vector<std::shared_ptr<const CTransaction>> vtx_missing; std::vector<CTransactionRef> vtx_missing;
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());

8
src/test/mempool_tests.cpp

@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)
CTxMemPool testPool(CFeeRate(0)); CTxMemPool testPool(CFeeRate(0));
std::vector<std::shared_ptr<const CTransaction>> removed; std::vector<CTransactionRef> removed;
// Nothing in pool, remove should do nothing: // Nothing in pool, remove should do nothing:
testPool.removeRecursive(txParent, &removed); testPool.removeRecursive(txParent, &removed);
@ -410,8 +410,8 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
CheckSort<ancestor_score>(pool, sortedOrder); CheckSort<ancestor_score>(pool, sortedOrder);
/* after tx6 is mined, tx7 should move up in the sort */ /* after tx6 is mined, tx7 should move up in the sort */
std::vector<std::shared_ptr<const CTransaction>> vtx; std::vector<CTransactionRef> vtx;
vtx.push_back(std::make_shared<const CTransaction>(tx6)); vtx.push_back(MakeTransactionRef(tx6));
pool.removeForBlock(vtx, 1, NULL, false); pool.removeForBlock(vtx, 1, NULL, false);
sortedOrder.erase(sortedOrder.begin()+1); sortedOrder.erase(sortedOrder.begin()+1);
@ -546,7 +546,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest)
pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool));
pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool));
std::vector<std::shared_ptr<const CTransaction>> vtx; std::vector<CTransactionRef> vtx;
SetMockTime(42); SetMockTime(42);
SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE); SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE);
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000); BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);

4
src/test/merkle_tests.cpp

@ -15,7 +15,7 @@ static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::ve
{ {
vMerkleTree.clear(); vMerkleTree.clear();
vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes. vMerkleTree.reserve(block.vtx.size() * 2 + 16); // Safe upper bound for the number of total nodes.
for (std::vector<std::shared_ptr<const CTransaction>>::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it) for (std::vector<CTransactionRef>::const_iterator it(block.vtx.begin()); it != block.vtx.end(); ++it)
vMerkleTree.push_back((*it)->GetHash()); vMerkleTree.push_back((*it)->GetHash());
int j = 0; int j = 0;
bool mutated = false; bool mutated = false;
@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(merkle_test)
for (int j = 0; j < ntx; j++) { for (int j = 0; j < ntx; j++) {
CMutableTransaction mtx; CMutableTransaction mtx;
mtx.nLockTime = j; mtx.nLockTime = j;
block.vtx[j] = std::make_shared<const CTransaction>(mtx); block.vtx[j] = MakeTransactionRef(std::move(mtx));
} }
// Compute the root of the block before mutating it. // Compute the root of the block before mutating it.
bool unmutatedMutated = false; bool unmutatedMutated = false;

6
src/test/miner_tests.cpp

@ -77,7 +77,7 @@ bool TestSequenceLocks(const CTransaction &tx, int flags)
// Implemented as an additional function, rather than a separate test case, // Implemented as an additional function, rather than a separate test case,
// to allow reusing the blockchain created in CreateNewBlock_validity. // to allow reusing the blockchain created in CreateNewBlock_validity.
// Note that this test assumes blockprioritysize is 0. // Note that this test assumes blockprioritysize is 0.
void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<std::shared_ptr<const CTransaction>>& txFirst) void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector<CTransactionRef>& txFirst)
{ {
// Test the ancestor feerate transaction selection. // Test the ancestor feerate transaction selection.
TestMemPoolEntryHelper entry; TestMemPoolEntryHelper entry;
@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// We can't make transactions until we have inputs // We can't make transactions until we have inputs
// Therefore, load 100 blocks :) // Therefore, load 100 blocks :)
int baseheight = 0; int baseheight = 0;
std::vector<std::shared_ptr<const CTransaction>> txFirst; std::vector<CTransactionRef> txFirst;
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i) for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
{ {
CBlock *pblock = &pblocktemplate->block; // pointer for convenience CBlock *pblock = &pblocktemplate->block; // pointer for convenience
@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce); txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
txCoinbase.vout[0].scriptPubKey = CScript(); txCoinbase.vout[0].scriptPubKey = CScript();
pblock->vtx[0] = std::make_shared<const CTransaction>(std::move(txCoinbase)); pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
if (txFirst.size() == 0) if (txFirst.size() == 0)
baseheight = chainActive.Height(); baseheight = chainActive.Height();
if (txFirst.size() < 4) if (txFirst.size() < 4)

2
src/test/pmt_tests.cpp

@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
for (unsigned int j=0; j<nTx; j++) { for (unsigned int j=0; j<nTx; j++) {
CMutableTransaction tx; CMutableTransaction tx;
tx.nLockTime = j; // actual transaction data doesn't matter; just make the nLockTime's unique tx.nLockTime = j; // actual transaction data doesn't matter; just make the nLockTime's unique
block.vtx.push_back(std::make_shared<const CTransaction>(tx)); block.vtx.push_back(MakeTransactionRef(std::move(tx)));
} }
// calculate actual merkle root and height // calculate actual merkle root and height

8
src/test/policyestimator_tests.cpp

@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
CFeeRate baseRate(basefee, GetVirtualTransactionSize(tx)); CFeeRate baseRate(basefee, GetVirtualTransactionSize(tx));
// Create a fake block // Create a fake block
std::vector<std::shared_ptr<const CTransaction>> block; std::vector<CTransactionRef> block;
int blocknum = 0; int blocknum = 0;
// Loop through 200 blocks // Loop through 200 blocks
@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// 9/10 blocks add 2nd highest and so on until ... // 9/10 blocks add 2nd highest and so on until ...
// 1/10 blocks add lowest fee transactions // 1/10 blocks add lowest fee transactions
while (txHashes[9-h].size()) { while (txHashes[9-h].size()) {
std::shared_ptr<const CTransaction> ptx = mpool.get(txHashes[9-h].back()); CTransactionRef ptx = mpool.get(txHashes[9-h].back());
if (ptx) if (ptx)
block.push_back(ptx); block.push_back(ptx);
txHashes[9-h].pop_back(); txHashes[9-h].pop_back();
@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// Estimates should still not be below original // Estimates should still not be below original
for (int j = 0; j < 10; j++) { for (int j = 0; j < 10; j++) {
while(txHashes[j].size()) { while(txHashes[j].size()) {
std::shared_ptr<const CTransaction> ptx = mpool.get(txHashes[j].back()); CTransactionRef ptx = mpool.get(txHashes[j].back());
if (ptx) if (ptx)
block.push_back(ptx); block.push_back(ptx);
txHashes[j].pop_back(); txHashes[j].pop_back();
@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
tx.vin[0].prevout.n = 10000*blocknum+100*j+k; tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
uint256 hash = tx.GetHash(); uint256 hash = tx.GetHash();
mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool)); mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool));
std::shared_ptr<const CTransaction> ptx = mpool.get(hash); CTransactionRef ptx = mpool.get(hash);
if (ptx) if (ptx)
block.push_back(ptx); block.push_back(ptx);

2
src/test/test_bitcoin.cpp

@ -119,7 +119,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
// Replace mempool-selected txns with just coinbase plus passed-in txns: // Replace mempool-selected txns with just coinbase plus passed-in txns:
block.vtx.resize(1); block.vtx.resize(1);
BOOST_FOREACH(const CMutableTransaction& tx, txns) BOOST_FOREACH(const CMutableTransaction& tx, txns)
block.vtx.push_back(std::make_shared<const CTransaction>(tx)); block.vtx.push_back(MakeTransactionRef(tx));
// IncrementExtraNonce creates a valid coinbase and merkleRoot // IncrementExtraNonce creates a valid coinbase and merkleRoot
unsigned int extraNonce = 0; unsigned int extraNonce = 0;
IncrementExtraNonce(&block, chainActive.Tip(), extraNonce); IncrementExtraNonce(&block, chainActive.Tip(), extraNonce);

14
src/txmempool.cpp

@ -24,7 +24,7 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTransaction& _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(std::make_shared<CTransaction>(_tx)), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), tx(MakeTransactionRef(_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)
{ {
@ -503,7 +503,7 @@ void CTxMemPool::CalculateDescendants(txiter entryit, setEntries &setDescendants
} }
} }
void CTxMemPool::removeRecursive(const CTransaction &origTx, std::vector<std::shared_ptr<const CTransaction>>* removed) void CTxMemPool::removeRecursive(const CTransaction &origTx, std::vector<CTransactionRef>* removed)
{ {
// Remove transaction from memory pool // Remove transaction from memory pool
{ {
@ -576,7 +576,7 @@ void CTxMemPool::removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMem
RemoveStaged(setAllRemoves, false); RemoveStaged(setAllRemoves, false);
} }
void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<std::shared_ptr<const CTransaction>>* removed) void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<CTransactionRef>* removed)
{ {
// Remove transactions which depend on inputs of tx, recursively // Remove transactions which depend on inputs of tx, recursively
LOCK(cs); LOCK(cs);
@ -596,8 +596,8 @@ void CTxMemPool::removeConflicts(const CTransaction &tx, std::vector<std::shared
/** /**
* Called when a block is connected. Removes from mempool and updates the miner fee estimator. * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
*/ */
void CTxMemPool::removeForBlock(const std::vector<shared_ptr<const CTransaction>>& vtx, unsigned int nBlockHeight, void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight,
std::vector<std::shared_ptr<const CTransaction>>* conflicts, bool fCurrentEstimate) std::vector<CTransactionRef>* conflicts, bool fCurrentEstimate)
{ {
LOCK(cs); LOCK(cs);
std::vector<CTxMemPoolEntry> entries; std::vector<CTxMemPoolEntry> entries;
@ -851,7 +851,7 @@ std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
return ret; return ret;
} }
std::shared_ptr<const CTransaction> CTxMemPool::get(const uint256& hash) const CTransactionRef CTxMemPool::get(const uint256& hash) const
{ {
LOCK(cs); LOCK(cs);
indexed_transaction_set::const_iterator i = mapTx.find(hash); indexed_transaction_set::const_iterator i = mapTx.find(hash);
@ -978,7 +978,7 @@ bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) const {
// If an entry in the mempool exists, always return that one, as it's guaranteed to never // If an entry in the mempool exists, always return that one, as it's guaranteed to never
// conflict with the underlying cache, and it cannot have pruned entries (as it contains full) // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
// transactions. First checking the underlying cache risks returning a pruned entry instead. // transactions. First checking the underlying cache risks returning a pruned entry instead.
shared_ptr<const CTransaction> ptx = mempool.get(txid); CTransactionRef ptx = mempool.get(txid);
if (ptx) { if (ptx) {
coins = CCoins(*ptx, MEMPOOL_HEIGHT); coins = CCoins(*ptx, MEMPOOL_HEIGHT);
return true; return true;

16
src/txmempool.h

@ -80,7 +80,7 @@ class CTxMemPool;
class CTxMemPoolEntry class CTxMemPoolEntry
{ {
private: private:
std::shared_ptr<const CTransaction> tx; CTransactionRef tx;
CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups
size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize())
size_t nModSize; //!< ... and modified size for priority size_t nModSize; //!< ... and modified size for priority
@ -118,7 +118,7 @@ public:
CTxMemPoolEntry(const CTxMemPoolEntry& other); CTxMemPoolEntry(const CTxMemPoolEntry& other);
const CTransaction& GetTx() const { return *this->tx; } const CTransaction& GetTx() const { return *this->tx; }
std::shared_ptr<const CTransaction> GetSharedTx() const { return this->tx; } CTransactionRef GetSharedTx() const { return this->tx; }
/** /**
* Fast calculation of lower bound of current priority as update * Fast calculation of lower bound of current priority as update
* from entry priority. Only inputs that were originally in-chain will age. * from entry priority. Only inputs that were originally in-chain will age.
@ -322,7 +322,7 @@ class CBlockPolicyEstimator;
struct TxMempoolInfo struct TxMempoolInfo
{ {
/** The transaction itself */ /** The transaction itself */
std::shared_ptr<const CTransaction> tx; CTransactionRef tx;
/** Time the transaction entered the mempool. */ /** Time the transaction entered the mempool. */
int64_t nTime; int64_t nTime;
@ -527,11 +527,11 @@ public:
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool fCurrentEstimate = true);
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool fCurrentEstimate = true);
void removeRecursive(const CTransaction &tx, std::vector<std::shared_ptr<const CTransaction>>* removed = NULL); void removeRecursive(const CTransaction &tx, std::vector<CTransactionRef>* removed = NULL);
void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags); void removeForReorg(const CCoinsViewCache *pcoins, unsigned int nMemPoolHeight, int flags);
void removeConflicts(const CTransaction &tx, std::vector<std::shared_ptr<const CTransaction>>* removed = NULL); void removeConflicts(const CTransaction &tx, std::vector<CTransactionRef>* removed = NULL);
void removeForBlock(const std::vector<std::shared_ptr<const CTransaction>>& vtx, unsigned int nBlockHeight, void removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight,
std::vector<std::shared_ptr<const CTransaction>>* conflicts = NULL, bool fCurrentEstimate = true); std::vector<CTransactionRef>* conflicts = NULL, bool fCurrentEstimate = true);
void clear(); void clear();
void _clear(); //lock free void _clear(); //lock free
bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb); bool CompareDepthAndScore(const uint256& hasha, const uint256& hashb);
@ -623,7 +623,7 @@ public:
return (mapTx.count(hash) != 0); return (mapTx.count(hash) != 0);
} }
std::shared_ptr<const CTransaction> get(const uint256& hash) const; CTransactionRef get(const uint256& hash) const;
TxMempoolInfo info(const uint256& hash) const; TxMempoolInfo info(const uint256& hash) const;
std::vector<TxMempoolInfo> infoAll() const; std::vector<TxMempoolInfo> infoAll() const;

Loading…
Cancel
Save