20#include <boost/test/unit_test.hpp>
31 return m_orphans.size();
36 std::map<Wtxid, OrphanTx>::iterator it;
38 if (it == m_orphans.end())
39 it = m_orphans.begin();
48 std::vector<unsigned char> keydata;
50 key.
Set(keydata.data(), keydata.data() + keydata.size(),
true);
61 if (outpoints.empty()) {
64 for (
const auto& outpoint : outpoints) {
65 tx.
vin.emplace_back(outpoint);
69 tx.
vin[0].scriptWitness.stack.push_back({1});
82 tx.
vin[0].scriptWitness.stack.push_back({5});
84 assert(ptx->GetHash() == mutated_tx->GetHash());
88static bool EqualTxns(
const std::set<CTransactionRef>& set_txns,
const std::vector<CTransactionRef>& vec_txns)
90 if (vec_txns.size() != set_txns.size())
return false;
91 for (
const auto& tx : vec_txns) {
92 if (!set_txns.contains(tx))
return false;
114 auto now{GetTime<std::chrono::seconds>()};
118 for (
int i = 0; i < 50; i++)
122 tx.
vin[0].prevout.n = 0;
133 for (
int i = 0; i < 50; i++)
139 tx.
vin[0].prevout.n = 0;
140 tx.
vin[0].prevout.hash = txPrev->GetHash();
151 for (
int i = 0; i < 10; i++)
160 for (
unsigned int j = 0; j < tx.
vin.size(); j++)
162 tx.
vin[j].prevout.n = j;
163 tx.
vin[j].prevout.hash = txPrev->GetHash();
169 for (
unsigned int j = 1; j < tx.
vin.size(); j++)
170 tx.
vin[j].scriptSig = tx.
vin[0].scriptSig;
175 size_t expected_num_orphans = orphanage.CountOrphans();
178 orphanage.EraseForPeer(-1);
183 for (
NodeId i = 0; i < 3; i++)
185 orphanage.EraseForPeer(i);
186 expected_num_orphans -= 2;
187 BOOST_CHECK(orphanage.CountOrphans() == expected_num_orphans);
192 orphanage.LimitOrphans(expected_num_orphans, rng);
194 expected_num_orphans -= 1;
195 orphanage.LimitOrphans(expected_num_orphans, rng);
197 assert(expected_num_orphans > 40);
198 orphanage.LimitOrphans(40, rng);
200 orphanage.LimitOrphans(10, rng);
202 orphanage.LimitOrphans(0, rng);
207 orphanage.AddTx(timeout_tx, 0);
208 orphanage.LimitOrphans(1, rng);
213 orphanage.LimitOrphans(1, rng);
219 orphanage.LimitOrphans(1, rng);
229 std::vector<COutPoint> empty_outpoints;
236 const auto& normal_wtxid = child_normal->GetWitnessHash();
237 const auto& mutated_wtxid = child_mutated->GetWitnessHash();
254 std::set<CTransactionRef> expected_children{child_normal, child_mutated};
271 std::vector<COutPoint> empty_outpoints;
277 while (parent1->GetHash() == parent2->GetHash()) {
300 std::set<CTransactionRef> expected_parent1_children{child_p1n0, child_p1n0_p2n0, child_p1n0_p1n1};
301 std::set<CTransactionRef> expected_parent2_children{child_p2n1, child_p1n0_p2n0};
332 std::set<CTransactionRef> expected_parent1_node1{child_p1n0};
339 std::set<CTransactionRef> expected_parent2_node1{child_p2n1};
346 std::set<CTransactionRef> expected_parent1_node2{child_p1n0_p1n1, child_p1n0_p2n0};
353 std::set<CTransactionRef> expected_parent2_node2{child_p1n0_p2n0};
383 std::vector<COutPoint> outpoints;
384 const uint32_t num_outpoints{6};
385 outpoints.reserve(num_outpoints);
386 for (uint32_t i{0}; i < num_outpoints; ++i) {
399 block.
vtx.emplace_back(bo_tx_same_txid);
403 block.
vtx.emplace_back(b_tx_same_txid_diff_witness);
405 auto o_tx_same_txid_diff_witness =
MakeMutation(b_tx_same_txid_diff_witness);
410 block.
vtx.emplace_back(b_tx_conflict);
417 block.
vtx.emplace_back(b_tx_conflict_partial);
422 orphanage.EraseForBlock(block);
423 for (
const auto& expected_removed : {bo_tx_same_txid, o_tx_same_txid_diff_witness, o_tx_conflict, o_tx_conflict_partial_2}) {
424 const auto& expected_removed_wtxid = expected_removed->GetWitnessHash();
425 BOOST_CHECK(!orphanage.HaveTx(expected_removed_wtxid));
429 BOOST_CHECK(orphanage.HaveTx(control_tx->GetWitnessHash()));
437 size_t expected_total_count{0};
445 const auto& wtxid = ptx->GetWitnessHash();
448 expected_total_count += 1;
458 BOOST_CHECK(orphanage.HaveTx(ptx_mutated->GetWitnessHash()));
459 expected_total_count += 1;
464 BOOST_CHECK(orphanage.AddAnnouncer(ptx->GetWitnessHash(), node2));
468 BOOST_CHECK(orphanage.HaveTxFromPeer(ptx->GetWitnessHash(), node2));
469 BOOST_CHECK(!orphanage.AddAnnouncer(ptx->GetWitnessHash(), node2));
477 orphanage.EraseForPeer(node0);
478 BOOST_CHECK(orphanage.HaveTx(ptx->GetWitnessHash()));
479 BOOST_CHECK(!orphanage.HaveTxFromPeer(ptx->GetWitnessHash(), node0));
481 BOOST_CHECK(!orphanage.HaveTx(ptx_mutated->GetWitnessHash()));
482 expected_total_count -= 1;
486 orphanage.EraseForPeer(node1);
488 BOOST_CHECK(orphanage.HaveTx(ptx->GetWitnessHash()));
489 orphanage.EraseForPeer(node2);
490 expected_total_count -= 1;
492 BOOST_CHECK(!orphanage.HaveTx(ptx->GetWitnessHash()));
499 block.
vtx.emplace_back(tx_block);
503 expected_total_count += 1;
507 orphanage.EraseForBlock(block);
509 expected_total_count -= 1;
525 const auto& orphan_wtxid = tx_orphan->GetWitnessHash();
530 BOOST_CHECK(orphanage.AddAnnouncer(orphan_wtxid, node2));
536 orphanage.AddChildrenToWorkSet(*tx_missing_parent);
542 orphanage.EraseForPeer(node0);
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::vector< CTransactionRef > vtx
An encapsulated private key.
bool IsValid() const
Check whether this private key is valid.
CPubKey GetPubKey() const
Compute the public key from a private key.
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
An outpoint - a combination of a transaction hash and an index n into its vout.
The basic transaction that is broadcasted on the network and contained in blocks.
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddKey(const CKey &key)
uint256 rand256() noexcept
generate a random uint256.
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
A class to track orphan transactions (failed on TX_MISSING_INPUTS) Since we cannot distinguish orphan...
bool AddTx(const CTransactionRef &tx, NodeId peer)
Add a new orphan transaction.
int EraseTx(const Wtxid &wtxid)
Erase an orphan by wtxid.
CTransactionRef GetTx(const Wtxid &wtxid) const
std::vector< CTransactionRef > GetChildrenFromSamePeer(const CTransactionRef &parent, NodeId nodeid) const
Get all children that spend from this tx and were received from nodeid.
bool HaveTx(const Wtxid &wtxid) const
Check if we already have an orphan transaction (by wtxid only)
FastRandomContext & m_rng
size_t CountOrphans() const
CTransactionRef RandomOrphan()
TxOrphanageTest(FastRandomContext &rng)
static transaction_identifier FromUint256(const uint256 &id)
static int32_t GetTransactionWeight(const CTransaction &tx)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static CTransactionRef MakeMutation(const CTransactionRef &ptx)
static void MakeNewKeyWithFastRandomContext(CKey &key, FastRandomContext &rand_ctx)
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
static CTransactionRef MakeTransactionSpending(const std::vector< COutPoint > &outpoints, FastRandomContext &det_rand)
static bool EqualTxns(const std::set< CTransactionRef > &set_txns, const std::vector< CTransactionRef > &vec_txns)
static constexpr int32_t MAX_STANDARD_TX_WEIGHT
The maximum weight for transactions we're willing to relay/mine.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr CAmount CENT
A mutable version of CTransaction.
std::vector< CTxOut > vout
Testing setup that configures a complete environment.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
void BulkTransaction(CMutableTransaction &tx, int32_t target_weight)
bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType, SignatureData &sig_data)
Produce a satisfying script (scriptSig or witness).
static constexpr auto ORPHAN_TX_EXPIRE_TIME
Expiration time for orphan transactions.