Skip to content

Commit 869781c

Browse files
committed
Merge #9283: A few more CTransactionRef optimizations
91335ba Remove unused MakeTransactionRef overloads (Pieter Wuille) 6713f0f Make FillBlock consume txn_available to avoid shared_ptr copies (Pieter Wuille) 62607d7 Convert COrphanTx to keep a CTransactionRef (Pieter Wuille) c44e4c4 Make AcceptToMemoryPool take CTransactionRef (Pieter Wuille)
2 parents d9ae1ce + 91335ba commit 869781c

15 files changed

+95
-72
lines changed

src/bench/mempool_eviction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static void AddTx(const CTransaction& tx, const CAmount& nFee, CTxMemPool& pool)
1818
unsigned int sigOpCost = 4;
1919
LockPoints lp;
2020
pool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(
21-
tx, nFee, nTime, dPriority, nHeight, pool.HasNoInputsOf(tx),
21+
MakeTransactionRef(tx), nFee, nTime, dPriority, nHeight, pool.HasNoInputsOf(tx),
2222
tx.GetValueOut(), spendsCoinbase, sigOpCost, lp));
2323
}
2424

src/blockencodings.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,9 @@ bool PartiallyDownloadedBlock::IsTxAvailable(size_t index) const {
142142
return txn_available[index] ? true : false;
143143
}
144144

145-
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) const {
145+
ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) {
146146
assert(!header.IsNull());
147+
uint256 hash = header.GetHash();
147148
block = header;
148149
block.vtx.resize(txn_available.size());
149150

@@ -154,8 +155,13 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<
154155
return READ_STATUS_INVALID;
155156
block.vtx[i] = vtx_missing[tx_missing_offset++];
156157
} else
157-
block.vtx[i] = txn_available[i];
158+
block.vtx[i] = std::move(txn_available[i]);
158159
}
160+
161+
// Make sure we can't call FillBlock again.
162+
header.SetNull();
163+
txn_available.clear();
164+
159165
if (vtx_missing.size() != tx_missing_offset)
160166
return READ_STATUS_INVALID;
161167

@@ -170,10 +176,10 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector<
170176
return READ_STATUS_CHECKBLOCK_FAILED;
171177
}
172178

173-
LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", header.GetHash().ToString(), prefilled_count, mempool_count, vtx_missing.size());
179+
LogPrint("cmpctblock", "Successfully reconstructed block %s with %lu txn prefilled, %lu txn from mempool and %lu txn requested\n", hash.ToString(), prefilled_count, mempool_count, vtx_missing.size());
174180
if (vtx_missing.size() < 5) {
175181
for (const auto& tx : vtx_missing)
176-
LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", header.GetHash().ToString(), tx->GetHash().ToString());
182+
LogPrint("cmpctblock", "Reconstructed block %s required tx %s\n", hash.ToString(), tx->GetHash().ToString());
177183
}
178184

179185
return READ_STATUS_OK;

src/blockencodings.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class PartiallyDownloadedBlock {
202202

203203
ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock);
204204
bool IsTxAvailable(size_t index) const;
205-
ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing) const;
205+
ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing);
206206
};
207207

208208
#endif

src/net_processing.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct IteratorComparator
5151

5252
struct COrphanTx {
5353
// When modifying, adapt the copy of this definition in tests/DoS_tests.
54-
CTransaction tx;
54+
CTransactionRef tx;
5555
NodeId fromPeer;
5656
int64_t nTimeExpire;
5757
};
@@ -586,9 +586,9 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals)
586586
// mapOrphanTransactions
587587
//
588588

589-
bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
589+
bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
590590
{
591-
uint256 hash = tx.GetHash();
591+
const uint256& hash = tx->GetHash();
592592
if (mapOrphanTransactions.count(hash))
593593
return false;
594594

@@ -599,7 +599,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c
599599
// have been mined or received.
600600
// 100 orphans, each of which is at most 99,999 bytes big is
601601
// at most 10 megabytes of orphans and somewhat more byprev index (in the worst case):
602-
unsigned int sz = GetTransactionWeight(tx);
602+
unsigned int sz = GetTransactionWeight(*tx);
603603
if (sz >= MAX_STANDARD_TX_WEIGHT)
604604
{
605605
LogPrint("mempool", "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
@@ -608,7 +608,7 @@ bool AddOrphanTx(const CTransaction& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(c
608608

609609
auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME});
610610
assert(ret.second);
611-
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
611+
BOOST_FOREACH(const CTxIn& txin, tx->vin) {
612612
mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
613613
}
614614

@@ -622,7 +622,7 @@ int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
622622
map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
623623
if (it == mapOrphanTransactions.end())
624624
return 0;
625-
BOOST_FOREACH(const CTxIn& txin, it->second.tx.vin)
625+
BOOST_FOREACH(const CTxIn& txin, it->second.tx->vin)
626626
{
627627
auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
628628
if (itPrev == mapOrphanTransactionsByPrev.end())
@@ -644,7 +644,7 @@ void EraseOrphansFor(NodeId peer)
644644
map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
645645
if (maybeErase->second.fromPeer == peer)
646646
{
647-
nErased += EraseOrphanTx(maybeErase->second.tx.GetHash());
647+
nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
648648
}
649649
}
650650
if (nErased > 0) LogPrint("mempool", "Erased %d orphan tx from peer %d\n", nErased, peer);
@@ -665,7 +665,7 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans) EXCLUSIVE_LOCKS_REQUIRE
665665
{
666666
map<uint256, COrphanTx>::iterator maybeErase = iter++;
667667
if (maybeErase->second.nTimeExpire <= nNow) {
668-
nErased += EraseOrphanTx(maybeErase->second.tx.GetHash());
668+
nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
669669
} else {
670670
nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
671671
}
@@ -736,7 +736,7 @@ void PeerLogicValidation::SyncTransaction(const CTransaction& tx, const CBlockIn
736736
auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout);
737737
if (itByPrev == mapOrphanTransactionsByPrev.end()) continue;
738738
for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
739-
const CTransaction& orphanTx = (*mi)->second.tx;
739+
const CTransaction& orphanTx = *(*mi)->second.tx;
740740
const uint256& orphanHash = orphanTx.GetHash();
741741
vOrphanErase.push_back(orphanHash);
742742
}
@@ -1600,7 +1600,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
16001600

16011601
deque<COutPoint> vWorkQueue;
16021602
vector<uint256> vEraseQueue;
1603-
CTransaction tx(deserialize, vRecv);
1603+
CTransactionRef ptx;
1604+
vRecv >> ptx;
1605+
const CTransaction& tx = *ptx;
16041606

16051607
CInv inv(MSG_TX, tx.GetHash());
16061608
pfrom->AddInventoryKnown(inv);
@@ -1613,7 +1615,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
16131615
pfrom->setAskFor.erase(inv.hash);
16141616
mapAlreadyAskedFor.erase(inv.hash);
16151617

1616-
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) {
1618+
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs)) {
16171619
mempool.check(pcoinsTip);
16181620
RelayTransaction(tx, connman);
16191621
for (unsigned int i = 0; i < tx.vout.size(); i++) {
@@ -1638,7 +1640,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
16381640
mi != itByPrev->second.end();
16391641
++mi)
16401642
{
1641-
const CTransaction& orphanTx = (*mi)->second.tx;
1643+
const CTransactionRef& porphanTx = (*mi)->second.tx;
1644+
const CTransaction& orphanTx = *porphanTx;
16421645
const uint256& orphanHash = orphanTx.GetHash();
16431646
NodeId fromPeer = (*mi)->second.fromPeer;
16441647
bool fMissingInputs2 = false;
@@ -1650,7 +1653,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
16501653

16511654
if (setMisbehaving.count(fromPeer))
16521655
continue;
1653-
if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) {
1656+
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, true, &fMissingInputs2)) {
16541657
LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString());
16551658
RelayTransaction(orphanTx, connman);
16561659
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
@@ -1703,7 +1706,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
17031706
pfrom->AddInventoryKnown(_inv);
17041707
if (!AlreadyHave(_inv)) pfrom->AskFor(_inv);
17051708
}
1706-
AddOrphanTx(tx, pfrom->GetId());
1709+
AddOrphanTx(ptx, pfrom->GetId());
17071710

17081711
// DoS prevention: do not allow mapOrphanTransactions to grow unbounded
17091712
unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));

src/primitives/transaction.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,6 @@ struct CMutableTransaction
453453
typedef std::shared_ptr<const CTransaction> CTransactionRef;
454454
static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
455455
template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
456-
static inline CTransactionRef MakeTransactionRef(const CTransactionRef& txIn) { return txIn; }
457-
static inline CTransactionRef MakeTransactionRef(CTransactionRef&& txIn) { return std::move(txIn); }
458456

459457
/** Compute the weight of a transaction, as defined by BIP 141 */
460458
int64_t GetTransactionWeight(const CTransaction &tx);

src/rpc/rawtransaction.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,8 +883,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
883883
CMutableTransaction mtx;
884884
if (!DecodeHexTx(mtx, request.params[0].get_str()))
885885
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
886-
CTransaction tx(std::move(mtx));
887-
uint256 hashTx = tx.GetHash();
886+
CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
887+
const uint256& hashTx = tx->GetHash();
888888

889889
bool fLimitFree = false;
890890
CAmount nMaxRawTxFee = maxTxFee;
@@ -899,7 +899,7 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
899899
// push to local node and sync with wallets
900900
CValidationState state;
901901
bool fMissingInputs;
902-
if (!AcceptToMemoryPool(mempool, state, tx, fLimitFree, &fMissingInputs, false, nMaxRawTxFee)) {
902+
if (!AcceptToMemoryPool(mempool, state, std::move(tx), fLimitFree, &fMissingInputs, false, nMaxRawTxFee)) {
903903
if (state.IsInvalid()) {
904904
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
905905
} else {

src/test/DoS_tests.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@
2424
#include <boost/test/unit_test.hpp>
2525

2626
// Tests this internal-to-main.cpp method:
27-
extern bool AddOrphanTx(const CTransaction& tx, NodeId peer);
27+
extern bool AddOrphanTx(const CTransactionRef& tx, NodeId peer);
2828
extern void EraseOrphansFor(NodeId peer);
2929
extern unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans);
3030
struct COrphanTx {
31-
CTransaction tx;
31+
CTransactionRef tx;
3232
NodeId fromPeer;
3333
int64_t nTimeExpire;
3434
};
@@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
122122
BOOST_CHECK(!connman->IsBanned(addr));
123123
}
124124

125-
CTransaction RandomOrphan()
125+
CTransactionRef RandomOrphan()
126126
{
127127
std::map<uint256, COrphanTx>::iterator it;
128128
it = mapOrphanTransactions.lower_bound(GetRandHash());
@@ -150,30 +150,30 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
150150
tx.vout[0].nValue = 1*CENT;
151151
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
152152

153-
AddOrphanTx(tx, i);
153+
AddOrphanTx(MakeTransactionRef(tx), i);
154154
}
155155

156156
// ... and 50 that depend on other orphans:
157157
for (int i = 0; i < 50; i++)
158158
{
159-
CTransaction txPrev = RandomOrphan();
159+
CTransactionRef txPrev = RandomOrphan();
160160

161161
CMutableTransaction tx;
162162
tx.vin.resize(1);
163163
tx.vin[0].prevout.n = 0;
164-
tx.vin[0].prevout.hash = txPrev.GetHash();
164+
tx.vin[0].prevout.hash = txPrev->GetHash();
165165
tx.vout.resize(1);
166166
tx.vout[0].nValue = 1*CENT;
167167
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
168-
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
168+
SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
169169

170-
AddOrphanTx(tx, i);
170+
AddOrphanTx(MakeTransactionRef(tx), i);
171171
}
172172

173173
// This really-big orphan should be ignored:
174174
for (int i = 0; i < 10; i++)
175175
{
176-
CTransaction txPrev = RandomOrphan();
176+
CTransactionRef txPrev = RandomOrphan();
177177

178178
CMutableTransaction tx;
179179
tx.vout.resize(1);
@@ -183,15 +183,15 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
183183
for (unsigned int j = 0; j < tx.vin.size(); j++)
184184
{
185185
tx.vin[j].prevout.n = j;
186-
tx.vin[j].prevout.hash = txPrev.GetHash();
186+
tx.vin[j].prevout.hash = txPrev->GetHash();
187187
}
188-
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL);
188+
SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL);
189189
// Re-use same signature for other inputs
190190
// (they don't have to be valid for this test)
191191
for (unsigned int j = 1; j < tx.vin.size(); j++)
192192
tx.vin[j].scriptSig = tx.vin[0].scriptSig;
193193

194-
BOOST_CHECK(!AddOrphanTx(tx, i));
194+
BOOST_CHECK(!AddOrphanTx(MakeTransactionRef(tx), i));
195195
}
196196

197197
// Test EraseOrphansFor:

src/test/blockencodings_tests.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,23 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
8585
BOOST_CHECK_EQUAL(pool.size(), poolSize - 1);
8686

8787
CBlock block2;
88-
std::vector<CTransactionRef> vtx_missing;
89-
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
88+
{
89+
PartiallyDownloadedBlock tmp = partialBlock;
90+
BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions
91+
partialBlock = tmp;
92+
}
9093

91-
vtx_missing.push_back(block.vtx[2]); // Wrong transaction
92-
partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that
94+
// Wrong transaction
95+
{
96+
PartiallyDownloadedBlock tmp = partialBlock;
97+
partialBlock.FillBlock(block2, {block.vtx[2]}); // Current implementation doesn't check txn here, but don't require that
98+
partialBlock = tmp;
99+
}
93100
bool mutated;
94101
BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
95102

96-
vtx_missing[0] = block.vtx[1];
97103
CBlock block3;
98-
BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK);
104+
BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}) == READ_STATUS_OK);
99105
BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
100106
BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
101107
BOOST_CHECK(!mutated);
@@ -181,17 +187,24 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
181187
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
182188

183189
CBlock block2;
184-
std::vector<CTransactionRef> vtx_missing;
185-
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_INVALID); // No transactions
190+
{
191+
PartiallyDownloadedBlock tmp = partialBlock;
192+
BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions
193+
partialBlock = tmp;
194+
}
186195

187-
vtx_missing.push_back(block.vtx[1]); // Wrong transaction
188-
partialBlock.FillBlock(block2, vtx_missing); // Current implementation doesn't check txn here, but don't require that
196+
// Wrong transaction
197+
{
198+
PartiallyDownloadedBlock tmp = partialBlock;
199+
partialBlock.FillBlock(block2, {block.vtx[1]}); // Current implementation doesn't check txn here, but don't require that
200+
partialBlock = tmp;
201+
}
189202
bool mutated;
190203
BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
191204

192-
vtx_missing[0] = block.vtx[0];
193205
CBlock block3;
194-
BOOST_CHECK(partialBlock.FillBlock(block3, vtx_missing) == READ_STATUS_OK);
206+
PartiallyDownloadedBlock partialBlockCopy = partialBlock;
207+
BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}) == READ_STATUS_OK);
195208
BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
196209
BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
197210
BOOST_CHECK(!mutated);
@@ -200,7 +213,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
200213
block.vtx.clear();
201214
block2.vtx.clear();
202215
block3.vtx.clear();
203-
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
216+
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); // + 1 because of partialBlockCopy.
204217
}
205218
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
206219
}
@@ -240,8 +253,8 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
240253
BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
241254

242255
CBlock block2;
243-
std::vector<CTransactionRef> vtx_missing;
244-
BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
256+
PartiallyDownloadedBlock partialBlockCopy = partialBlock;
257+
BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_OK);
245258
BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
246259
bool mutated;
247260
BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
@@ -250,7 +263,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
250263
txhash = block.vtx[1]->GetHash();
251264
block.vtx.clear();
252265
block2.vtx.clear();
253-
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
266+
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); // + 1 because of partialBlockCopy.
254267
}
255268
BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
256269
}

src/test/test_bitcoin.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPo
151151
// Hack to assume either its completely dependent on other mempool txs or not at all
152152
CAmount inChainValue = hasNoDependencies ? txn.GetValueOut() : 0;
153153

154-
return CTxMemPoolEntry(txn, nFee, nTime, dPriority, nHeight,
154+
return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, dPriority, nHeight,
155155
hasNoDependencies, inChainValue, spendsCoinbase, sigOpCost, lp);
156156
}
157157

src/test/txvalidationcache_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ ToMemPool(CMutableTransaction& tx)
2323
LOCK(cs_main);
2424

2525
CValidationState state;
26-
return AcceptToMemoryPool(mempool, state, tx, false, NULL, true, 0);
26+
return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, NULL, true, 0);
2727
}
2828

2929
BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)

0 commit comments

Comments
 (0)