Branch data Line data Source code
1 : : // Copyright (c) 2025-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #include <primitives/transaction.h>
6 : : #include <private_broadcast.h>
7 : : #include <test/util/setup_common.h>
8 : : #include <util/time.h>
9 : :
10 : : #include <boost/test/unit_test.hpp>
11 : :
12 : : BOOST_FIXTURE_TEST_SUITE(private_broadcast_tests, BasicTestingSetup)
13 : :
14 : 2 : static CTransactionRef MakeDummyTx(uint32_t id, size_t num_witness)
15 : : {
16 : 2 : CMutableTransaction mtx;
17 [ + - ]: 2 : mtx.vin.resize(1);
18 [ + + ]: 2 : mtx.vin[0].nSequence = id;
19 [ + + ]: 2 : if (num_witness > 0) {
20 : 1 : mtx.vin[0].scriptWitness = CScriptWitness{};
21 [ + - ]: 1 : mtx.vin[0].scriptWitness.stack.resize(num_witness);
22 : : }
23 [ + - ]: 4 : return MakeTransactionRef(mtx);
24 : 2 : }
25 : :
26 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(basic)
+ - + - -
+ + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- + - + -
+ - + - +
- + - - +
+ - + - +
- + - + -
+ - - + +
- ]
27 : : {
28 : 1 : SetMockTime(Now<NodeSeconds>());
29 : :
30 [ + - + - ]: 2 : PrivateBroadcast pb;
31 : 1 : const NodeId recipient1{1};
32 : :
33 : : // No transactions initially.
34 [ + - + - : 2 : BOOST_CHECK(!pb.PickTxForSend(/*will_send_to_nodeid=*/recipient1).has_value());
+ - + - ]
35 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetStale().size(), 0);
+ - ]
36 [ + - + - : 2 : BOOST_CHECK(!pb.HavePendingTransactions());
+ - + - ]
37 : :
38 : : // Make a transaction and add it.
39 [ + - ]: 1 : const auto tx1{MakeDummyTx(/*id=*/1, /*num_witness=*/0)};
40 : :
41 [ + - + - : 2 : BOOST_CHECK(pb.Add(tx1));
+ - + - ]
42 [ + - + - : 2 : BOOST_CHECK(!pb.Add(tx1));
+ - + - ]
43 : :
44 : : // Make another transaction with same txid, different wtxid and add it.
45 [ + - ]: 1 : const auto tx2{MakeDummyTx(/*id=*/1, /*num_witness=*/1)};
46 [ + - + - : 2 : BOOST_REQUIRE(tx1->GetHash() == tx2->GetHash());
+ - ]
47 [ + - + - : 2 : BOOST_REQUIRE(tx1->GetWitnessHash() != tx2->GetWitnessHash());
+ - ]
48 : :
49 [ + - + - : 2 : BOOST_CHECK(pb.Add(tx2));
+ - + - ]
50 : :
51 [ + - ]: 2 : const auto tx_for_recipient1{pb.PickTxForSend(/*will_send_to_nodeid=*/recipient1).value()};
52 [ + - + - : 3 : BOOST_CHECK(tx_for_recipient1 == tx1 || tx_for_recipient1 == tx2);
+ - + - +
- ]
53 : :
54 : : // A second pick must return the other transaction.
55 : 1 : const NodeId recipient2{2};
56 [ + - ]: 2 : const auto tx_for_recipient2{pb.PickTxForSend(/*will_send_to_nodeid=*/recipient2).value()};
57 [ + - - + : 2 : BOOST_CHECK(tx_for_recipient2 == tx1 || tx_for_recipient2 == tx2);
- - + - +
- ]
58 [ + - + - ]: 1 : BOOST_CHECK_NE(tx_for_recipient1, tx_for_recipient2);
59 : :
60 : 1 : const NodeId nonexistent_recipient{0};
61 : :
62 : : // Confirm transactions <-> recipients mapping is correct.
63 [ + - + - : 2 : BOOST_CHECK(!pb.GetTxForNode(nonexistent_recipient).has_value());
+ - + - ]
64 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetTxForNode(recipient1).value(), tx_for_recipient1);
+ - ]
65 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetTxForNode(recipient2).value(), tx_for_recipient2);
+ - ]
66 : :
67 : : // Confirm none of the transactions' reception have been confirmed.
68 [ + - + - : 2 : BOOST_CHECK(!pb.DidNodeConfirmReception(recipient1));
+ - + - ]
69 [ + - + - : 2 : BOOST_CHECK(!pb.DidNodeConfirmReception(recipient2));
+ - + - ]
70 [ + - + - : 2 : BOOST_CHECK(!pb.DidNodeConfirmReception(nonexistent_recipient));
+ - + - ]
71 : :
72 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetStale().size(), 2);
+ - ]
73 : :
74 : : // Confirm reception by recipient1.
75 [ + - ]: 1 : pb.NodeConfirmedReception(nonexistent_recipient); // Dummy call.
76 [ + - ]: 1 : pb.NodeConfirmedReception(recipient1);
77 : :
78 [ + - + - : 2 : BOOST_CHECK(pb.DidNodeConfirmReception(recipient1));
+ - + - ]
79 [ + - + - : 2 : BOOST_CHECK(!pb.DidNodeConfirmReception(recipient2));
+ - + - ]
80 : :
81 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetStale().size(), 1);
+ - ]
82 [ + - + - : 1 : BOOST_CHECK_EQUAL(pb.GetStale()[0], tx_for_recipient2);
+ - ]
83 : :
84 [ + - ]: 1 : SetMockTime(Now<NodeSeconds>() + 10h);
85 : :
86 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.GetStale().size(), 2);
+ - ]
87 : :
88 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.Remove(tx_for_recipient1).value(), 1);
+ - ]
89 [ + - + - : 2 : BOOST_CHECK(!pb.Remove(tx_for_recipient1).has_value());
+ - + - ]
90 [ + - + - : 2 : BOOST_CHECK_EQUAL(pb.Remove(tx_for_recipient2).value(), 0);
+ - ]
91 [ + - + - : 2 : BOOST_CHECK(!pb.Remove(tx_for_recipient2).has_value());
+ - + - ]
92 : :
93 [ + - + - : 2 : BOOST_CHECK(!pb.PickTxForSend(/*will_send_to_nodeid=*/nonexistent_recipient).has_value());
+ - + - ]
94 [ + - + - : 4 : }
+ - ]
95 : :
96 : : BOOST_AUTO_TEST_SUITE_END()
|