21 #include <util/time.h> 30 constexpr
size_t NUM_COINS{50};
50 std::vector<CTransactionRef> TRANSACTIONS;
53 constexpr
int NUM_PEERS = 16;
56 std::chrono::microseconds TIME_SKIPS[128];
62 for (
const auto& outpoint : outpoints) {
63 tx.
vin.emplace_back(outpoint);
66 tx.
vin[0].scriptWitness.stack.push_back({1});
73 std::vector<COutPoint>
ret;
83 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
85 for (uint32_t i = 0; i < uint32_t{NUM_COINS}; ++i) {
88 size_t outpoints_index = 0;
93 Assert(tx1->GetHash() == tx2->GetHash());
94 TRANSACTIONS.emplace_back(tx1);
95 TRANSACTIONS.emplace_back(tx2);
101 TRANSACTIONS.emplace_back(tx_parent_1);
103 TRANSACTIONS.emplace_back(tx_parent_2);
110 TRANSACTIONS.emplace_back(tx_parent);
118 COutPoint& last_outpoint = COINS[outpoints_index++];
119 for (
auto i{0}; i < 5; ++i) {
121 TRANSACTIONS.emplace_back(tx);
127 COutPoint& last_outpoint = COINS[outpoints_index++];
128 for (
auto i{0}; i < 5; ++i) {
130 TRANSACTIONS.emplace_back(tx);
136 for (
const auto& outpoint : COINS) {
143 for (; i < 16; ++i) {
144 TIME_SKIPS[i] = std::chrono::microseconds{i};
148 for (; i < 128; ++i) {
149 int diff_bits = ((i - 10) * 2) / 9;
151 TIME_SKIPS[i] = TIME_SKIPS[i - 1] + std::chrono::microseconds{diff};
162 const auto&
package = package_to_validate.m_txns;
164 Assert(package.size() == 2);
179 std::chrono::microseconds time{244466666};
200 txdownloadman.ConnectedPeer(rand_peer, info);
203 txdownloadman.DisconnectedPeer(rand_peer);
204 txdownloadman.CheckIsEmpty(rand_peer);
207 txdownloadman.ActiveTipChange();
211 block.
vtx.push_back(rand_tx);
212 txdownloadman.BlockConnected(std::make_shared<CBlock>(block));
215 txdownloadman.BlockDisconnected();
218 txdownloadman.MempoolAcceptedTx(rand_tx);
225 node::RejectedTxTodo todo = txdownloadman.MempoolRejectedTx(rand_tx, state, rand_peer, first_time_failure);
231 GenTxid{rand_tx->GetWitnessHash()};
232 txdownloadman.AddTxAnnouncement(rand_peer, gtxid, time);
235 txdownloadman.GetRequestsToSend(rand_peer, time);
238 txdownloadman.ReceivedTx(rand_peer, rand_tx);
239 const auto& [should_validate, maybe_package] = txdownloadman.ReceivedTx(rand_peer, rand_tx);
245 Assert(!(should_validate && maybe_package.has_value()));
246 if (maybe_package.has_value()) CheckPackageToValidate(*maybe_package, rand_peer);
249 txdownloadman.ReceivedNotFound(rand_peer, {rand_tx->GetWitnessHash()});
252 const bool expect_work{txdownloadman.HaveMoreWork(rand_peer)};
253 const auto ptx = txdownloadman.GetTxToReconsider(rand_peer);
269 for (
NodeId nodeid = 0; nodeid < NUM_PEERS; ++nodeid) {
270 txdownloadman.DisconnectedPeer(nodeid);
271 txdownloadman.CheckIsEmpty(nodeid);
273 txdownloadman.CheckIsEmpty();
278 static bool HasRelayPermissions(
NodeId peer) {
return peer == 0; }
284 for (
NodeId peer = 0; peer < NUM_PEERS; ++peer) {
285 if (!HasRelayPermissions(peer)) {
304 std::chrono::microseconds time{244466666};
322 .m_relay_permissions = HasRelayPermissions(rand_peer),
334 for (
const auto& tx : TRANSACTIONS) {
343 block.
vtx.push_back(rand_tx);
370 GenTxid{rand_tx->GetWitnessHash()};
374 const auto getdata_requests = txdownload_impl.
GetRequestsToSend(rand_peer, time);
377 for (
const auto& gtxid : getdata_requests) {
382 const auto& [should_validate, maybe_package] = txdownload_impl.
ReceivedTx(rand_peer, rand_tx);
388 Assert(!(should_validate && maybe_package.has_value()));
389 if (should_validate) {
392 if (maybe_package.has_value()) {
393 CheckPackageToValidate(*maybe_package, rand_peer);
395 const auto&
package = maybe_package->m_txns;
398 Assert(txdownload_impl.
m_orphanage->HaveTx(maybe_package->m_txns.back()->GetWitnessHash()));
410 const bool expect_work{txdownload_impl.
HaveMoreWork(rand_peer)};
433 CheckInvariants(txdownload_impl);
435 for (
NodeId nodeid = 0; nodeid < NUM_PEERS; ++nodeid) {
std::shared_ptr< const CTransaction > CTransactionRef
invalid by consensus rules
std::vector< Txid > m_unique_parents
size_t Count(NodeId peer) const
Count how many announcements a peer has (REQUESTED, CANDIDATE, and COMPLETED combined).
uint256 GetPackageHash(const std::vector< CTransactionRef > &transactions)
Get the hash of the concatenated wtxids of transactions, with wtxids treated as a little-endian numbe...
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
std::pair< bool, std::optional< PackageToValidate > > ReceivedTx(NodeId nodeid, const CTransactionRef &ptx)
bool IsChildWithParents(const Package &package)
Context-free check that a package is exactly one child and its parents; not all parents need to be pr...
CRollingBloomFilter & RecentConfirmedTransactionsFilter()
transaction was not validated because package failed
TxRequestTracker m_txrequest
Tracks candidates for requesting and downloading transaction data.
static const CScript P2WSH_OP_TRUE
transaction was missing some of its inputs
RejectedTxTodo MempoolRejectedTx(const CTransactionRef &ptx, const TxValidationState &state, NodeId nodeid, bool first_time_failure)
void BlockConnected(const std::shared_ptr< const CBlock > &pblock)
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
bool contains(std::span< const unsigned char > vKey) const
const TestingSetup * g_setup
violated mempool's fee/size/descendant/RBF/etc limits
inputs (covered by txid) failed policy rules
transaction spends a coinbase too early, or violates locktime/sequence locks
bool AddTxAnnouncement(NodeId peer, const GenTxid >xid, std::chrono::microseconds now)
Consider adding this tx hash to txrequest.
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS
Maximum number of transactions to consider for requesting, per peer.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
void SanityCheck() const
Run internal consistency check (testing only).
Class responsible for deciding what transactions to request and, once downloaded, whether and how to ...
const bool m_preferred
Whether this peer is preferred for transaction download.
CRollingBloomFilter & RecentRejectsFilter()
std::unique_ptr< TxOrphanage > m_orphanage
Manages unvalidated tx data (orphan transactions for which we are downloading ancestors).
A writer stream (for serialization) that computes a 256-bit hash.
CRollingBloomFilter & RecentRejectsReconsiderableFilter()
bool HaveMoreWork(NodeId nodeid)
void ReceivedNotFound(NodeId nodeid, const std::vector< GenTxid > >xids)
Marks a tx as ReceivedResponse in txrequest.
static CTransactionRef MakeTransactionSpending(const std::vector< COutPoint > &outpoints, FastRandomContext &det_rand)
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Txid GetHash() const
Compute the hash of this CMutableTransaction.
An outpoint - a combination of a transaction hash and an index n into its vout.
bool m_should_add_extra_compact_tx
std::vector< CTxOut > vout
fails some policy, but might be acceptable if submitted in a (different) package
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Transaction is missing a witness.
void SeedRandomStateForTest(SeedRand seedtype)
Seed the global RNG state for testing and log the seed value.
std::vector< GenTxid > GetRequestsToSend(NodeId nodeid, std::chrono::microseconds current_time)
Get getdata requests to send.
std::vector< CTransactionRef > vtx
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
static transaction_identifier FromUint256(const uint256 &id)
FuzzedDataProvider & fuzzed_data_provider
General SipHash-2-4 implementation.
std::vector< NodeId > m_senders
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
A mutable version of CTransaction.
static constexpr CAmount CENT
const uint256 & ToUint256() const LIFETIMEBOUND
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
void MempoolAcceptedTx(const CTransactionRef &tx)
CTransactionRef GetTxToReconsider(NodeId nodeid)
T ConsumeIntegralInRange(T min, T max)
Seed with a compile time constant of zeros.
T PickValueInArray(const T(&array)[size])
void ConnectedPeer(NodeId nodeid, const TxDownloadConnectionInfo &info)
Tx already in mempool or conflicts with a tx in the chain (if it conflicts with another tx in mempool...
bool AlreadyHaveTx(const GenTxid >xid, bool include_reconsiderable)
Check whether we already have this gtxid in:
void DisconnectedPeer(NodeId nodeid)
otherwise didn't meet our local policy rules
Testing setup that configures a complete environment.
#define Assert(val)
Identity function.
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
TxValidationResult
A "reason" why a transaction was invalid, suitable for determining whether the provider of the transa...