aboutsummaryrefslogtreecommitdiff
path: root/src/test/blockencodings_tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/blockencodings_tests.cpp')
-rw-r--r--src/test/blockencodings_tests.cpp102
1 files changed, 77 insertions, 25 deletions
diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp
index 05355fb21d..b0749c851c 100644
--- a/src/test/blockencodings_tests.cpp
+++ b/src/test/blockencodings_tests.cpp
@@ -14,31 +14,36 @@
#include <boost/test/unit_test.hpp>
-std::vector<CTransactionRef> extra_txn;
+const std::vector<CTransactionRef> empty_extra_txn;
BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegTestingSetup)
-static CBlock BuildBlockTestCase() {
- CBlock block;
+static CMutableTransaction BuildTransactionTestCase() {
CMutableTransaction tx;
tx.vin.resize(1);
tx.vin[0].scriptSig.resize(10);
tx.vout.resize(1);
tx.vout[0].nValue = 42;
+ return tx;
+}
+
+static CBlock BuildBlockTestCase(FastRandomContext& ctx) {
+ CBlock block;
+ CMutableTransaction tx = BuildTransactionTestCase();
block.vtx.resize(3);
block.vtx[0] = MakeTransactionRef(tx);
block.nVersion = 42;
- block.hashPrevBlock = InsecureRand256();
+ block.hashPrevBlock = ctx.rand256();
block.nBits = 0x207fffff;
- tx.vin[0].prevout.hash = Txid::FromUint256(InsecureRand256());
+ tx.vin[0].prevout.hash = Txid::FromUint256(ctx.rand256());
tx.vin[0].prevout.n = 0;
block.vtx[1] = MakeTransactionRef(tx);
tx.vin.resize(10);
for (size_t i = 0; i < tx.vin.size(); i++) {
- tx.vin[i].prevout.hash = Txid::FromUint256(InsecureRand256());
+ tx.vin[i].prevout.hash = Txid::FromUint256(ctx.rand256());
tx.vin[i].prevout.n = 0;
}
block.vtx[2] = MakeTransactionRef(tx);
@@ -58,7 +63,8 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
{
CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
- CBlock block(BuildBlockTestCase());
+ auto rand_ctx(FastRandomContext(uint256{42}));
+ CBlock block(BuildBlockTestCase(rand_ctx));
LOCK2(cs_main, pool.cs);
pool.addUnchecked(entry.FromTx(block.vtx[2]));
@@ -66,7 +72,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
// Do a simple ShortTxIDs RT
{
- CBlockHeaderAndShortTxIDs shortIDs{block};
+ CBlockHeaderAndShortTxIDs shortIDs{block, rand_ctx.rand64()};
DataStream stream{};
stream << shortIDs;
@@ -75,7 +81,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
stream >> shortIDs2;
PartiallyDownloadedBlock partialBlock(&pool);
- BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
BOOST_CHECK( partialBlock.IsTxAvailable(0));
BOOST_CHECK(!partialBlock.IsTxAvailable(1));
BOOST_CHECK( partialBlock.IsTxAvailable(2));
@@ -123,8 +129,8 @@ public:
stream << orig;
stream >> *this;
}
- explicit TestHeaderAndShortIDs(const CBlock& block) :
- TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs{block}) {}
+ explicit TestHeaderAndShortIDs(const CBlock& block, FastRandomContext& ctx) :
+ TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs{block, ctx.rand64()}) {}
uint64_t GetShortID(const Wtxid& txhash) const {
DataStream stream{};
@@ -141,7 +147,8 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
{
CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
- CBlock block(BuildBlockTestCase());
+ auto rand_ctx(FastRandomContext(uint256{42}));
+ CBlock block(BuildBlockTestCase(rand_ctx));
LOCK2(cs_main, pool.cs);
pool.addUnchecked(entry.FromTx(block.vtx[2]));
@@ -151,7 +158,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
// Test with pre-forwarding tx 1, but not coinbase
{
- TestHeaderAndShortIDs shortIDs(block);
+ TestHeaderAndShortIDs shortIDs(block, rand_ctx);
shortIDs.prefilledtxn.resize(1);
shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
shortIDs.shorttxids.resize(2);
@@ -165,7 +172,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
stream >> shortIDs2;
PartiallyDownloadedBlock partialBlock(&pool);
- BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
BOOST_CHECK(!partialBlock.IsTxAvailable(0));
BOOST_CHECK( partialBlock.IsTxAvailable(1));
BOOST_CHECK( partialBlock.IsTxAvailable(2));
@@ -211,7 +218,8 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
{
CTxMemPool& pool = *Assert(m_node.mempool);
TestMemPoolEntryHelper entry;
- CBlock block(BuildBlockTestCase());
+ auto rand_ctx(FastRandomContext(uint256{42}));
+ CBlock block(BuildBlockTestCase(rand_ctx));
LOCK2(cs_main, pool.cs);
pool.addUnchecked(entry.FromTx(block.vtx[1]));
@@ -221,7 +229,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
// Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool
{
- TestHeaderAndShortIDs shortIDs(block);
+ TestHeaderAndShortIDs shortIDs(block, rand_ctx);
shortIDs.prefilledtxn.resize(2);
shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
@@ -235,7 +243,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
stream >> shortIDs2;
PartiallyDownloadedBlock partialBlock(&pool);
- BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
BOOST_CHECK( partialBlock.IsTxAvailable(0));
BOOST_CHECK( partialBlock.IsTxAvailable(1));
BOOST_CHECK( partialBlock.IsTxAvailable(2));
@@ -261,17 +269,14 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
{
CTxMemPool& pool = *Assert(m_node.mempool);
- CMutableTransaction coinbase;
- coinbase.vin.resize(1);
- coinbase.vin[0].scriptSig.resize(10);
- coinbase.vout.resize(1);
- coinbase.vout[0].nValue = 42;
+ CMutableTransaction coinbase = BuildTransactionTestCase();
CBlock block;
+ auto rand_ctx(FastRandomContext(uint256{42}));
block.vtx.resize(1);
block.vtx[0] = MakeTransactionRef(std::move(coinbase));
block.nVersion = 42;
- block.hashPrevBlock = InsecureRand256();
+ block.hashPrevBlock = rand_ctx.rand256();
block.nBits = 0x207fffff;
bool mutated;
@@ -281,7 +286,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
// Test simple header round-trip with only coinbase
{
- CBlockHeaderAndShortTxIDs shortIDs{block};
+ CBlockHeaderAndShortTxIDs shortIDs{block, rand_ctx.rand64()};
DataStream stream{};
stream << shortIDs;
@@ -290,7 +295,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
stream >> shortIDs2;
PartiallyDownloadedBlock partialBlock(&pool);
- BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
BOOST_CHECK(partialBlock.IsTxAvailable(0));
CBlock block2;
@@ -302,6 +307,53 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
}
}
+BOOST_AUTO_TEST_CASE(ReceiveWithExtraTransactions) {
+ CTxMemPool& pool = *Assert(m_node.mempool);
+ TestMemPoolEntryHelper entry;
+ auto rand_ctx(FastRandomContext(uint256{42}));
+
+ CMutableTransaction mtx = BuildTransactionTestCase();
+ mtx.vin[0].prevout.hash = Txid::FromUint256(rand_ctx.rand256());
+ mtx.vin[0].prevout.n = 0;
+ const CTransactionRef non_block_tx = MakeTransactionRef(std::move(mtx));
+
+ CBlock block(BuildBlockTestCase(rand_ctx));
+ std::vector<CTransactionRef> extra_txn;
+ extra_txn.resize(10);
+
+ LOCK2(cs_main, pool.cs);
+ pool.addUnchecked(entry.FromTx(block.vtx[2]));
+ BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
+ // Ensure the non_block_tx is actually not in the block
+ for (const auto &block_tx : block.vtx) {
+ BOOST_CHECK_NE(block_tx->GetHash(), non_block_tx->GetHash());
+ }
+ // Ensure block.vtx[1] is not in pool
+ BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()), nullptr);
+
+ {
+ const CBlockHeaderAndShortTxIDs cmpctblock{block, rand_ctx.rand64()};
+ PartiallyDownloadedBlock partial_block(&pool);
+ PartiallyDownloadedBlock partial_block_with_extra(&pool);
+
+ BOOST_CHECK(partial_block.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK( partial_block.IsTxAvailable(0));
+ BOOST_CHECK(!partial_block.IsTxAvailable(1));
+ BOOST_CHECK( partial_block.IsTxAvailable(2));
+
+ // Add an unrelated tx to extra_txn:
+ extra_txn[0] = non_block_tx;
+ // and a tx from the block that's not in the mempool:
+ extra_txn[1] = block.vtx[1];
+
+ BOOST_CHECK(partial_block_with_extra.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
+ BOOST_CHECK(partial_block_with_extra.IsTxAvailable(0));
+ // This transaction is now available via extra_txn:
+ BOOST_CHECK(partial_block_with_extra.IsTxAvailable(1));
+ BOOST_CHECK(partial_block_with_extra.IsTxAvailable(2));
+ }
+}
+
BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
BlockTransactionsRequest req1;
req1.blockhash = InsecureRand256();