40 std::vector<COutPoint> outpoints;
41 outpoints.reserve(200'000);
44 for (uint8_t i = 0; i < 4; i++) {
50 std::vector<CTransactionRef> tx_history;
61 tx_mut.
vin.reserve(num_in);
62 for (uint32_t i = 0; i < num_in; i++) {
63 auto& prevout =
PickValue(fuzzed_data_provider, outpoints);
68 tx_mut.
vout.reserve(num_out);
69 for (uint32_t i = 0; i < num_out; i++) {
74 for (uint32_t i = 0; i < num_out; i++) {
75 outpoints.emplace_back(new_tx->GetHash(), i);
80 tx_history.push_back(tx);
82 const auto wtxid{tx->GetWitnessHash()};
86 if (ptx_potential_parent) {
93 assert(std::any_of(child->vin.cbegin(), child->vin.cend(), [&](
const auto& input) {
94 return input.prevout.hash == ptx_potential_parent->GetHash();
104 const auto total_peer_bytes_start{orphanage.
UsageByPeer(peer_id)};
108 fuzzed_data_provider,
118 bool have_tx = orphanage.
HaveTx(tx->GetWitnessHash());
122 bool add_tx = orphanage.
AddTx(tx, peer_id);
124 Assert(!have_tx || !add_tx);
132 if (orphanage.
UsageByPeer(peer_id) == tx_weight + total_peer_bytes_start) {
143 have_tx = orphanage.
HaveTx(tx->GetWitnessHash());
145 bool add_tx = orphanage.
AddTx(tx, peer_id);
148 Assert(!have_tx || !add_tx);
152 bool have_tx = orphanage.
HaveTx(tx->GetWitnessHash());
153 bool have_tx_and_peer = orphanage.
HaveTxFromPeer(tx->GetWitnessHash(), peer_id);
156 bool added_announcer = orphanage.
AddAnnouncer(tx->GetWitnessHash(), peer_id);
158 Assert(have_tx || !added_announcer);
160 Assert(!have_tx_and_peer || !added_announcer);
165 if (added_announcer) {
173 bool have_tx = orphanage.
HaveTx(tx->GetWitnessHash());
177 auto bytes_from_peer_before{orphanage.
UsageByPeer(peer_id)};
181 if (have_tx_and_peer) {
190 have_tx = orphanage.
HaveTx(tx->GetWitnessHash());
194 Assert(!have_tx && !have_tx_and_peer && !orphanage.
EraseTx(wtxid));
206 for (
int i{0}; i < num_txs; ++i) {
207 auto& tx_to_remove =
PickValue(fuzzed_data_provider, tx_history);
208 block.
vtx.push_back(tx_to_remove);
211 for (
const auto& tx_removed : block.
vtx) {
212 Assert(!orphanage.
HaveTx(tx_removed->GetWitnessHash()));
227 if (!ptx_potential_parent || fuzzed_data_provider.
ConsumeBool()) {
228 ptx_potential_parent = tx;
231 const bool have_tx{orphanage.
HaveTx(tx->GetWitnessHash())};
232 const bool get_tx_nonnull{orphanage.
GetTx(tx->GetWitnessHash()) !=
nullptr};
233 Assert(have_tx == get_tx_nonnull);
int64_t CAmount
Amount in satoshis (Can be negative)
#define Assert(val)
Identity function.
std::vector< CTransactionRef > vtx
Serialized script, used inside transaction inputs and outputs.
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
T ConsumeIntegralInRange(T min, T max)
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.
void EraseForPeer(NodeId peer)
Maybe erase all orphans announced by a peer (eg, after that peer disconnects).
void LimitOrphans(unsigned int max_orphans, FastRandomContext &rng)
Limit the orphanage to the given maximum.
int EraseTx(const Wtxid &wtxid)
Erase an orphan by wtxid.
void EraseForBlock(const CBlock &block)
Erase all orphans included in or invalidated by a new block.
size_t Size() const
Return how many entries exist in the orphange.
CTransactionRef GetTx(const Wtxid &wtxid) const
bool AddAnnouncer(const Wtxid &wtxid, NodeId peer)
Add an additional announcer to an orphan if it exists.
std::vector< CTransactionRef > GetChildrenFromSamePeer(const CTransactionRef &parent, NodeId nodeid) const
Get all children that spend from this tx and were received from nodeid.
void AddChildrenToWorkSet(const CTransaction &tx, FastRandomContext &rng)
Add any orphans that list a particular tx as a parent into the from peer's work set.
void SanityCheck() const
Check consistency between PeerOrphanInfo and m_orphans.
bool HaveTx(const Wtxid &wtxid) const
Check if we already have an orphan transaction (by wtxid only)
unsigned int UsageByPeer(NodeId peer) const
Total usage (weight) of orphans for which this peer is an announcer.
unsigned int TotalOrphanUsage() const
Get the total usage (weight) of all orphans.
CTransactionRef GetTxToReconsider(NodeId peer)
Extract a transaction from a peer's work set Returns nullptr if there are no transactions to work on.
bool HaveTxFromPeer(const Wtxid &wtxid, NodeId peer) const
Check if a {tx, peer} exists in the orphanage.
static transaction_identifier FromUint256(const uint256 &id)
static int32_t GetTransactionWeight(const CTransaction &tx)
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
static const uint32_t DEFAULT_MAX_ORPHAN_TRANSACTIONS
Default for -maxorphantx, maximum number of orphan transactions kept in memory.
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
std::unique_ptr< T > MakeNoLogFileContext(const ChainType chain_type=ChainType::REGTEST, TestOpts opts={})
Make a test setup that has disk access to the debug.log file disabled.
A mutable version of CTransaction.
std::vector< CTxOut > vout
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
void initialize_orphanage()
FUZZ_TARGET(txorphan,.init=initialize_orphanage)