Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
mini_miner.cpp
Go to the documentation of this file.
1// Copyright (c) The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
6#include <test/fuzz/fuzz.h>
7#include <test/fuzz/util.h>
9#include <test/util/script.h>
11#include <test/util/txmempool.h>
12#include <test/util/mining.h>
13
14#include <node/miner.h>
15#include <node/mini_miner.h>
16#include <node/types.h>
18#include <random.h>
19#include <txmempool.h>
20#include <util/check.h>
21#include <util/time.h>
22#include <util/translation.h>
23
24#include <deque>
25#include <vector>
26
27namespace {
28
29std::deque<COutPoint> g_available_coins;
30void initialize_miner()
31{
32 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
33 for (uint32_t i = 0; i < uint32_t{100}; ++i) {
34 g_available_coins.emplace_back(Txid::FromUint256(uint256::ZERO), i);
35 }
36}
37
38// Test that the MiniMiner can run with various outpoints and feerates.
39FUZZ_TARGET(mini_miner, .init = initialize_miner)
40{
42 FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
43 SetMockTime(ConsumeTime(fuzzed_data_provider));
44 bilingual_str error;
45 CTxMemPool pool{CTxMemPool::Options{}, error};
46 Assert(error.empty());
47 std::vector<COutPoint> outpoints;
48 std::deque<COutPoint> available_coins = g_available_coins;
49 LOCK2(::cs_main, pool.cs);
50 // Cluster size cannot exceed 500
51 LIMITED_WHILE(!available_coins.empty(), 100)
52 {
54 const size_t num_inputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, available_coins.size());
55 const size_t num_outputs = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(1, 50);
56 for (size_t n{0}; n < num_inputs; ++n) {
57 auto prevout = available_coins.front();
58 mtx.vin.emplace_back(prevout, CScript());
59 available_coins.pop_front();
60 }
61 for (uint32_t n{0}; n < num_outputs; ++n) {
62 mtx.vout.emplace_back(100, P2WSH_OP_TRUE);
63 }
66 const CAmount fee{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/100000)};
68 TryAddToMempool(pool, entry.Fee(fee).FromTx(tx));
69
70 // All outputs are available to spend
71 for (uint32_t n{0}; n < num_outputs; ++n) {
72 if (fuzzed_data_provider.ConsumeBool()) {
73 available_coins.emplace_back(tx->GetHash(), n);
74 }
75 }
76
77 if (fuzzed_data_provider.ConsumeBool() && !tx->vout.empty()) {
78 // Add outpoint from this tx (may or not be spent by a later tx)
79 outpoints.emplace_back(tx->GetHash(),
80 (uint32_t)fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, tx->vout.size()));
81 } else {
82 // Add some random outpoint (will be interpreted as confirmed or not yet submitted
83 // to mempool).
84 auto outpoint = ConsumeDeserializable<COutPoint>(fuzzed_data_provider);
85 if (outpoint.has_value() && std::find(outpoints.begin(), outpoints.end(), *outpoint) == outpoints.end()) {
86 outpoints.push_back(*outpoint);
87 }
88 }
89
90 }
91
92 const CFeeRate target_feerate{CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/MAX_MONEY/1000)}};
93 std::optional<CAmount> total_bumpfee;
94 CAmount sum_fees = 0;
95 {
96 node::MiniMiner mini_miner{pool, outpoints};
97 assert(mini_miner.IsReadyToCalculate());
98 const auto bump_fees = mini_miner.CalculateBumpFees(target_feerate);
99 for (const auto& outpoint : outpoints) {
100 auto it = bump_fees.find(outpoint);
101 assert(it != bump_fees.end());
102 assert(it->second >= 0);
103 sum_fees += it->second;
104 }
105 assert(!mini_miner.IsReadyToCalculate());
106 }
107 {
108 node::MiniMiner mini_miner{pool, outpoints};
109 assert(mini_miner.IsReadyToCalculate());
110 total_bumpfee = mini_miner.CalculateTotalBumpFees(target_feerate);
111 assert(total_bumpfee.has_value());
112 assert(!mini_miner.IsReadyToCalculate());
113 }
114 // Overlapping ancestry across multiple outpoints can only reduce the total bump fee.
115 assert (sum_fees >= *total_bumpfee);
116}
117} // namespace
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition amount.h:26
bool MoneyRange(const CAmount &nValue)
Definition amount.h:27
int64_t CAmount
Amount in satoshis (Can be negative).
Definition amount.h:12
TryAddToMempool(pool, CTxMemPoolEntry(tx, fee, 0, 1, 0, false, 4, lp))
#define Assert(val)
Identity function.
Definition check.h:113
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
Definition feerate.h:32
Serialized script, used inside transaction inputs and outputs.
Definition script.h:405
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:187
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition txmempool.h:260
kernel::MemPoolOptions Options
Definition txmempool.h:301
T ConsumeIntegralInRange(T min, T max)
A minimal version of BlockAssembler, using the same ancestor set scoring algorithm.
Definition mini_miner.h:79
std::map< COutPoint, CAmount > CalculateBumpFees(const CFeeRate &target_feerate)
Construct a new block template and, for each outpoint corresponding to a transaction that did not mak...
std::optional< CAmount > CalculateTotalBumpFees(const CFeeRate &target_feerate)
Construct a new block template and, calculate the cost of bumping all transactions that did not make ...
bool IsReadyToCalculate() const
Returns true if CalculateBumpFees may be called, false if not.
Definition mini_miner.h:125
static transaction_identifier FromUint256(const uint256 &id)
static const uint256 ZERO
Definition uint256.h:203
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:8
#define FUZZ_TARGET(...)
Definition fuzz.h:35
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
Definition fuzz.h:22
uint64_t fee
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
std::vector< CTxIn > vin
Definition txmempool.h:19
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
Definition txmempool.cpp:34
TestMemPoolEntryHelper & Fee(CAmount _fee)
Definition txmempool.h:33
Bilingual messages:
Definition translation.h:24
bool empty() const
Definition translation.h:35
#define LOCK2(cs1, cs2)
Definition sync.h:259
NodeSeconds ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition util.cpp:34
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
Definition util.cpp:29
std::optional< T > ConsumeDeserializable(FuzzedDataProvider &fuzzed_data_provider, const P &params, const std::optional< size_t > &max_length=std::nullopt) noexcept
Definition util.h:100
void SeedRandomStateForTest(SeedRand seedtype)
Seed the global RNG state for testing and log the seed value.
Definition random.cpp:19
@ ZEROS
Seed with a compile time constant of zeros.
Definition random.h:19
static const CScript P2WSH_OP_TRUE
Definition script.h:13
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
Definition time.cpp:44
assert(!tx.IsCoinBase())