Skip to content
Permalink
Browse files

Introduce convenience type CTransactionRef

  • Loading branch information...
sipa committed Nov 11, 2016
1 parent 1662b43 commit b4e4ba475a5679e09f279aaf2a83dcf93c632bdb
@@ -142,7 +142,7 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
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());
block = header;
block.vtx.resize(txn_available.size());
@@ -14,9 +14,9 @@ class CTxMemPool;
// Dumb helper to handle CTransaction compression at serialize-time
struct TransactionCompressor {
private:
std::shared_ptr<const CTransaction>& tx;
CTransactionRef& tx;
public:
TransactionCompressor(std::shared_ptr<const CTransaction>& txIn) : tx(txIn) {}
TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {}

ADD_SERIALIZE_METHODS;

@@ -72,7 +72,7 @@ class BlockTransactions {
public:
// A BlockTransactions message
uint256 blockhash;
std::vector<std::shared_ptr<const CTransaction>> txn;
std::vector<CTransactionRef> txn;

BlockTransactions() {}
BlockTransactions(const BlockTransactionsRequest& req) :
@@ -104,7 +104,7 @@ struct PrefilledTransaction {
// Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs,
// as a proper transaction-in-block-index in PartiallyDownloadedBlock
uint16_t index;
std::shared_ptr<const CTransaction> tx;
CTransactionRef tx;

ADD_SERIALIZE_METHODS;

@@ -193,7 +193,7 @@ class CBlockHeaderAndShortTxIDs {

class PartiallyDownloadedBlock {
protected:
std::vector<std::shared_ptr<const CTransaction> > txn_available;
std::vector<CTransactionRef> txn_available;
size_t prefilled_count = 0, mempool_count = 0;
CTxMemPool* pool;
public:
@@ -202,7 +202,7 @@ class PartiallyDownloadedBlock {

ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock);
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
@@ -31,7 +31,7 @@ static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesi
genesis.nBits = nBits;
genesis.nNonce = nNonce;
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.hashMerkleRoot = BlockMerkleRoot(genesis);
return genesis;
@@ -233,7 +233,7 @@ namespace {
int nPeersWithValidatedDownloads = 0;

/** Relay map, protected by cs_main. */
typedef std::map<uint256, std::shared_ptr<const CTransaction>> MapRelay;
typedef std::map<uint256, CTransactionRef> MapRelay;
MapRelay mapRelay;
/** Expiration-time ordered list of (expire time, relay map entry) pairs, protected by cs_main). */
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);

std::shared_ptr<const CTransaction> ptx = mempool.get(hash);
CTransactionRef ptx = mempool.get(hash);
if (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
* 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());
// Read block from disk.
@@ -2968,7 +2968,7 @@ static void PruneBlockIndexCandidates() {
* Try to make some progress towards making pindexMostWork the active block.
* 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);
const CBlockIndex *pindexOldTip = chainActive.Tip();
@@ -3069,7 +3069,7 @@ static void NotifyHeaderTip() {
bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) {
CBlockIndex *pindexMostWork = 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)
txChanged.reserve(pblock->vtx.size());
do {
@@ -3079,7 +3079,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
break;

const CBlockIndex *pindexFork;
std::vector<std::shared_ptr<const CTransaction>> txConflicted;
std::vector<CTransactionRef> txConflicted;
bool fInitialDownload;
{
LOCK(cs_main);
@@ -3523,7 +3523,7 @@ void UpdateUncommittedBlockStructures(CBlock& block, const CBlockIndex* pindexPr
tx.wit.vtxinwit.resize(1);
tx.wit.vtxinwit[0].scriptWitness.stack.resize(1);
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));
}
}

@@ -178,7 +178,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn;
coinbaseTx.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
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->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;
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);
}
@@ -73,7 +73,7 @@ class CBlock : public CBlockHeader
{
public:
// network and disk
std::vector<std::shared_ptr<const CTransaction>> vtx;
std::vector<CTransactionRef> vtx;

// memory only
mutable bool fChecked;
@@ -475,6 +475,12 @@ struct CMutableTransaction
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 */
int64_t GetTransactionWeight(const CTransaction &tx);

@@ -26,21 +26,21 @@ static CBlock BuildBlockTestCase() {
tx.vout[0].nValue = 42;

block.vtx.resize(3);
block.vtx[0] = std::make_shared<const CTransaction>(tx);
block.vtx[0] = MakeTransactionRef(tx);
block.nVersion = 42;
block.hashPrevBlock = GetRandHash();
block.nBits = 0x207fffff;

tx.vin[0].prevout.hash = GetRandHash();
tx.vin[0].prevout.n = 0;
block.vtx[1] = std::make_shared<const CTransaction>(tx);
block.vtx[1] = MakeTransactionRef(tx);

tx.vin.resize(10);
for (size_t i = 0; i < tx.vin.size(); i++) {
tx.vin[i].prevout.hash = GetRandHash();
tx.vin[i].prevout.n = 0;
}
block.vtx[2] = std::make_shared<const CTransaction>(tx);
block.vtx[2] = MakeTransactionRef(tx);

bool 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);

std::vector<std::shared_ptr<const CTransaction>> removed;
std::vector<CTransactionRef> removed;
pool.removeRecursive(*block.vtx[2], &removed);
BOOST_CHECK_EQUAL(removed.size(), 1);

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

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);

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

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);

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_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
bool mutated;
@@ -266,7 +266,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)

CBlock block;
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.hashPrevBlock = GetRandHash();
block.nBits = 0x207fffff;
@@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
BOOST_CHECK(partialBlock.IsTxAvailable(0));

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_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
@@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest)


CTxMemPool testPool(CFeeRate(0));
std::vector<std::shared_ptr<const CTransaction>> removed;
std::vector<CTransactionRef> removed;

// Nothing in pool, remove should do nothing:
testPool.removeRecursive(txParent, &removed);
@@ -410,8 +410,8 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest)
CheckSort<ancestor_score>(pool, sortedOrder);

/* after tx6 is mined, tx7 should move up in the sort */
std::vector<std::shared_ptr<const CTransaction>> vtx;
vtx.push_back(std::make_shared<const CTransaction>(tx6));
std::vector<CTransactionRef> vtx;
vtx.push_back(MakeTransactionRef(tx6));
pool.removeForBlock(vtx, 1, NULL, false);

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(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool));

std::vector<std::shared_ptr<const CTransaction>> vtx;
std::vector<CTransactionRef> vtx;
SetMockTime(42);
SetMockTime(42 + CTxMemPool::ROLLING_FEE_HALFLIFE);
BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000);
@@ -15,7 +15,7 @@ static uint256 BlockBuildMerkleTree(const CBlock& block, bool* fMutated, std::ve
{
vMerkleTree.clear();
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());
int j = 0;
bool mutated = false;
@@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(merkle_test)
for (int j = 0; j < ntx; j++) {
CMutableTransaction mtx;
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.
bool unmutatedMutated = false;
@@ -77,7 +77,7 @@ bool TestSequenceLocks(const CTransaction &tx, int flags)
// Implemented as an additional function, rather than a separate test case,
// to allow reusing the blockchain created in CreateNewBlock_validity.
// 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.
TestMemPoolEntryHelper entry;
@@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
// We can't make transactions until we have inputs
// Therefore, load 100 blocks :)
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)
{
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(chainActive.Height());
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)
baseheight = chainActive.Height();
if (txFirst.size() < 4)
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(pmt_test1)
for (unsigned int j=0; j<nTx; j++) {
CMutableTransaction tx;
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
@@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
CFeeRate baseRate(basefee, GetVirtualTransactionSize(tx));

// Create a fake block
std::vector<std::shared_ptr<const CTransaction>> block;
std::vector<CTransactionRef> block;
int blocknum = 0;

// Loop through 200 blocks
@@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// 9/10 blocks add 2nd highest and so on until ...
// 1/10 blocks add lowest fee transactions
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)
block.push_back(ptx);
txHashes[9-h].pop_back();
@@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
// Estimates should still not be below original
for (int j = 0; j < 10; j++) {
while(txHashes[j].size()) {
std::shared_ptr<const CTransaction> ptx = mpool.get(txHashes[j].back());
CTransactionRef ptx = mpool.get(txHashes[j].back());
if (ptx)
block.push_back(ptx);
txHashes[j].pop_back();
@@ -163,7 +163,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
tx.vin[0].prevout.n = 10000*blocknum+100*j+k;
uint256 hash = tx.GetHash();
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)
block.push_back(ptx);

@@ -119,7 +119,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
// Replace mempool-selected txns with just coinbase plus passed-in txns:
block.vtx.resize(1);
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
unsigned int extraNonce = 0;
IncrementExtraNonce(&block, chainActive.Tip(), extraNonce);

0 comments on commit b4e4ba4

Please sign in to comment.
You can’t perform that action at this time.