mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
[unit test] multiple orphan announcers
This commit is contained in:
parent
96c1a822a2
commit
22b023b09d
1 changed files with 126 additions and 0 deletions
|
@ -446,4 +446,130 @@ BOOST_AUTO_TEST_CASE(process_block)
|
|||
BOOST_CHECK_EQUAL(orphanage.Size(), 1);
|
||||
BOOST_CHECK(orphanage.HaveTx(control_tx->GetWitnessHash()));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(multiple_announcers)
|
||||
{
|
||||
const NodeId node0{0};
|
||||
const NodeId node1{1};
|
||||
const NodeId node2{2};
|
||||
size_t expected_total_count{0};
|
||||
FastRandomContext det_rand{true};
|
||||
TxOrphanageTest orphanage{det_rand};
|
||||
|
||||
// Check accounting per peer.
|
||||
// Check that EraseForPeer works with multiple announcers.
|
||||
{
|
||||
auto ptx = MakeTransactionSpending({}, det_rand);
|
||||
const auto& wtxid = ptx->GetWitnessHash();
|
||||
BOOST_CHECK(orphanage.AddTx(ptx, node0));
|
||||
BOOST_CHECK(orphanage.HaveTx(wtxid));
|
||||
expected_total_count += 1;
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
// Adding again should do nothing.
|
||||
BOOST_CHECK(!orphanage.AddTx(ptx, node0));
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
// We can add another tx with the same txid but different witness.
|
||||
auto ptx_mutated{MakeMutation(ptx)};
|
||||
BOOST_CHECK(orphanage.AddTx(ptx_mutated, node0));
|
||||
BOOST_CHECK(orphanage.HaveTx(ptx_mutated->GetWitnessHash()));
|
||||
expected_total_count += 1;
|
||||
|
||||
BOOST_CHECK(!orphanage.AddTx(ptx, node0));
|
||||
|
||||
// Adding a new announcer should not change overall accounting.
|
||||
BOOST_CHECK(orphanage.AddAnnouncer(ptx->GetWitnessHash(), node2));
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
// If we already have this announcer, AddAnnouncer returns false.
|
||||
BOOST_CHECK(orphanage.HaveTxFromPeer(ptx->GetWitnessHash(), node2));
|
||||
BOOST_CHECK(!orphanage.AddAnnouncer(ptx->GetWitnessHash(), node2));
|
||||
|
||||
// Same with using AddTx for an existing tx, which is equivalent to using AddAnnouncer
|
||||
BOOST_CHECK(!orphanage.AddTx(ptx, node1));
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
// if EraseForPeer is called for an orphan with multiple announcers, the orphanage should only
|
||||
// erase that peer from the announcers set.
|
||||
orphanage.EraseForPeer(node0);
|
||||
BOOST_CHECK(orphanage.HaveTx(ptx->GetWitnessHash()));
|
||||
BOOST_CHECK(!orphanage.HaveTxFromPeer(ptx->GetWitnessHash(), node0));
|
||||
// node0 is the only one that announced ptx_mutated
|
||||
BOOST_CHECK(!orphanage.HaveTx(ptx_mutated->GetWitnessHash()));
|
||||
expected_total_count -= 1;
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
// EraseForPeer should delete the orphan if it's the only announcer left.
|
||||
orphanage.EraseForPeer(node1);
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
BOOST_CHECK(orphanage.HaveTx(ptx->GetWitnessHash()));
|
||||
orphanage.EraseForPeer(node2);
|
||||
expected_total_count -= 1;
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
BOOST_CHECK(!orphanage.HaveTx(ptx->GetWitnessHash()));
|
||||
}
|
||||
|
||||
// Check that erasure for blocks removes for all peers.
|
||||
{
|
||||
CBlock block;
|
||||
auto tx_block = MakeTransactionSpending({}, det_rand);
|
||||
block.vtx.emplace_back(tx_block);
|
||||
BOOST_CHECK(orphanage.AddTx(tx_block, node0));
|
||||
BOOST_CHECK(!orphanage.AddTx(tx_block, node1));
|
||||
|
||||
expected_total_count += 1;
|
||||
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
|
||||
orphanage.EraseForBlock(block);
|
||||
|
||||
expected_total_count -= 1;
|
||||
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), expected_total_count);
|
||||
}
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(peer_worksets)
|
||||
{
|
||||
const NodeId node0{0};
|
||||
const NodeId node1{1};
|
||||
const NodeId node2{2};
|
||||
FastRandomContext det_rand{true};
|
||||
TxOrphanageTest orphanage{det_rand};
|
||||
// AddChildrenToWorkSet should pick an announcer randomly
|
||||
{
|
||||
auto tx_missing_parent = MakeTransactionSpending({}, det_rand);
|
||||
auto tx_orphan = MakeTransactionSpending({COutPoint{tx_missing_parent->GetHash(), 0}}, det_rand);
|
||||
const auto& orphan_wtxid = tx_orphan->GetWitnessHash();
|
||||
|
||||
// All 3 peers are announcers.
|
||||
BOOST_CHECK(orphanage.AddTx(tx_orphan, node0));
|
||||
BOOST_CHECK(!orphanage.AddTx(tx_orphan, node1));
|
||||
BOOST_CHECK(orphanage.AddAnnouncer(orphan_wtxid, node2));
|
||||
for (NodeId node = node0; node <= node2; ++node) {
|
||||
BOOST_CHECK(orphanage.HaveTxFromPeer(orphan_wtxid, node));
|
||||
}
|
||||
|
||||
// Parent accepted: add child to all 3 worksets.
|
||||
orphanage.AddChildrenToWorkSet(*tx_missing_parent);
|
||||
BOOST_CHECK_EQUAL(orphanage.GetTxToReconsider(node0), tx_orphan);
|
||||
BOOST_CHECK_EQUAL(orphanage.GetTxToReconsider(node1), tx_orphan);
|
||||
// Don't call GetTxToReconsider(node2) yet because it mutates the workset.
|
||||
|
||||
// EraseForPeer also removes that tx from the workset.
|
||||
orphanage.EraseForPeer(node0);
|
||||
BOOST_CHECK_EQUAL(orphanage.GetTxToReconsider(node0), nullptr);
|
||||
|
||||
// However, the other peers' worksets are not touched.
|
||||
BOOST_CHECK_EQUAL(orphanage.GetTxToReconsider(node2), tx_orphan);
|
||||
|
||||
// Delete this tx, clearing the orphanage.
|
||||
BOOST_CHECK_EQUAL(orphanage.EraseTx(orphan_wtxid), 1);
|
||||
BOOST_CHECK_EQUAL(orphanage.Size(), 0);
|
||||
for (NodeId node = node0; node <= node2; ++node) {
|
||||
BOOST_CHECK_EQUAL(orphanage.GetTxToReconsider(node), nullptr);
|
||||
BOOST_CHECK(!orphanage.HaveTxFromPeer(orphan_wtxid, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Reference in a new issue