17 #include <boost/test/unit_test.hpp>
27 return m_orphans.size();
33 std::map<Wtxid, OrphanTx>::iterator it;
35 if (it == m_orphans.end())
36 it = m_orphans.begin();
43 std::vector<unsigned char> keydata;
44 keydata = rand_ctx.randbytes(32);
45 key.
Set(keydata.data(), keydata.data() + keydata.size(),
true);
56 if (outpoints.empty()) {
59 for (
const auto& outpoint : outpoints) {
60 tx.
vin.emplace_back(outpoint);
64 tx.
vin[0].scriptWitness.stack.push_back({1});
77 tx.
vin[0].scriptWitness.stack.push_back({5});
79 assert(ptx->GetHash() == mutated_tx->GetHash());
83 static bool EqualTxns(
const std::set<CTransactionRef>& set_txns,
const std::vector<CTransactionRef>& vec_txns)
85 if (vec_txns.size() != set_txns.size())
return false;
86 for (
const auto& tx : vec_txns) {
87 if (!set_txns.contains(tx))
return false;
91 static bool EqualTxns(
const std::set<CTransactionRef>& set_txns,
92 const std::vector<std::pair<CTransactionRef, NodeId>>& vec_txns)
94 if (vec_txns.size() != set_txns.size())
return false;
95 for (
const auto& [tx, nodeid] : vec_txns) {
96 if (!set_txns.contains(tx))
return false;
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;
176 for (
NodeId i = 0; i < 3; i++)
199 std::vector<COutPoint> empty_outpoints;
206 const auto& normal_wtxid = child_normal->GetWitnessHash();
207 const auto& mutated_wtxid = child_mutated->GetWitnessHash();
222 std::set<CTransactionRef> expected_children{child_normal, child_mutated};
239 std::vector<COutPoint> empty_outpoints;
245 while (parent1->GetHash() == parent2->GetHash()) {
268 std::set<CTransactionRef> expected_parent1_children{child_p1n0, child_p1n0_p2n0, child_p1n0_p1n1};
269 std::set<CTransactionRef> expected_parent2_children{child_p2n1, child_p1n0_p2n0};
305 std::set<CTransactionRef> expected_parent1_node1{child_p1n0};
313 std::set<CTransactionRef> expected_parent2_node1{child_p2n1};
321 std::set<CTransactionRef> expected_parent1_node2{child_p1n0_p1n1, child_p1n0_p2n0};
329 std::set<CTransactionRef> expected_parent2_node2{child_p1n0_p2n0};
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
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.
uint256 rand256() noexcept
generate a random uint256.
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddKey(const CKey &key)
A class to track orphan transactions (failed on TX_MISSING_INPUTS) Since we cannot distinguish orphan...
void LimitOrphans(unsigned int max_orphans, FastRandomContext &rng) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Limit the orphanage to the given maximum.
bool AddTx(const CTransactionRef &tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Add a new orphan transaction.
std::vector< std::pair< CTransactionRef, NodeId > > GetChildrenFromDifferentPeer(const CTransactionRef &parent, NodeId nodeid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get all children that spend from this tx but were not received from nodeid.
bool HaveTx(const Wtxid &wtxid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Check if we already have an orphan transaction (by wtxid only)
void EraseForPeer(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Erase all orphans announced by a peer (eg, after that peer disconnects)
std::vector< CTransactionRef > GetChildrenFromSamePeer(const CTransactionRef &parent, NodeId nodeid) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get all children that spend from this tx and were received from nodeid.
int EraseTx(const Wtxid &wtxid) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Erase an orphan by wtxid.
size_t CountOrphans() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
CTransactionRef RandomOrphan() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
static transaction_identifier FromUint256(const uint256 &id)
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static CTransactionRef MakeMutation(const CTransactionRef &ptx)
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
static void MakeNewKeyWithFastRandomContext(CKey &key, FastRandomContext &rand_ctx=g_insecure_rand_ctx)
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 CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
static constexpr CAmount CENT
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).
A mutable version of CTransaction.
std::vector< CTxOut > vout
Testing setup that configures a complete environment.
FastRandomContext g_insecure_rand_ctx
This global and the helpers that use it are not thread-safe.
static uint256 InsecureRand256()
#define EXCLUSIVE_LOCKS_REQUIRED(...)