mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-10 14:48:46 +02:00
Merge bitcoin/bitcoin#33966: refactor: disentangle miner startup defaults from runtime options
1e5d3b4f0ddoc: add release note for mining option validation (Sjors Provoost)0317f52022ci: enforce iwyu for touched files (Sjors Provoost)8c58f63578refactor: have mining files include what they use (Sjors Provoost)3bb6498fb0mining: store block create options in NodeContext (Sjors Provoost)4637cd157dmining: reject invalid block create options (Sjors Provoost)8daac1d6ebmining: add block create option helpers (Sjors Provoost)128da7c3ffminer: add block_max_weight to BlockCreateOptions (Sjors Provoost)fa81e51eaemining: parse block creation args in mining_args (Sjors Provoost)020166080cmining: use interface for tests, bench and fuzzers (Sjors Provoost)44082bea47interfaces: make Mining use const NodeContext (Sjors Provoost)d4368e059cmove-only: add node/mining_types.h (Sjors Provoost)6aeb1fbea2test: cover IPC blockmaxweight policy (Sjors Provoost)63b23ea1e9test: regression test for waitNext mining policy (Sjors Provoost)24750f8b31test: add createNewBlock failure helper (Sjors Provoost)63ee9cd15btest: misc interface_ipc_mining.py improvements (Sjors Provoost) Pull request description: Although this PR is primarily a refactor, _there are behavior changes_ documented in the release note: - the IPC mining interface now rejects out-of-range block template options instead of silently clamping them; - startup now rejects `-blockmaxweight` values lower than `-blockreservedweight`, instead of allowing them to be clamped later. The interaction between node startup options like `-blockreservedweight` and runtime options, especially those passed via IPC, is confusing. They're combined in `BlockAssembler::Options`, which this PR gets rid of in favour of `BlockCreateOptions`. `BlockCreateOptions` is used by interface clients. As before, IPC clients have access to a safe / sane subset, whereas RPC and test code can use all fields. The same type is also used to store mining defaults parsed once during node startup in `NodeContext`. The maximum block weight setting (`block_max_weight`) is optional. When read from startup options it matches `-blockmaxweight`; when provided by callers it is a runtime override. `Merge()` fills unset fields from startup defaults while preserving caller-provided values. This all happens in commits `mining: add block create option helpers` and `mining: store block create options in NodeContext`, and requires some preparation to keep things easy to review. We get rid of `BlockAssembler::Options` but this is used in many tests. Since large churn is inevitable, we might as well switch all tests, bench and fuzzers over to the Mining interface. The `mining: use interface for tests, bench and fuzzers` commit does that, dramatically reducing direct use of `BlockAssembler`. Two exceptions are documented in the commit message. Because `test_block_validity` wasn't available via the interface and the block_assemble benchmark needs it, it's moved from `BlockAssembler::Options` to `BlockCreateOptions` (still not exposed via IPC). We need access to mining related structs from both the miner and node initialization code. To avoid having to pull in all of `BlockAssembler` for the latter, the `move-only: add node/mining_types.h` commit introduces `node/mining_types.h` and moves `BlockCreateOptions`, `BlockWaitOptions` and `BlockCheckOptions` there from `src/node/types.h`. I considered also moving `DEFAULT_BLOCK_MAX_WEIGHT`, `DEFAULT_BLOCK_RESERVED_WEIGHT`, `MINIMUM_BLOCK_RESERVED_WEIGHT` and `DEFAULT_BLOCK_MIN_TX_FEE` there from `policy.h`, since they are distinct from relay policy and not needed by the kernel. But this seems more appropriate for a follow-up and requires additional discussion. --- I kept variable renaming and other formatting changes to a minimum to ease review with `--color-moved=dimmed-zebra`. ## Commit summary Tests and test cleanup: - `test: misc interface_ipc_mining.py improvements` - `test: add assert_create_fails helper` - `test: regression test for waitNext mining policy` - `test: cover IPC blockmaxweight policy` Refactoring test/bench/fuzz callers: - `interfaces: make Mining use const NodeContext` - `mining: use interface for tests, bench and fuzzers` Moving mining interface types: - `move-only: add node/mining_types.h` Separating startup defaults from runtime options: - `mining: parse block creation args in mining_args`: adds `node/mining_args.{h,cpp}` and moves mining option parsing out of `init.cpp`, without storing the parsed values yet. - `miner: add block_max_weight to BlockCreateOptions`: moves the runtime maximum block weight setting into `BlockCreateOptions` as an optional value, so it can later be defaulted from startup args when unset. - `mining: add block create option helpers`: centralizes block template option defaulting and merging, removes `BlockAssembler::Options`, and preserves behavior except for dropping the `Specified ` prefix from startup option error messages. - `mining: reject invalid block create options`: checks typed `BlockCreateOptions` before block template creation, so invalid runtime options are rejected instead of silently clamped. Startup validation also rejects `-blockmaxweight` values lower than `-blockreservedweight`. - `mining: store block create options in NodeContext`: stores the startup mining options in `NodeContext` as `BlockCreateOptions`, so startup defaults and runtime overrides can be merged with the same option type. Include hygiene, CI and release note: - `refactor: have mining files include what they use` - `ci: enforce iwyu for touched files` - `doc: add release note for mining option validation` ACKs for top commit: w0xlt: reACK1e5d3b4f0dsedited: ACK1e5d3b4f0dryanofsky: Code review ACK1e5d3b4f0d. Looks good, thanks for the updates! Tree-SHA512: 28c715023cb78f02775caa787b243c994bd0f8ce4559afc8db9301e93400ebbc74963626a4afe65ae15bcc16b9192d051a745839f4c804848d50746ea5a224b4
This commit is contained in:
@@ -229,7 +229,7 @@ fi
|
||||
|
||||
if [[ "${RUN_IWYU}" == true ]]; then
|
||||
# TODO: Consider enforcing IWYU across the entire codebase.
|
||||
FILES_WITH_ENFORCED_IWYU="/src/(((crypto|index|kernel|primitives|univalue/(lib|test)|util|zmq)/.*|common/license_info|node/blockstorage|node/utxo_snapshot|clientversion|core_io|signet)\\.cpp)"
|
||||
FILES_WITH_ENFORCED_IWYU="/src/(((crypto|index|kernel|primitives|univalue/(lib|test)|util|zmq)/.*|bench/(block_assemble|connectblock)|common/license_info|node/(blockstorage|interfaces|miner|mining_args|utxo_snapshot)|rpc/mining|clientversion|core_io|signet|init)\\.cpp)"
|
||||
jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns)))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_errors.json"
|
||||
jq --arg patterns "$FILES_WITH_ENFORCED_IWYU" 'map(select(.file | test($patterns) | not))' "${BASE_BUILD_DIR}/compile_commands.json" > "${BASE_BUILD_DIR}/compile_commands_iwyu_warnings.json"
|
||||
|
||||
|
||||
9
doc/release-notes-33966.md
Normal file
9
doc/release-notes-33966.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Mining
|
||||
------
|
||||
|
||||
- The IPC mining interface now rejects out-of-range block template options
|
||||
instead of silently clamping them, such as oversized reserved block weight or
|
||||
coinbase sigops limits. (#33966)
|
||||
|
||||
- The `-blockmaxweight` startup option is now rejected when it is lower than
|
||||
`-blockreservedweight`, instead of being silently clamped. (#33966)
|
||||
@@ -232,6 +232,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL
|
||||
node/mempool_persist.cpp
|
||||
node/mempool_persist_args.cpp
|
||||
node/miner.cpp
|
||||
node/mining_args.cpp
|
||||
node/mini_miner.cpp
|
||||
node/minisketchwrapper.cpp
|
||||
node/peerman_args.cpp
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <bench/bench.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <script/script.h>
|
||||
@@ -18,9 +18,10 @@
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
|
||||
static void AssembleBlock(benchmark::Bench& bench)
|
||||
{
|
||||
@@ -28,8 +29,9 @@ static void AssembleBlock(benchmark::Bench& bench)
|
||||
|
||||
CScriptWitness witness;
|
||||
witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
};
|
||||
|
||||
// Collect some loose transactions that spend the coinbases of our mined blocks
|
||||
constexpr size_t NUM_BLOCKS{200};
|
||||
@@ -60,12 +62,12 @@ static void BlockAssemblerAddPackageTxns(benchmark::Bench& bench)
|
||||
FastRandomContext det_rand{true};
|
||||
auto testing_setup{MakeNoLogFileContext<TestChain100Setup>()};
|
||||
testing_setup->PopulateMempool(det_rand, /*num_transactions=*/1000, /*submit=*/true);
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.test_block_validity = false;
|
||||
assembler_options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
|
||||
bench.run([&] {
|
||||
PrepareBlock(testing_setup->m_node, assembler_options);
|
||||
PrepareBlock(testing_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
.test_block_validity = false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,14 +4,27 @@
|
||||
|
||||
#include <addresstype.h>
|
||||
#include <bench/bench.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <kernel/cs_main.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <chain.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <key.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <pubkey.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
@@ -39,7 +52,7 @@ CBlock CreateTestBlock(
|
||||
{COutPoint(coinbase_to_spend->GetHash(), 0)},
|
||||
chainstate.m_chain.Height() + 1, keys, outputs, {}, {})};
|
||||
const CScript coinbase_spk{GetScriptForDestination(coinbase_taproot)};
|
||||
test_setup.CreateAndProcessBlock({first_tx}, coinbase_spk, &chainstate);
|
||||
test_setup.CreateAndProcessBlock({first_tx}, coinbase_spk);
|
||||
|
||||
std::vector<CMutableTransaction> txs;
|
||||
txs.reserve(num_txs);
|
||||
@@ -59,7 +72,7 @@ CBlock CreateTestBlock(
|
||||
}
|
||||
|
||||
// Coinbase output can use any output type as it is not spent and will not change the benchmark
|
||||
return test_setup.CreateBlock(txs, coinbase_spk, chainstate);
|
||||
return test_setup.CreateBlock(txs, coinbase_spk);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
67
src/init.cpp
67
src/init.cpp
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <kernel/checks.h>
|
||||
|
||||
#include <addrdb.h>
|
||||
#include <addrman.h>
|
||||
#include <banman.h>
|
||||
#include <blockfilter.h>
|
||||
@@ -18,13 +19,15 @@
|
||||
#include <chainparamsbase.h>
|
||||
#include <clientversion.h>
|
||||
#include <common/args.h>
|
||||
#include <common/messages.h>
|
||||
#include <common/system.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <hash.h>
|
||||
#include <compat/compat.h>
|
||||
#include <consensus/params.h>
|
||||
#include <crypto/hex_base.h>
|
||||
#include <dbwrapper.h>
|
||||
#include <httprpc.h>
|
||||
#include <httpserver.h>
|
||||
#include <index/base.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <index/coinstatsindex.h>
|
||||
#include <index/txindex.h>
|
||||
@@ -36,14 +39,18 @@
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/node.h>
|
||||
#include <ipc/exception.h>
|
||||
#include <kernel/blockmanager_opts.h>
|
||||
#include <kernel/caches.h>
|
||||
#include <kernel/chainstatemanager_opts.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/notifications_interface.h>
|
||||
#include <key.h>
|
||||
#include <logging.h>
|
||||
#include <mapport.h>
|
||||
#include <net.h>
|
||||
#include <net_permissions.h>
|
||||
#include <net_processing.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <netgroup.h>
|
||||
#include <node/blockmanager_args.h>
|
||||
@@ -57,7 +64,8 @@
|
||||
#include <node/mempool_args.h>
|
||||
#include <node/mempool_persist.h>
|
||||
#include <node/mempool_persist_args.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_args.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <node/peerman_args.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/fees/block_policy_estimator.h>
|
||||
@@ -65,19 +73,20 @@
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
#include <protocol.h>
|
||||
#include <rpc/blockchain.h>
|
||||
#include <random.h>
|
||||
#include <rpc/register.h>
|
||||
#include <rpc/server.h>
|
||||
#include <rpc/util.h>
|
||||
#include <scheduler.h>
|
||||
#include <script/sigcache.h>
|
||||
#include <sync.h>
|
||||
#include <tinyformat.h>
|
||||
#include <torcontrol.h>
|
||||
#include <txdb.h>
|
||||
#include <txgraph.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/asmap.h>
|
||||
#include <util/batchpriority.h>
|
||||
#include <util/byte_units.h>
|
||||
#include <util/chaintype.h>
|
||||
#include <util/check.h>
|
||||
#include <util/fs.h>
|
||||
@@ -97,21 +106,31 @@
|
||||
#include <walletinitinterface.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <any>
|
||||
#include <cerrno>
|
||||
#include <condition_variable>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <csignal>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ZMQ
|
||||
@@ -124,7 +143,6 @@
|
||||
#include <node/data/ip_asn.dat.h>
|
||||
#endif
|
||||
|
||||
using common::AmountErrMsg;
|
||||
using common::InvalidPortErrMsg;
|
||||
using common::ResolveErrMsg;
|
||||
|
||||
@@ -1074,27 +1092,9 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||
return InitError(Untranslated("peertimeout must be a positive integer."));
|
||||
}
|
||||
|
||||
if (const auto arg{args.GetArg("-blockmintxfee")}) {
|
||||
if (!ParseMoney(*arg)) {
|
||||
return InitError(AmountErrMsg("blockmintxfee", *arg));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto max_block_weight = args.GetIntArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT);
|
||||
if (max_block_weight > MAX_BLOCK_WEIGHT) {
|
||||
return InitError(strprintf(_("Specified -blockmaxweight (%d) exceeds consensus maximum block weight (%d)"), max_block_weight, MAX_BLOCK_WEIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto block_reserved_weight = args.GetIntArg("-blockreservedweight", DEFAULT_BLOCK_RESERVED_WEIGHT);
|
||||
if (block_reserved_weight > MAX_BLOCK_WEIGHT) {
|
||||
return InitError(strprintf(_("Specified -blockreservedweight (%d) exceeds consensus maximum block weight (%d)"), block_reserved_weight, MAX_BLOCK_WEIGHT));
|
||||
}
|
||||
if (block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
|
||||
return InitError(strprintf(_("Specified -blockreservedweight (%d) is lower than minimum safety value of (%d)"), block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT));
|
||||
}
|
||||
auto mining_result{node::ReadMiningArgs(args)};
|
||||
if (!mining_result) {
|
||||
return InitError(util::ErrorString(mining_result));
|
||||
}
|
||||
|
||||
nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp);
|
||||
@@ -1328,6 +1328,9 @@ static ChainstateLoadResult InitAndLoadChainstate(
|
||||
if (!mempool_error.empty()) {
|
||||
return {ChainstateLoadStatus::FAILURE_FATAL, mempool_error};
|
||||
}
|
||||
auto mining_args{node::ReadMiningArgs(args)};
|
||||
Assert(mining_args); // no error can happen, already checked in AppInitParameterInteraction
|
||||
node.mining_args = std::move(*mining_args);
|
||||
LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
|
||||
cache_sizes.coins / double(1_MiB),
|
||||
mempool_opts.max_size_bytes / double(1_MiB));
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include <consensus/amount.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <node/types.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <uint256.h>
|
||||
@@ -16,15 +16,13 @@
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace node {
|
||||
struct NodeContext;
|
||||
} // namespace node
|
||||
|
||||
class BlockValidationState;
|
||||
class CScript;
|
||||
|
||||
namespace interfaces {
|
||||
|
||||
//! Block template interface
|
||||
@@ -161,7 +159,7 @@ public:
|
||||
|
||||
//! Get internal node context. Useful for RPC and testing,
|
||||
//! but not accessible across processes.
|
||||
virtual node::NodeContext* context() { return nullptr; }
|
||||
virtual const node::NodeContext* context() { return nullptr; }
|
||||
};
|
||||
|
||||
//! Return implementation of Mining interface.
|
||||
@@ -169,7 +167,7 @@ public:
|
||||
//! @param[in] wait_loaded waits for chainstate data to be loaded before
|
||||
//! returning. Used to prevent external clients from
|
||||
//! being able to crash the node during startup.
|
||||
std::unique_ptr<Mining> MakeMining(node::NodeContext& node, bool wait_loaded=true);
|
||||
std::unique_ptr<Mining> MakeMining(const node::NodeContext& node, bool wait_loaded=true);
|
||||
|
||||
} // namespace interfaces
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef BITCOIN_NODE_CONTEXT_H
|
||||
#define BITCOIN_NODE_CONTEXT_H
|
||||
|
||||
#include <node/mining_types.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
@@ -81,6 +83,11 @@ struct NodeContext {
|
||||
//! Reference to chain client that should used to load or create wallets
|
||||
//! opened by the gui.
|
||||
std::unique_ptr<interfaces::Mining> mining;
|
||||
//! Mining options used to create block templates. This value member is an
|
||||
//! exception to the dependency guidance above because BlockCreateOptions is
|
||||
//! a minimal dependency. It could be moved to the BlockTemplateCache
|
||||
//! proposed in bitcoin/bitcoin#33421.
|
||||
BlockCreateOptions mining_args;
|
||||
interfaces::WalletLoader* wallet_loader{nullptr};
|
||||
std::unique_ptr<CScheduler> scheduler;
|
||||
std::function<void()> rpc_interruption_point = [] {};
|
||||
|
||||
@@ -2,16 +2,19 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <addrdb.h>
|
||||
#include <bitcoin-build-config.h> // IWYU pragma: keep
|
||||
|
||||
#include <banman.h>
|
||||
#include <blockfilter.h>
|
||||
#include <btcsignals.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <common/args.h>
|
||||
#include <common/settings.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <external_signer.h>
|
||||
#include <httprpc.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
@@ -22,23 +25,24 @@
|
||||
#include <interfaces/node.h>
|
||||
#include <interfaces/rpc.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/mempool_entry.h>
|
||||
#include <key.h>
|
||||
#include <logging.h>
|
||||
#include <mapport.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <net_types.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/coin.h>
|
||||
#include <node/context.h>
|
||||
#include <node/interface_ui.h>
|
||||
#include <node/mini_miner.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/kernel_notifications.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mini_miner.h>
|
||||
#include <node/mining_args.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <node/transaction.h>
|
||||
#include <node/types.h>
|
||||
#include <node/warnings.h>
|
||||
@@ -46,13 +50,12 @@
|
||||
#include <policy/fees/block_policy_estimator.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/rbf.h>
|
||||
#include <policy/settings.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <rpc/blockchain.h>
|
||||
#include <rpc/protocol.h>
|
||||
#include <rpc/request.h>
|
||||
#include <rpc/server.h>
|
||||
#include <support/allocators/secure.h>
|
||||
#include <sync.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
@@ -61,17 +64,24 @@
|
||||
#include <util/result.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/string.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <bitcoin-build-config.h> // IWYU pragma: keep
|
||||
|
||||
#include <any>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using interfaces::BlockRef;
|
||||
using interfaces::BlockTemplate;
|
||||
@@ -86,6 +96,7 @@ using interfaces::Rpc;
|
||||
using interfaces::WalletLoader;
|
||||
using kernel::ChainstateRole;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
using node::BlockWaitOptions;
|
||||
using node::CoinbaseTx;
|
||||
using util::Join;
|
||||
@@ -867,11 +878,11 @@ public:
|
||||
class BlockTemplateImpl : public BlockTemplate
|
||||
{
|
||||
public:
|
||||
explicit BlockTemplateImpl(BlockAssembler::Options assemble_options,
|
||||
explicit BlockTemplateImpl(BlockCreateOptions create_options,
|
||||
std::unique_ptr<CBlockTemplate> block_template,
|
||||
NodeContext& node) : m_assemble_options(std::move(assemble_options)),
|
||||
m_block_template(std::move(block_template)),
|
||||
m_node(node)
|
||||
const NodeContext& node) : m_create_options(std::move(create_options)),
|
||||
m_block_template(std::move(block_template)),
|
||||
m_node(node)
|
||||
{
|
||||
assert(m_block_template);
|
||||
}
|
||||
@@ -914,8 +925,14 @@ public:
|
||||
|
||||
std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override
|
||||
{
|
||||
auto new_template = WaitAndCreateNewBlock(chainman(), notifications(), m_node.mempool.get(), m_block_template, options, m_assemble_options, m_interrupt_wait);
|
||||
if (new_template) return std::make_unique<BlockTemplateImpl>(m_assemble_options, std::move(new_template), m_node);
|
||||
auto new_template = WaitAndCreateNewBlock(chainman(),
|
||||
notifications(),
|
||||
m_node.mempool.get(),
|
||||
m_block_template,
|
||||
/*wait_options=*/options,
|
||||
/*create_options=*/m_create_options,
|
||||
/*interrupt_wait=*/m_interrupt_wait);
|
||||
if (new_template) return std::make_unique<BlockTemplateImpl>(m_create_options, std::move(new_template), m_node);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -924,20 +941,20 @@ public:
|
||||
InterruptWait(notifications(), m_interrupt_wait);
|
||||
}
|
||||
|
||||
const BlockAssembler::Options m_assemble_options;
|
||||
const BlockCreateOptions m_create_options;
|
||||
|
||||
const std::unique_ptr<CBlockTemplate> m_block_template;
|
||||
|
||||
bool m_interrupt_wait{false};
|
||||
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
|
||||
KernelNotifications& notifications() { return *Assert(m_node.notifications); }
|
||||
NodeContext& m_node;
|
||||
const NodeContext& m_node;
|
||||
};
|
||||
|
||||
class MinerImpl : public Mining
|
||||
{
|
||||
public:
|
||||
explicit MinerImpl(NodeContext& node) : m_node(node) {}
|
||||
explicit MinerImpl(const NodeContext& node) : m_node(node) {}
|
||||
|
||||
bool isTestChain() override
|
||||
{
|
||||
@@ -961,16 +978,6 @@ public:
|
||||
|
||||
std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options, bool cooldown) override
|
||||
{
|
||||
// Reject too-small values instead of clamping so callers don't silently
|
||||
// end up mining with different options than requested. This matches the
|
||||
// behavior of the `-blockreservedweight` startup option, which rejects
|
||||
// values below MINIMUM_BLOCK_RESERVED_WEIGHT.
|
||||
if (options.block_reserved_weight && options.block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
|
||||
throw std::runtime_error(strprintf("block_reserved_weight (%zu) must be at least %u weight units",
|
||||
*options.block_reserved_weight,
|
||||
MINIMUM_BLOCK_RESERVED_WEIGHT));
|
||||
}
|
||||
|
||||
// Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.
|
||||
std::optional<BlockRef> maybe_tip{waitTipChanged(uint256::ZERO, MillisecondsDouble::max())};
|
||||
|
||||
@@ -990,10 +997,14 @@ public:
|
||||
// Also wait during the final catch-up moments after IBD.
|
||||
if (!CooldownIfHeadersAhead(chainman(), notifications(), *maybe_tip, m_interrupt_mining)) return {};
|
||||
}
|
||||
|
||||
BlockAssembler::Options assemble_options{options};
|
||||
ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
|
||||
return std::make_unique<BlockTemplateImpl>(assemble_options, BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(), m_node);
|
||||
const BlockCreateOptions create_options{MergeMiningOptions(options, m_node.mining_args)};
|
||||
return std::make_unique<BlockTemplateImpl>(create_options,
|
||||
BlockAssembler{
|
||||
chainman().ActiveChainstate(),
|
||||
m_node.mempool.get(),
|
||||
create_options,
|
||||
}.CreateNewBlock(),
|
||||
m_node);
|
||||
}
|
||||
|
||||
void interrupt() override
|
||||
@@ -1010,12 +1021,12 @@ public:
|
||||
return state.IsValid();
|
||||
}
|
||||
|
||||
NodeContext* context() override { return &m_node; }
|
||||
const NodeContext* context() override { return &m_node; }
|
||||
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
|
||||
KernelNotifications& notifications() { return *Assert(m_node.notifications); }
|
||||
// Treat as if guarded by notifications().m_tip_block_mutex
|
||||
bool m_interrupt_mining{false};
|
||||
NodeContext& m_node;
|
||||
const NodeContext& m_node;
|
||||
};
|
||||
|
||||
class RpcImpl : public Rpc
|
||||
@@ -1041,7 +1052,7 @@ public:
|
||||
namespace interfaces {
|
||||
std::unique_ptr<Node> MakeNode(node::NodeContext& context) { return std::make_unique<node::NodeImpl>(context); }
|
||||
std::unique_ptr<Chain> MakeChain(node::NodeContext& context) { return std::make_unique<node::ChainImpl>(context); }
|
||||
std::unique_ptr<Mining> MakeMining(node::NodeContext& context, bool wait_loaded)
|
||||
std::unique_ptr<Mining> MakeMining(const node::NodeContext& context, bool wait_loaded)
|
||||
{
|
||||
if (wait_loaded) {
|
||||
node::KernelNotifications& kernel_notifications(*Assert(context.notifications));
|
||||
|
||||
@@ -7,29 +7,49 @@
|
||||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <common/args.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <node/context.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/kernel_notifications.h>
|
||||
#include <node/mining_args.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <tinyformat.h>
|
||||
#include <txgraph.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <util/feefrac.h>
|
||||
#include <util/log.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/result.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <compare>
|
||||
#include <condition_variable>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace node {
|
||||
|
||||
@@ -76,38 +96,21 @@ void RegenerateCommitments(CBlock& block, ChainstateManager& chainman)
|
||||
block.hashMerkleRoot = BlockMerkleRoot(block);
|
||||
}
|
||||
|
||||
static BlockAssembler::Options ClampOptions(BlockAssembler::Options options)
|
||||
{
|
||||
// Apply DEFAULT_BLOCK_RESERVED_WEIGHT when the caller left it unset.
|
||||
options.block_reserved_weight = std::clamp<size_t>(options.block_reserved_weight.value_or(DEFAULT_BLOCK_RESERVED_WEIGHT), MINIMUM_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT);
|
||||
options.coinbase_output_max_additional_sigops = std::clamp<size_t>(options.coinbase_output_max_additional_sigops, 0, MAX_BLOCK_SIGOPS_COST);
|
||||
// Limit weight to between block_reserved_weight and MAX_BLOCK_WEIGHT for sanity:
|
||||
// block_reserved_weight can safely exceed -blockmaxweight, but the rest of the block template will be empty.
|
||||
options.nBlockMaxWeight = std::clamp<size_t>(options.nBlockMaxWeight, *options.block_reserved_weight, MAX_BLOCK_WEIGHT);
|
||||
return options;
|
||||
}
|
||||
|
||||
BlockAssembler::BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options)
|
||||
BlockAssembler::BlockAssembler(Chainstate& chainstate,
|
||||
const CTxMemPool* mempool,
|
||||
BlockCreateOptions options)
|
||||
: chainparams{chainstate.m_chainman.GetParams()},
|
||||
m_mempool{options.use_mempool ? mempool : nullptr},
|
||||
m_chainstate{chainstate},
|
||||
m_options{ClampOptions(options)}
|
||||
m_options{[&] {
|
||||
if (auto result{CheckMiningOptions(options, /*use_argnames=*/false)}; !result) {
|
||||
throw std::runtime_error(util::ErrorString(result).original);
|
||||
}
|
||||
return FlattenMiningOptions(std::move(options));
|
||||
}()}
|
||||
{
|
||||
}
|
||||
|
||||
void ApplyArgsManOptions(const ArgsManager& args, BlockAssembler::Options& options)
|
||||
{
|
||||
// Block resource limits
|
||||
options.nBlockMaxWeight = args.GetIntArg("-blockmaxweight", options.nBlockMaxWeight);
|
||||
if (const auto blockmintxfee{args.GetArg("-blockmintxfee")}) {
|
||||
if (const auto parsed{ParseMoney(*blockmintxfee)}) options.blockMinFeeRate = CFeeRate{*parsed};
|
||||
}
|
||||
options.print_modified_fee = args.GetBoolArg("-printpriority", options.print_modified_fee);
|
||||
if (!options.block_reserved_weight) {
|
||||
options.block_reserved_weight = args.GetIntArg("-blockreservedweight");
|
||||
}
|
||||
}
|
||||
|
||||
void BlockAssembler::resetBlock()
|
||||
{
|
||||
// Reserve space for fixed-size block header, txs count, and coinbase tx.
|
||||
@@ -241,7 +244,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock()
|
||||
|
||||
bool BlockAssembler::TestChunkBlockLimits(FeePerWeight chunk_feerate, int64_t chunk_sigops_cost) const
|
||||
{
|
||||
if (nBlockWeight + chunk_feerate.size >= m_options.nBlockMaxWeight) {
|
||||
if (nBlockWeight + chunk_feerate.size >= m_options.block_max_weight) {
|
||||
return false;
|
||||
}
|
||||
if (nBlockSigOpsCost + chunk_sigops_cost >= MAX_BLOCK_SIGOPS_COST) {
|
||||
@@ -272,7 +275,7 @@ void BlockAssembler::AddToBlock(const CTxMemPoolEntry& entry)
|
||||
nBlockSigOpsCost += entry.GetSigOpCost();
|
||||
nFees += entry.GetFee();
|
||||
|
||||
if (m_options.print_modified_fee) {
|
||||
if (*m_options.print_modified_fee) {
|
||||
LogInfo("fee rate %s txid %s\n",
|
||||
CFeeRate(entry.GetModifiedFee(), entry.GetTxSize()).ToString(),
|
||||
entry.GetTx().GetHash().ToString());
|
||||
@@ -298,7 +301,7 @@ void BlockAssembler::addChunks()
|
||||
|
||||
while (selected_transactions.size() > 0) {
|
||||
// Check to see if min fee rate is still respected.
|
||||
if (ByRatio{chunk_feerate_vsize} < ByRatio{m_options.blockMinFeeRate.GetFeePerVSize()}) {
|
||||
if (ByRatio{chunk_feerate_vsize} < ByRatio{m_options.block_min_fee_rate->GetFeePerVSize()}) {
|
||||
// Everything else we might consider has a lower feerate
|
||||
return;
|
||||
}
|
||||
@@ -315,7 +318,7 @@ void BlockAssembler::addChunks()
|
||||
++nConsecutiveFailed;
|
||||
|
||||
if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
|
||||
BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.nBlockMaxWeight) {
|
||||
BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.block_max_weight) {
|
||||
// Give up if we're close to full and haven't succeeded in a while
|
||||
return;
|
||||
}
|
||||
@@ -365,8 +368,8 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
|
||||
KernelNotifications& kernel_notifications,
|
||||
CTxMemPool* mempool,
|
||||
const std::unique_ptr<CBlockTemplate>& block_template,
|
||||
const BlockWaitOptions& options,
|
||||
const BlockAssembler::Options& assemble_options,
|
||||
const BlockWaitOptions& wait_options,
|
||||
const BlockCreateOptions& create_options,
|
||||
bool& interrupt_wait)
|
||||
{
|
||||
// Delay calculating the current template fees, just in case a new block
|
||||
@@ -376,7 +379,7 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
|
||||
// Alternate waiting for a new tip and checking if fees have risen.
|
||||
// The latter check is expensive so we only run it once per second.
|
||||
auto now{NodeClock::now()};
|
||||
const auto deadline = now + options.timeout;
|
||||
const auto deadline = now + wait_options.timeout;
|
||||
const MillisecondsDouble tick{1000};
|
||||
const bool allow_min_difficulty{chainman.GetParams().GetConsensus().fPowAllowMinDifficultyBlocks};
|
||||
|
||||
@@ -423,12 +426,12 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
|
||||
*
|
||||
* We'll also create a new template if the tip changed during this iteration.
|
||||
*/
|
||||
if (options.fee_threshold < MAX_MONEY || tip_changed) {
|
||||
if (wait_options.fee_threshold < MAX_MONEY || tip_changed) {
|
||||
auto new_tmpl{BlockAssembler{
|
||||
chainman.ActiveChainstate(),
|
||||
mempool,
|
||||
assemble_options}
|
||||
.CreateNewBlock()};
|
||||
create_options
|
||||
}.CreateNewBlock()};
|
||||
|
||||
// If the tip changed, return the new template regardless of its fees.
|
||||
if (tip_changed) return new_tmpl;
|
||||
@@ -440,8 +443,8 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
|
||||
|
||||
// Check if fees increased enough to return the new template
|
||||
const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(), CAmount{0});
|
||||
Assume(options.fee_threshold != MAX_MONEY);
|
||||
if (new_fees >= current_fees + options.fee_threshold) return new_tmpl;
|
||||
Assume(wait_options.fee_threshold != MAX_MONEY);
|
||||
if (new_fees >= current_fees + wait_options.fee_threshold) return new_tmpl;
|
||||
}
|
||||
|
||||
now = NodeClock::now();
|
||||
|
||||
@@ -6,39 +6,38 @@
|
||||
#ifndef BITCOIN_NODE_MINER_H
|
||||
#define BITCOIN_NODE_MINER_H
|
||||
|
||||
#include <interfaces/types.h>
|
||||
#include <node/types.h>
|
||||
#include <policy/policy.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <threadsafety.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/feefrac.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/indexed_by.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/tag.hpp>
|
||||
#include <boost/multi_index_container.hpp>
|
||||
|
||||
class ArgsManager;
|
||||
class CBlockIndex;
|
||||
class CChainParams;
|
||||
class CScript;
|
||||
class Chainstate;
|
||||
class ChainstateManager;
|
||||
|
||||
namespace Consensus { struct Params; };
|
||||
namespace Consensus {
|
||||
struct Params;
|
||||
} // namespace Consensus
|
||||
class uint256;
|
||||
namespace interfaces {
|
||||
struct BlockRef;
|
||||
} // namespace interfaces
|
||||
|
||||
using interfaces::BlockRef;
|
||||
|
||||
namespace node {
|
||||
class KernelNotifications;
|
||||
|
||||
static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
|
||||
|
||||
struct CBlockTemplate
|
||||
{
|
||||
CBlock block;
|
||||
@@ -78,16 +77,9 @@ private:
|
||||
Chainstate& m_chainstate;
|
||||
|
||||
public:
|
||||
struct Options : BlockCreateOptions {
|
||||
// Configuration parameters for the block size
|
||||
size_t nBlockMaxWeight{DEFAULT_BLOCK_MAX_WEIGHT};
|
||||
CFeeRate blockMinFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
|
||||
// Whether to call TestBlockValidity() at the end of CreateNewBlock().
|
||||
bool test_block_validity{true};
|
||||
bool print_modified_fee{DEFAULT_PRINT_MODIFIED_FEE};
|
||||
};
|
||||
|
||||
explicit BlockAssembler(Chainstate& chainstate, const CTxMemPool* mempool, const Options& options);
|
||||
explicit BlockAssembler(Chainstate& chainstate,
|
||||
const CTxMemPool* mempool,
|
||||
BlockCreateOptions create_options);
|
||||
|
||||
/** Construct a new block template */
|
||||
std::unique_ptr<CBlockTemplate> CreateNewBlock();
|
||||
@@ -98,7 +90,7 @@ public:
|
||||
inline static std::optional<int64_t> m_last_block_weight{};
|
||||
|
||||
private:
|
||||
const Options m_options;
|
||||
const BlockCreateOptions m_options;
|
||||
|
||||
// utility functions
|
||||
/** Clear the block's state and prepare for assembling a new block */
|
||||
@@ -134,9 +126,6 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
||||
/** Update an old GenerateCoinbaseCommitment from CreateNewBlock after the block txs have changed */
|
||||
void RegenerateCommitments(CBlock& block, ChainstateManager& chainman);
|
||||
|
||||
/** Apply -blockmintxfee and -blockmaxweight options from ArgsManager to BlockAssembler options. */
|
||||
void ApplyArgsManOptions(const ArgsManager& gArgs, BlockAssembler::Options& options);
|
||||
|
||||
/* Compute the block's merkle root, insert or replace the coinbase transaction and the merkle root into the block */
|
||||
void AddMerkleRootAndCoinbase(CBlock& block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce);
|
||||
|
||||
@@ -151,8 +140,8 @@ std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(ChainstateManager& chainma
|
||||
KernelNotifications& kernel_notifications,
|
||||
CTxMemPool* mempool,
|
||||
const std::unique_ptr<CBlockTemplate>& block_template,
|
||||
const BlockWaitOptions& options,
|
||||
const BlockAssembler::Options& assemble_options,
|
||||
const BlockWaitOptions& wait_options,
|
||||
const BlockCreateOptions& create_options,
|
||||
bool& interrupt_wait);
|
||||
|
||||
/* Locks cs_main and returns the block hash and block height of the active chain if it exists; otherwise, returns nullopt.*/
|
||||
|
||||
@@ -5,13 +5,12 @@
|
||||
#ifndef BITCOIN_NODE_MINI_MINER_H
|
||||
#define BITCOIN_NODE_MINI_MINER_H
|
||||
|
||||
#include <attributes.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
99
src/node/mining_args.cpp
Normal file
99
src/node/mining_args.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <node/mining_args.h>
|
||||
|
||||
#include <common/args.h>
|
||||
#include <common/messages.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <tinyformat.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/result.h>
|
||||
#include <util/translation.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using common::AmountErrMsg;
|
||||
using util::Error;
|
||||
using util::Result;
|
||||
|
||||
namespace node {
|
||||
|
||||
Result<void> CheckMiningOptions(BlockCreateOptions options, bool use_argnames)
|
||||
{
|
||||
options = FlattenMiningOptions(std::move(options));
|
||||
if (*options.block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
|
||||
return Error{Untranslated(strprintf("%s (%d) is lower than minimum safety value of (%d)",
|
||||
use_argnames ? "-blockreservedweight" : "block_reserved_weight",
|
||||
*options.block_reserved_weight, MINIMUM_BLOCK_RESERVED_WEIGHT))};
|
||||
}
|
||||
if (*options.block_reserved_weight > MAX_BLOCK_WEIGHT) {
|
||||
return Error{Untranslated(strprintf("%s (%d) exceeds consensus maximum block weight (%d)",
|
||||
use_argnames ? "-blockreservedweight" : "block_reserved_weight",
|
||||
*options.block_reserved_weight, MAX_BLOCK_WEIGHT))};
|
||||
}
|
||||
if (*options.block_max_weight > MAX_BLOCK_WEIGHT) {
|
||||
return Error{Untranslated(strprintf("%s (%d) exceeds consensus maximum block weight (%d)",
|
||||
use_argnames ? "-blockmaxweight" : "block_max_weight",
|
||||
*options.block_max_weight, MAX_BLOCK_WEIGHT))};
|
||||
}
|
||||
if (*options.block_reserved_weight > *options.block_max_weight) {
|
||||
return Error{Untranslated(strprintf("%s (%d) exceeds %s (%d)",
|
||||
use_argnames ? "-blockreservedweight" : "block_reserved_weight",
|
||||
*options.block_reserved_weight,
|
||||
use_argnames ? "-blockmaxweight" : "block_max_weight",
|
||||
*options.block_max_weight))};
|
||||
}
|
||||
if (options.coinbase_output_max_additional_sigops > MAX_BLOCK_SIGOPS_COST) {
|
||||
return Error{Untranslated(strprintf("%s (%zu) exceeds consensus maximum block sigops cost (%d)",
|
||||
"coinbase_output_max_additional_sigops",
|
||||
options.coinbase_output_max_additional_sigops, MAX_BLOCK_SIGOPS_COST))};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Result<BlockCreateOptions> ReadMiningArgs(const ArgsManager& args)
|
||||
{
|
||||
BlockCreateOptions options;
|
||||
if (const auto arg{args.GetArg("-blockmintxfee")}) {
|
||||
std::optional<CAmount> block_min_tx_fee{ParseMoney(*arg)};
|
||||
if (!block_min_tx_fee) return Error{AmountErrMsg("blockmintxfee", *arg)};
|
||||
options.block_min_fee_rate = CFeeRate{*block_min_tx_fee};
|
||||
}
|
||||
|
||||
if (const auto arg{args.GetBoolArg("-printpriority")}) options.print_modified_fee = *arg;
|
||||
|
||||
options.block_reserved_weight = args.GetArg<uint64_t>("-blockreservedweight");
|
||||
options.block_max_weight = args.GetArg<uint64_t>("-blockmaxweight");
|
||||
|
||||
if (auto result{CheckMiningOptions(options, /*use_argnames=*/true)}; !result) return Error{util::ErrorString(result)};
|
||||
return options;
|
||||
}
|
||||
|
||||
BlockCreateOptions FlattenMiningOptions(BlockCreateOptions options)
|
||||
{
|
||||
if (!options.block_min_fee_rate) options.block_min_fee_rate = CFeeRate{DEFAULT_BLOCK_MIN_TX_FEE};
|
||||
if (!options.print_modified_fee) options.print_modified_fee = DEFAULT_PRINT_MODIFIED_FEE;
|
||||
if (!options.block_reserved_weight) options.block_reserved_weight = DEFAULT_BLOCK_RESERVED_WEIGHT;
|
||||
if (!options.block_max_weight) options.block_max_weight = DEFAULT_BLOCK_MAX_WEIGHT;
|
||||
return options;
|
||||
}
|
||||
|
||||
BlockCreateOptions MergeMiningOptions(BlockCreateOptions x, const BlockCreateOptions& y)
|
||||
{
|
||||
if (!x.block_min_fee_rate) x.block_min_fee_rate = y.block_min_fee_rate;
|
||||
if (!x.print_modified_fee) x.print_modified_fee = y.print_modified_fee;
|
||||
if (!x.block_reserved_weight) x.block_reserved_weight = y.block_reserved_weight;
|
||||
if (!x.block_max_weight) x.block_max_weight = y.block_max_weight;
|
||||
return x;
|
||||
}
|
||||
|
||||
} // namespace node
|
||||
37
src/node/mining_args.h
Normal file
37
src/node/mining_args.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_NODE_MINING_ARGS_H
|
||||
#define BITCOIN_NODE_MINING_ARGS_H
|
||||
|
||||
#include <node/mining_types.h>
|
||||
#include <util/result.h>
|
||||
|
||||
class ArgsManager;
|
||||
|
||||
namespace node {
|
||||
|
||||
static const bool DEFAULT_PRINT_MODIFIED_FEE = false;
|
||||
|
||||
/**
|
||||
* Read the mining options set in \p args. Returns an error if one was
|
||||
* encountered.
|
||||
*/
|
||||
[[nodiscard]] util::Result<BlockCreateOptions> ReadMiningArgs(const ArgsManager& args);
|
||||
|
||||
/** Check option values for validity. Returns an error for invalid values. */
|
||||
[[nodiscard]] util::Result<void> CheckMiningOptions(BlockCreateOptions options, bool use_argnames);
|
||||
|
||||
/** Replace null optional values with their hardcoded defaults. */
|
||||
[[nodiscard]] BlockCreateOptions FlattenMiningOptions(BlockCreateOptions options);
|
||||
|
||||
/**
|
||||
* Merge two BlockCreateOptions structs, replacing null values in \p x with
|
||||
* non-null values from \p y.
|
||||
*/
|
||||
[[nodiscard]] BlockCreateOptions MergeMiningOptions(BlockCreateOptions x, const BlockCreateOptions& y);
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif // BITCOIN_NODE_MINING_ARGS_H
|
||||
178
src/node/mining_types.h
Normal file
178
src/node/mining_types.h
Normal file
@@ -0,0 +1,178 @@
|
||||
// Copyright (c) The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
//! @file node/mining_types.h is used externally by mining IPC clients, so it should
|
||||
//! only declare simple data definitions.
|
||||
//!
|
||||
//! Avoid declaring functions or classes with methods here unless they are
|
||||
//! header-only or provided by the util library.
|
||||
|
||||
#ifndef BITCOIN_NODE_MINING_TYPES_H
|
||||
#define BITCOIN_NODE_MINING_TYPES_H
|
||||
|
||||
#include <consensus/amount.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <uint256.h>
|
||||
#include <util/time.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace node {
|
||||
|
||||
/**
|
||||
* Block template creation options. These override node defaults, but can't
|
||||
* exceed node limits (e.g. block_reserved_weight can't exceed max block weight).
|
||||
*/
|
||||
struct BlockCreateOptions {
|
||||
/**
|
||||
* Set false to omit mempool transactions
|
||||
*/
|
||||
bool use_mempool{true};
|
||||
/**
|
||||
* Minimum fee rate for transactions to be included. Providing a value
|
||||
* overrides the -blockmintxfee startup setting.
|
||||
*/
|
||||
std::optional<CFeeRate> block_min_fee_rate{};
|
||||
/**
|
||||
* Whether to log the fee rate of each transaction when it is added to the
|
||||
* block template. Providing a value overrides the -printpriority startup
|
||||
* setting.
|
||||
*/
|
||||
std::optional<bool> print_modified_fee{};
|
||||
/**
|
||||
* The default reserved weight for the fixed-size block header,
|
||||
* transaction count and coinbase transaction. Minimum: 2000 weight units
|
||||
* (MINIMUM_BLOCK_RESERVED_WEIGHT).
|
||||
*
|
||||
* Providing a value overrides the `-blockreservedweight` startup setting.
|
||||
* Cap'n Proto IPC clients currently cannot leave this field unset, so they
|
||||
* always provide a value.
|
||||
*/
|
||||
std::optional<uint64_t> block_reserved_weight{};
|
||||
/**
|
||||
* Maximum block weight, defaults to -maxblockweight
|
||||
*
|
||||
* Must not be lower than block_reserved_weight. Setting this equal to
|
||||
* block_reserved_weight leaves no room for non-coinbase transactions.
|
||||
*/
|
||||
std::optional<uint64_t> block_max_weight{};
|
||||
/**
|
||||
* The maximum additional sigops which the pool will add in coinbase
|
||||
* transaction outputs.
|
||||
*/
|
||||
size_t coinbase_output_max_additional_sigops{DEFAULT_COINBASE_OUTPUT_MAX_ADDITIONAL_SIGOPS};
|
||||
/**
|
||||
* Script to put in the coinbase transaction. The default is an
|
||||
* anyone-can-spend dummy.
|
||||
*
|
||||
* Should only be used for tests, when the default doesn't suffice.
|
||||
*
|
||||
* Note that higher level code like the getblocktemplate RPC may omit the
|
||||
* coinbase transaction entirely. It's instead constructed by pool software
|
||||
* using fields like coinbasevalue, coinbaseaux and default_witness_commitment.
|
||||
* This software typically also controls the payout outputs, even for solo
|
||||
* mining.
|
||||
*
|
||||
* The size and sigops are not checked against
|
||||
* coinbase_max_additional_weight and coinbase_output_max_additional_sigops.
|
||||
*/
|
||||
CScript coinbase_output_script{CScript() << OP_TRUE};
|
||||
/**
|
||||
* Whether to call TestBlockValidity() at the end of CreateNewBlock().
|
||||
* Should only be used for tests / benchmarks.
|
||||
*/
|
||||
bool test_block_validity{true};
|
||||
};
|
||||
|
||||
struct BlockWaitOptions {
|
||||
/**
|
||||
* How long to wait before returning nullptr instead of a new template.
|
||||
* Default is to wait forever.
|
||||
*/
|
||||
MillisecondsDouble timeout{MillisecondsDouble::max()};
|
||||
|
||||
/**
|
||||
* The wait method will not return a new template unless it has fees at
|
||||
* least fee_threshold sats higher than the current template, or unless
|
||||
* the chain tip changes and the previous template is no longer valid.
|
||||
*
|
||||
* A caller may not be interested in templates with higher fees, and
|
||||
* determining whether fee_threshold is reached is also expensive. So as
|
||||
* an optimization, when fee_threshold is set to MAX_MONEY (default), the
|
||||
* implementation is able to be much more efficient, skipping expensive
|
||||
* checks and only returning new templates when the chain tip changes.
|
||||
*/
|
||||
CAmount fee_threshold{MAX_MONEY};
|
||||
};
|
||||
|
||||
struct BlockCheckOptions {
|
||||
/**
|
||||
* Set false to omit the merkle root check
|
||||
*/
|
||||
bool check_merkle_root{true};
|
||||
|
||||
/**
|
||||
* Set false to omit the proof-of-work check
|
||||
*/
|
||||
bool check_pow{true};
|
||||
};
|
||||
|
||||
/**
|
||||
* Template containing all coinbase transaction fields that are set by our
|
||||
* miner code. Clients are expected to add their own outputs and typically
|
||||
* also expand the scriptSig.
|
||||
*/
|
||||
struct CoinbaseTx {
|
||||
/* nVersion */
|
||||
uint32_t version;
|
||||
/* nSequence for the only coinbase transaction input */
|
||||
uint32_t sequence;
|
||||
/**
|
||||
* Prefix which needs to be placed at the beginning of the scriptSig.
|
||||
* Clients may append extra data to this as long as the overall scriptSig
|
||||
* size is 100 bytes or less, to avoid the block being rejected with
|
||||
* "bad-cb-length" error. At heights <= 16 the BIP 34 height push is only
|
||||
* one byte long, so clients must append at least one additional byte to
|
||||
* meet the consensus minimum scriptSig length of two bytes.
|
||||
*
|
||||
* Currently with BIP 34, the prefix is guaranteed to be less than 8 bytes,
|
||||
* but future soft forks could require longer prefixes.
|
||||
*/
|
||||
CScript script_sig_prefix;
|
||||
/**
|
||||
* The first (and only) witness stack element of the coinbase input.
|
||||
*
|
||||
* Omitted for block templates without witness data.
|
||||
*
|
||||
* This is currently the BIP 141 witness reserved value, and can be chosen
|
||||
* arbitrarily by the node, but future soft forks may constrain it.
|
||||
*/
|
||||
std::optional<uint256> witness;
|
||||
/**
|
||||
* Block subsidy plus fees, minus any non-zero required_outputs.
|
||||
*
|
||||
* Currently there are no non-zero required_outputs, so block_reward_remaining
|
||||
* is the entire block reward. See also required_outputs.
|
||||
*/
|
||||
CAmount block_reward_remaining;
|
||||
/*
|
||||
* To be included as the last outputs in the coinbase transaction.
|
||||
* Currently this is only the witness commitment OP_RETURN, but future
|
||||
* softforks or a custom mining patch could add more.
|
||||
*
|
||||
* The dummy output that spends the full reward is excluded.
|
||||
*/
|
||||
std::vector<CTxOut> required_outputs;
|
||||
uint32_t lock_time;
|
||||
};
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif // BITCOIN_NODE_MINING_TYPES_H
|
||||
129
src/node/types.h
129
src/node/types.h
@@ -13,16 +13,7 @@
|
||||
#ifndef BITCOIN_NODE_TYPES_H
|
||||
#define BITCOIN_NODE_TYPES_H
|
||||
|
||||
#include <consensus/amount.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <uint256.h>
|
||||
#include <util/time.h>
|
||||
#include <vector>
|
||||
|
||||
namespace node {
|
||||
enum class TransactionError {
|
||||
@@ -36,126 +27,6 @@ enum class TransactionError {
|
||||
INVALID_PACKAGE,
|
||||
};
|
||||
|
||||
struct BlockCreateOptions {
|
||||
/**
|
||||
* Set false to omit mempool transactions
|
||||
*/
|
||||
bool use_mempool{true};
|
||||
/**
|
||||
* The default reserved weight for the fixed-size block header,
|
||||
* transaction count and coinbase transaction. Minimum: 2000 weight units
|
||||
* (MINIMUM_BLOCK_RESERVED_WEIGHT).
|
||||
*
|
||||
* Providing a value overrides the `-blockreservedweight` startup setting.
|
||||
* Cap'n Proto IPC clients currently cannot leave this field unset, so they
|
||||
* always provide a value.
|
||||
*/
|
||||
std::optional<size_t> block_reserved_weight{};
|
||||
/**
|
||||
* The maximum additional sigops which the pool will add in coinbase
|
||||
* transaction outputs.
|
||||
*/
|
||||
size_t coinbase_output_max_additional_sigops{DEFAULT_COINBASE_OUTPUT_MAX_ADDITIONAL_SIGOPS};
|
||||
/**
|
||||
* Script to put in the coinbase transaction. The default is an
|
||||
* anyone-can-spend dummy.
|
||||
*
|
||||
* Should only be used for tests, when the default doesn't suffice.
|
||||
*
|
||||
* Note that higher level code like the getblocktemplate RPC may omit the
|
||||
* coinbase transaction entirely. It's instead constructed by pool software
|
||||
* using fields like coinbasevalue, coinbaseaux and default_witness_commitment.
|
||||
* This software typically also controls the payout outputs, even for solo
|
||||
* mining.
|
||||
*
|
||||
* The size and sigops are not checked against
|
||||
* coinbase_max_additional_weight and coinbase_output_max_additional_sigops.
|
||||
*/
|
||||
CScript coinbase_output_script{CScript() << OP_TRUE};
|
||||
};
|
||||
|
||||
struct BlockWaitOptions {
|
||||
/**
|
||||
* How long to wait before returning nullptr instead of a new template.
|
||||
* Default is to wait forever.
|
||||
*/
|
||||
MillisecondsDouble timeout{MillisecondsDouble::max()};
|
||||
|
||||
/**
|
||||
* The wait method will not return a new template unless it has fees at
|
||||
* least fee_threshold sats higher than the current template, or unless
|
||||
* the chain tip changes and the previous template is no longer valid.
|
||||
*
|
||||
* A caller may not be interested in templates with higher fees, and
|
||||
* determining whether fee_threshold is reached is also expensive. So as
|
||||
* an optimization, when fee_threshold is set to MAX_MONEY (default), the
|
||||
* implementation is able to be much more efficient, skipping expensive
|
||||
* checks and only returning new templates when the chain tip changes.
|
||||
*/
|
||||
CAmount fee_threshold{MAX_MONEY};
|
||||
};
|
||||
|
||||
struct BlockCheckOptions {
|
||||
/**
|
||||
* Set false to omit the merkle root check
|
||||
*/
|
||||
bool check_merkle_root{true};
|
||||
|
||||
/**
|
||||
* Set false to omit the proof-of-work check
|
||||
*/
|
||||
bool check_pow{true};
|
||||
};
|
||||
|
||||
/**
|
||||
* Template containing all coinbase transaction fields that are set by our
|
||||
* miner code. Clients are expected to add their own outputs and typically
|
||||
* also expand the scriptSig.
|
||||
*/
|
||||
struct CoinbaseTx {
|
||||
/* nVersion */
|
||||
uint32_t version;
|
||||
/* nSequence for the only coinbase transaction input */
|
||||
uint32_t sequence;
|
||||
/**
|
||||
* Prefix which needs to be placed at the beginning of the scriptSig.
|
||||
* Clients may append extra data to this as long as the overall scriptSig
|
||||
* size is 100 bytes or less, to avoid the block being rejected with
|
||||
* "bad-cb-length" error. At heights <= 16 the BIP 34 height push is only
|
||||
* one byte long, so clients must append at least one additional byte to
|
||||
* meet the consensus minimum scriptSig length of two bytes.
|
||||
*
|
||||
* Currently with BIP 34, the prefix is guaranteed to be less than 8 bytes,
|
||||
* but future soft forks could require longer prefixes.
|
||||
*/
|
||||
CScript script_sig_prefix;
|
||||
/**
|
||||
* The first (and only) witness stack element of the coinbase input.
|
||||
*
|
||||
* Omitted for block templates without witness data.
|
||||
*
|
||||
* This is currently the BIP 141 witness reserved value, and can be chosen
|
||||
* arbitrarily by the node, but future soft forks may constrain it.
|
||||
*/
|
||||
std::optional<uint256> witness;
|
||||
/**
|
||||
* Block subsidy plus fees, minus any non-zero required_outputs.
|
||||
*
|
||||
* Currently there are no non-zero required_outputs, so block_reward_remaining
|
||||
* is the entire block reward. See also required_outputs.
|
||||
*/
|
||||
CAmount block_reward_remaining;
|
||||
/*
|
||||
* To be included as the last outputs in the coinbase transaction.
|
||||
* Currently this is only the witness commitment OP_RETURN, but future
|
||||
* softforks or a custom mining patch could add more.
|
||||
*
|
||||
* The dummy output that spends the full reward is excluded.
|
||||
*/
|
||||
std::vector<CTxOut> required_outputs;
|
||||
uint32_t lock_time;
|
||||
};
|
||||
|
||||
/**
|
||||
* How to broadcast a local transaction.
|
||||
* Used to influence `BroadcastTransaction()` and its callers.
|
||||
|
||||
@@ -5,46 +5,77 @@
|
||||
|
||||
#include <bitcoin-build-config.h> // IWYU pragma: keep
|
||||
|
||||
#include <interfaces/mining.h>
|
||||
|
||||
#include <addresstype.h>
|
||||
#include <arith_uint256.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <chainparamsbase.h>
|
||||
#include <common/system.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <core_io.h>
|
||||
#include <deploymentinfo.h>
|
||||
#include <deploymentstatus.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <crypto/hex_base.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <key_io.h>
|
||||
#include <net.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/context.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_args.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <node/warnings.h>
|
||||
#include <policy/ephemeral_policy.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <rpc/blockchain.h>
|
||||
#include <rpc/mining.h>
|
||||
#include <rpc/protocol.h>
|
||||
#include <rpc/request.h>
|
||||
#include <rpc/server.h>
|
||||
#include <rpc/server_util.h>
|
||||
#include <rpc/util.h>
|
||||
#include <script/descriptor.h>
|
||||
#include <script/script.h>
|
||||
#include <script/signingprovider.h>
|
||||
#include <serialize.h>
|
||||
#include <streams.h>
|
||||
#include <sync.h>
|
||||
#include <tinyformat.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <univalue.h>
|
||||
#include <util/chaintype.h>
|
||||
#include <util/check.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/string.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using interfaces::BlockRef;
|
||||
using interfaces::BlockTemplate;
|
||||
@@ -463,7 +494,7 @@ static RPCMethod getmininginfo()
|
||||
CBlockIndex& tip{*CHECK_NONFATAL(active_chain.Tip())};
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("blocks", active_chain.Height());
|
||||
obj.pushKV("blocks", active_chain.Height());
|
||||
if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
|
||||
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
|
||||
obj.pushKV("bits", strprintf("%08x", tip.nBits));
|
||||
@@ -471,9 +502,8 @@ static RPCMethod getmininginfo()
|
||||
obj.pushKV("target", GetTarget(tip, chainman.GetConsensus().powLimit).GetHex());
|
||||
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
|
||||
obj.pushKV("pooledtx", mempool.size());
|
||||
BlockAssembler::Options assembler_options;
|
||||
ApplyArgsManOptions(*node.args, assembler_options);
|
||||
obj.pushKV("blockmintxfee", ValueFromAmount(assembler_options.blockMinFeeRate.GetFeePerK()));
|
||||
const auto mining_options{node::FlattenMiningOptions(node.mining_args)};
|
||||
obj.pushKV("blockmintxfee", ValueFromAmount(CHECK_NONFATAL(mining_options.block_min_fee_rate)->GetFeePerK()));
|
||||
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());
|
||||
|
||||
UniValue next(UniValue::VOBJ);
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef BITCOIN_RPC_MINING_H
|
||||
#define BITCOIN_RPC_MINING_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/** Default max iterations to try in RPC generatetodescriptor, generatetoaddress, and generateblock. */
|
||||
static const uint64_t DEFAULT_MAX_TRIES{1000000};
|
||||
|
||||
|
||||
@@ -4,25 +4,45 @@
|
||||
|
||||
#include <addresstype.h>
|
||||
#include <blockfilter.h>
|
||||
#include <chainparams.h>
|
||||
#include <chain.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <index/base.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <node/miner.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <key.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/blockfilter.h>
|
||||
#include <test/util/common.h>
|
||||
#include <test/util/common.h> // IWYU pragma: keep
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/byte_units.h>
|
||||
#include <tinyformat.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <future>
|
||||
|
||||
using node::BlockAssembler;
|
||||
#include <compare>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using node::BlockManager;
|
||||
using node::CBlockTemplate;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(blockfilter_index_tests)
|
||||
|
||||
@@ -69,10 +89,12 @@ CBlock BuildChainTestingSetup::CreateBlock(const CBlockIndex* prev,
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
CBlock& block = pblocktemplate->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
block.hashPrevBlock = prev->GetBlockHash();
|
||||
block.nTime = prev->nTime + 1;
|
||||
|
||||
|
||||
@@ -2,18 +2,31 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <index/coinstatsindex.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <kernel/coinstats.h>
|
||||
#include <kernel/types.h>
|
||||
#include <key.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/validation.h>
|
||||
#include <util/byte_units.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <vector>
|
||||
|
||||
using kernel::ChainstateRole;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
|
||||
@@ -83,7 +96,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
||||
CBlockIndex* new_block_index = nullptr;
|
||||
{
|
||||
const CScript script_pub_key{CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG};
|
||||
const CBlock block = this->CreateBlock({}, script_pub_key, chainstate);
|
||||
const CBlock block = this->CreateBlock({}, script_pub_key);
|
||||
|
||||
new_block = std::make_shared<CBlock>(block);
|
||||
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
#include <net_processing.h>
|
||||
#include <netmessagemaker.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <policy/truc_policy.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <protocol.h>
|
||||
#include <script/script.h>
|
||||
#include <serialize.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
@@ -43,7 +44,6 @@
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <boost/multi_index/detail/hash_index_iterator.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
@@ -52,7 +52,6 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -121,7 +120,7 @@ void ResetChainmanAndMempool(TestingSetup& setup)
|
||||
setup.m_make_chainman();
|
||||
setup.LoadVerifyActivateChainstate();
|
||||
|
||||
node::BlockAssembler::Options options;
|
||||
node::BlockCreateOptions options;
|
||||
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
|
||||
g_mature_coinbase.clear();
|
||||
|
||||
@@ -2,27 +2,35 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <node/mini_miner.h>
|
||||
|
||||
#include <consensus/amount.h>
|
||||
#include <kernel/cs_main.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/fuzz/util/mempool.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/time.h>
|
||||
#include <test/util/txmempool.h>
|
||||
|
||||
#include <node/miner.h>
|
||||
#include <node/mini_miner.h>
|
||||
#include <node/types.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -2,26 +2,50 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chain.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <node/context.h>
|
||||
#include <node/mempool_args.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_types.h> // IWYU pragma: keep
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/packages.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
#include <policy/truc_policy.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/fuzz/util/mempool.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/check.h>
|
||||
#include <util/rbf.h>
|
||||
#include <util/hasher.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
using node::BlockAssembler;
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
using node::NodeContext;
|
||||
|
||||
namespace {
|
||||
@@ -44,11 +68,10 @@ void initialize_tx_pool()
|
||||
g_setup = testing_setup.get();
|
||||
SetMockTime(WITH_LOCK(g_setup->m_node.chainman->GetMutex(), return g_setup->m_node.chainman->ActiveTip()->Time()));
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_EMPTY;
|
||||
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, options)};
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_EMPTY,
|
||||
})};
|
||||
if (i < COINBASE_MATURITY) {
|
||||
// Remember the txids to avoid expensive disk access later on
|
||||
g_outpoints_coinbase_init_mature.push_back(prevout);
|
||||
|
||||
@@ -2,14 +2,16 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <addrman.h>
|
||||
#include <banman.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <kernel/chainparams.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <node/warnings.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <protocol.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
@@ -17,18 +19,25 @@
|
||||
#include <test/fuzz/util/net.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/net.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/time.h>
|
||||
#include <test/util/validation.h>
|
||||
#include <util/check.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
@@ -42,7 +51,7 @@ void ResetChainman(TestingSetup& setup)
|
||||
setup.m_make_chainman();
|
||||
setup.LoadVerifyActivateChainstate();
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||
node::BlockAssembler::Options options;
|
||||
node::BlockCreateOptions options;
|
||||
MineBlock(setup.m_node, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <addrman.h>
|
||||
#include <banman.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <kernel/chainparams.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <node/warnings.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <protocol.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
@@ -16,13 +19,18 @@
|
||||
#include <test/fuzz/util/net.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/net.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/time.h>
|
||||
#include <test/util/validation.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -36,7 +44,7 @@ void ResetChainman(TestingSetup& setup)
|
||||
setup.m_node.chainman.reset();
|
||||
setup.m_make_chainman();
|
||||
setup.LoadVerifyActivateChainstate();
|
||||
node::BlockAssembler::Options options;
|
||||
node::BlockCreateOptions options;
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||
MineBlock(setup.m_node, options);
|
||||
}
|
||||
|
||||
@@ -2,26 +2,53 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chain.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <node/context.h>
|
||||
#include <node/mempool_args.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/packages.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/truc_policy.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/fuzz/util/mempool.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/check.h>
|
||||
#include <util/rbf.h>
|
||||
#include <util/string.h>
|
||||
#include <util/time.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
using node::NodeContext;
|
||||
using util::ToString;
|
||||
|
||||
@@ -46,11 +73,10 @@ void initialize_tx_pool()
|
||||
g_setup = testing_setup.get();
|
||||
SetMockTime(WITH_LOCK(g_setup->m_node.chainman->GetMutex(), return g_setup->m_node.chainman->ActiveTip()->Time()));
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = P2WSH_OP_TRUE;
|
||||
|
||||
for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) {
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, options)};
|
||||
COutPoint prevout{MineBlock(g_setup->m_node, {
|
||||
.coinbase_output_script = P2WSH_OP_TRUE,
|
||||
})};
|
||||
// Remember the txids to avoid expensive disk access later on
|
||||
auto& outpoints = i < COINBASE_MATURITY ?
|
||||
g_outpoints_coinbase_init_mature :
|
||||
@@ -94,9 +120,10 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, Cha
|
||||
{
|
||||
WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
|
||||
{
|
||||
BlockAssembler::Options options;
|
||||
options.nBlockMaxWeight = fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BLOCK_WEIGHT);
|
||||
options.blockMinFeeRate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)};
|
||||
BlockCreateOptions options{
|
||||
.block_min_fee_rate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)},
|
||||
.block_max_weight = fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(DEFAULT_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT),
|
||||
};
|
||||
auto assembler = BlockAssembler{chainstate, &tx_pool, options};
|
||||
auto block_template = assembler.CreateNewBlock();
|
||||
Assert(block_template->block.vtx.size() >= 1);
|
||||
|
||||
@@ -3,23 +3,33 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <kernel/coinstats.h>
|
||||
#include <node/miner.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <streams.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
#include <test/util/mining.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/time.h>
|
||||
#include <util/chaintype.h>
|
||||
#include <util/time.h>
|
||||
#include <txdb.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
|
||||
using node::BlockAssembler;
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
FUZZ_TARGET(utxo_total_supply)
|
||||
{
|
||||
@@ -44,11 +54,11 @@ FUZZ_TARGET(utxo_total_supply)
|
||||
LOCK(chainman.GetMutex());
|
||||
return chainman.ActiveHeight();
|
||||
};
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = CScript() << OP_FALSE;
|
||||
const auto PrepareNextBlock = [&]() {
|
||||
// Use OP_FALSE to avoid BIP30 check from hitting early
|
||||
auto block = PrepareBlock(node, options);
|
||||
auto block = PrepareBlock(node, {
|
||||
.coinbase_output_script = CScript() << OP_FALSE,
|
||||
});
|
||||
// Replace OP_FALSE with OP_TRUE
|
||||
{
|
||||
CMutableTransaction tx{*block->vtx.back()};
|
||||
|
||||
@@ -3,15 +3,28 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <addresstype.h>
|
||||
#include <chain.h>
|
||||
#include <coins.h>
|
||||
#include <common/system.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <interfaces/types.h>
|
||||
#include <kernel/chainparams.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <test/util/random.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <script/script.h>
|
||||
#include <serialize.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/common.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/transaction_utils.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txmempool.h>
|
||||
@@ -23,20 +36,24 @@
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <versionbits.h>
|
||||
#include <pow.h>
|
||||
|
||||
#include <test/util/common.h>
|
||||
#include <test/util/setup_common.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace util::hex_literals;
|
||||
using interfaces::BlockTemplate;
|
||||
using interfaces::Mining;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockCreateOptions;
|
||||
|
||||
namespace miner_tests {
|
||||
struct MinerTestingSetup : public TestingSetup {
|
||||
@@ -115,8 +132,9 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
|
||||
{
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
auto mining{MakeMining()};
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
LOCK(tx_mempool.cs);
|
||||
BOOST_CHECK(tx_mempool.size() == 0);
|
||||
@@ -175,7 +193,12 @@ void MinerTestingSetup::TestPackageSelection(const CScript& scriptPubKey, const
|
||||
BOOST_CHECK(block.vtx[3]->GetHash() == hashMediumFeeTx);
|
||||
|
||||
// Test the inclusion of package feerates in the block template and ensure they are sequential.
|
||||
const auto block_package_feerates = BlockAssembler{m_node.chainman->ActiveChainstate(), &tx_mempool, options}.CreateNewBlock()->m_package_feerates;
|
||||
// Can't use the Mining interface because it needs access to m_package_feerates.
|
||||
const auto block_package_feerates = BlockAssembler{
|
||||
m_node.chainman->ActiveChainstate(),
|
||||
&tx_mempool,
|
||||
m_node.mining_args,
|
||||
}.CreateNewBlock()->m_package_feerates;
|
||||
BOOST_CHECK(block_package_feerates.size() == 2);
|
||||
|
||||
// parent_tx and high_fee_tx are added to the block as a package.
|
||||
@@ -333,8 +356,9 @@ void MinerTestingSetup::TestBasicMining(const CScript& scriptPubKey, const std::
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
{
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
@@ -659,8 +683,9 @@ void MinerTestingSetup::TestPrioritisedMining(const CScript& scriptPubKey, const
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
CTxMemPool& tx_mempool{MakeMempool()};
|
||||
LOCK(tx_mempool.cs);
|
||||
@@ -748,12 +773,20 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
|
||||
// Note that by default, these tests run with size accounting enabled.
|
||||
CScript scriptPubKey = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG;
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
BlockCreateOptions options{
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
};
|
||||
|
||||
// Create and check a simple template
|
||||
std::unique_ptr<BlockTemplate> block_template = mining->createNewBlock(options, /*cooldown=*/false);
|
||||
BOOST_REQUIRE(block_template);
|
||||
|
||||
BlockCreateOptions invalid_options{options};
|
||||
invalid_options.block_max_weight = DEFAULT_BLOCK_RESERVED_WEIGHT - 1;
|
||||
BOOST_CHECK_EXCEPTION(mining->createNewBlock(invalid_options, /*cooldown=*/false),
|
||||
std::runtime_error,
|
||||
HasReason("block_reserved_weight (8000) exceeds block_max_weight (7999)"));
|
||||
|
||||
{
|
||||
CBlock block{block_template->getBlock()};
|
||||
{
|
||||
|
||||
@@ -2,26 +2,39 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <node/miner.h>
|
||||
#include <consensus/params.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <net_processing.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <protocol.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/check.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(peerman_tests, RegTestingSetup)
|
||||
|
||||
/** Window, in blocks, for connecting to NODE_NETWORK_LIMITED peers */
|
||||
static constexpr int64_t NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS = 144;
|
||||
|
||||
static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_time)
|
||||
static void mineBlock(node::NodeContext& node, std::chrono::seconds block_time)
|
||||
{
|
||||
auto curr_time = GetTime<std::chrono::seconds>();
|
||||
node::BlockAssembler::Options options;
|
||||
SetMockTime(block_time); // update time so the block is created with it
|
||||
CBlock block = node::BlockAssembler{node.chainman->ActiveChainstate(), nullptr, options}.CreateNewBlock()->block;
|
||||
auto mining{interfaces::MakeMining(node)};
|
||||
auto block_template{mining->createNewBlock({}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
while (!CheckProofOfWork(block.GetHash(), block.nBits, node.chainman->GetConsensus())) ++block.nNonce;
|
||||
block.fChecked = true; // little speedup
|
||||
SetMockTime(curr_time); // process block at current time
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <common/system.h>
|
||||
#include <chain.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <node/miner.h>
|
||||
#include <test/util/common.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <primitives/block.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <test/util/time.h>
|
||||
#include <util/time.h>
|
||||
@@ -13,9 +14,10 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
using interfaces::BlockTemplate;
|
||||
using interfaces::Mining;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockWaitOptions;
|
||||
|
||||
namespace testnet4_miner_tests {
|
||||
@@ -35,18 +37,18 @@ BOOST_AUTO_TEST_CASE(MiningInterface)
|
||||
auto mining{MakeMining()};
|
||||
BOOST_REQUIRE(mining);
|
||||
|
||||
BlockAssembler::Options options;
|
||||
std::unique_ptr<BlockTemplate> block_template;
|
||||
|
||||
// Set node time a few minutes past the testnet4 genesis block
|
||||
const auto template_time{3min + WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Tip()->Time())};
|
||||
NodeClockContext clock_ctx{template_time};
|
||||
|
||||
block_template = mining->createNewBlock(options, /*cooldown=*/false);
|
||||
block_template = mining->createNewBlock({}, /*cooldown=*/false);
|
||||
BOOST_REQUIRE(block_template);
|
||||
|
||||
// The template should use the mocked system time
|
||||
BOOST_REQUIRE_EQUAL(block_template->getBlockHeader().Time(), template_time);
|
||||
BOOST_REQUIRE_EQUAL(TicksSinceEpoch<std::chrono::seconds>(block_template->getBlockHeader().Time()),
|
||||
TicksSinceEpoch<std::chrono::seconds>(template_time));
|
||||
|
||||
const BlockWaitOptions wait_options{.timeout = MillisecondsDouble{0}, .fee_threshold = 1};
|
||||
|
||||
|
||||
@@ -4,33 +4,40 @@
|
||||
|
||||
#include <test/util/mining.h>
|
||||
|
||||
#include <addresstype.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <key_io.h>
|
||||
#include <node/context.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/script.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
#include <versionbits.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
using node::BlockAssembler;
|
||||
using node::NodeContext;
|
||||
|
||||
COutPoint generatetoaddress(const NodeContext& node, const std::string& address)
|
||||
{
|
||||
const auto dest = DecodeDestination(address);
|
||||
assert(IsValidDestination(dest));
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.coinbase_output_script = GetScriptForDestination(dest);
|
||||
|
||||
return MineBlock(node, assembler_options);
|
||||
return MineBlock(node, {
|
||||
.coinbase_output_script = GetScriptForDestination(dest),
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params)
|
||||
@@ -68,7 +75,7 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
|
||||
return ret;
|
||||
}
|
||||
|
||||
COutPoint MineBlock(const NodeContext& node, const node::BlockAssembler::Options& assembler_options)
|
||||
COutPoint MineBlock(const NodeContext& node, const node::BlockCreateOptions& assembler_options)
|
||||
{
|
||||
auto block = PrepareBlock(node, assembler_options);
|
||||
auto valid = MineBlock(node, block);
|
||||
@@ -122,12 +129,11 @@ COutPoint ProcessBlock(const NodeContext& node, const std::shared_ptr<CBlock>& b
|
||||
}
|
||||
|
||||
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node,
|
||||
const BlockAssembler::Options& assembler_options)
|
||||
const node::BlockCreateOptions& assembler_options)
|
||||
{
|
||||
auto block = std::make_shared<CBlock>(
|
||||
BlockAssembler{Assert(node.chainman)->ActiveChainstate(), Assert(node.mempool.get()), assembler_options}
|
||||
.CreateNewBlock()
|
||||
->block);
|
||||
auto mining = interfaces::MakeMining(node);
|
||||
auto block_template = mining->createNewBlock(assembler_options, /*cooldown=*/false);
|
||||
auto block = std::make_shared<CBlock>(Assert(block_template)->getBlock());
|
||||
|
||||
LOCK(cs_main);
|
||||
block->nTime = Assert(node.chainman)->ActiveChain().Tip()->GetMedianTimePast() + 1;
|
||||
@@ -135,10 +141,3 @@ std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node,
|
||||
|
||||
return block;
|
||||
}
|
||||
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options assembler_options;
|
||||
assembler_options.coinbase_output_script = coinbase_scriptPubKey;
|
||||
ApplyArgsManOptions(*node.args, assembler_options);
|
||||
return PrepareBlock(node, assembler_options);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#ifndef BITCOIN_TEST_UTIL_MINING_H
|
||||
#define BITCOIN_TEST_UTIL_MINING_H
|
||||
|
||||
#include <node/miner.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -14,8 +13,8 @@
|
||||
class CBlock;
|
||||
class CChainParams;
|
||||
class COutPoint;
|
||||
class CScript;
|
||||
namespace node {
|
||||
struct BlockCreateOptions;
|
||||
struct NodeContext;
|
||||
} // namespace node
|
||||
|
||||
@@ -24,7 +23,7 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
|
||||
|
||||
/** Returns the generated coin */
|
||||
COutPoint MineBlock(const node::NodeContext&,
|
||||
const node::BlockAssembler::Options& assembler_options);
|
||||
const node::BlockCreateOptions& assembler_options);
|
||||
|
||||
/**
|
||||
* Returns the generated coin (or Null if the block was invalid).
|
||||
@@ -38,9 +37,8 @@ COutPoint MineBlock(const node::NodeContext&, std::shared_ptr<CBlock>& block);
|
||||
COutPoint ProcessBlock(const node::NodeContext&, const std::shared_ptr<CBlock>& block);
|
||||
|
||||
/** Prepare a block to be mined */
|
||||
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext&);
|
||||
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext& node,
|
||||
const node::BlockAssembler::Options& assembler_options);
|
||||
const node::BlockCreateOptions& assembler_options);
|
||||
|
||||
/** RPC-like helper function, returns the generated coin */
|
||||
COutPoint generatetoaddress(const node::NodeContext&, const std::string& address);
|
||||
|
||||
@@ -6,50 +6,68 @@
|
||||
|
||||
#include <addrman.h>
|
||||
#include <banman.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <common/system.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/params.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <crypto/sha256.h>
|
||||
#include <crypto/hex_base.h>
|
||||
#include <dbwrapper.h>
|
||||
#include <init.h>
|
||||
#include <init/common.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <kernel/mempool_entry.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <kernel/caches.h>
|
||||
#include <kernel/context.h>
|
||||
#include <key.h>
|
||||
#include <logging.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <netbase.h>
|
||||
#include <netgroup.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/chainstate.h>
|
||||
#include <node/context.h>
|
||||
#include <node/kernel_notifications.h>
|
||||
#include <node/mempool_args.h>
|
||||
#include <node/miner.h>
|
||||
#include <node/mining_args.h>
|
||||
#include <node/mining_types.h>
|
||||
#include <node/peerman_args.h>
|
||||
#include <node/warnings.h>
|
||||
#include <noui.h>
|
||||
#include <policy/fees/block_policy_estimator.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <rpc/blockchain.h>
|
||||
#include <rpc/register.h>
|
||||
#include <rpc/server.h>
|
||||
#include <scheduler.h>
|
||||
#include <script/sigcache.h>
|
||||
#include <script/interpreter.h>
|
||||
#include <script/script.h>
|
||||
#include <script/sign.h>
|
||||
#include <script/signingprovider.h>
|
||||
#include <serialize.h>
|
||||
#include <span.h>
|
||||
#include <streams.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/coverage.h>
|
||||
#include <test/util/net.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/transaction_utils.h>
|
||||
#include <test/util/txmempool.h>
|
||||
#include <txdb.h>
|
||||
#include <tinyformat.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/chaintype.h>
|
||||
#include <util/check.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/fs_helpers.h>
|
||||
#include <util/rbf.h>
|
||||
#include <util/result.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <util/string.h>
|
||||
#include <util/task_runner.h>
|
||||
#include <util/thread.h>
|
||||
#include <util/threadnames.h>
|
||||
@@ -58,16 +76,27 @@
|
||||
#include <util/vector.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
#include <walletinitinterface.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <future>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstdlib>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
using namespace util::hex_literals;
|
||||
using node::ApplyArgsManOptions;
|
||||
using node::BlockAssembler;
|
||||
using node::BlockManager;
|
||||
using node::KernelNotifications;
|
||||
using node::LoadChainstate;
|
||||
@@ -335,6 +364,8 @@ void ChainTestingSetup::LoadVerifyActivateChainstate()
|
||||
std::tie(status, error) = VerifyLoadedChainstate(chainman, options);
|
||||
assert(status == node::ChainstateLoadStatus::SUCCESS);
|
||||
|
||||
m_node.notifications->setChainstateLoaded(true);
|
||||
|
||||
BlockValidationState state;
|
||||
if (!chainman.ActiveChainstate().ActivateBestChain(state)) {
|
||||
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
|
||||
@@ -362,6 +393,9 @@ TestingSetup::TestingSetup(
|
||||
m_node.args->GetIntArg("-checkaddrman", 0));
|
||||
m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
|
||||
m_node.connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); // Deterministic randomness for tests.
|
||||
auto mining_args{node::ReadMiningArgs(*m_node.args)};
|
||||
Assert(mining_args);
|
||||
m_node.mining_args = std::move(*mining_args);
|
||||
PeerManager::Options peerman_opts;
|
||||
ApplyArgsManOptions(*m_node.args, peerman_opts);
|
||||
peerman_opts.deterministic_rng = true;
|
||||
@@ -411,12 +445,15 @@ void TestChain100Setup::mineBlocks(int num_blocks)
|
||||
|
||||
CBlock TestChain100Setup::CreateBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate& chainstate)
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = scriptPubKey;
|
||||
CBlock block = BlockAssembler{chainstate, nullptr, options}.CreateNewBlock()->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.use_mempool = false,
|
||||
.coinbase_output_script = scriptPubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
Assert(block_template);
|
||||
CBlock block{block_template->getBlock()};
|
||||
|
||||
Assert(block.vtx.size() == 1);
|
||||
for (const CMutableTransaction& tx : txns) {
|
||||
@@ -431,14 +468,9 @@ CBlock TestChain100Setup::CreateBlock(
|
||||
|
||||
CBlock TestChain100Setup::CreateAndProcessBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate* chainstate)
|
||||
const CScript& scriptPubKey)
|
||||
{
|
||||
if (!chainstate) {
|
||||
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
|
||||
}
|
||||
|
||||
CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
|
||||
CBlock block = this->CreateBlock(txns, scriptPubKey);
|
||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
||||
Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, true, nullptr);
|
||||
|
||||
|
||||
@@ -6,34 +6,29 @@
|
||||
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
|
||||
|
||||
#include <common/args.h> // IWYU pragma: export
|
||||
#include <consensus/amount.h>
|
||||
#include <kernel/caches.h>
|
||||
#include <kernel/context.h>
|
||||
#include <key.h>
|
||||
#include <node/caches.h>
|
||||
#include <node/context.h> // IWYU pragma: export
|
||||
#include <optional>
|
||||
#include <ostream>
|
||||
#include <primitives/transaction.h>
|
||||
#include <pubkey.h>
|
||||
#include <stdexcept>
|
||||
#include <random.h>
|
||||
#include <test/util/random.h>
|
||||
#include <util/chaintype.h> // IWYU pragma: export
|
||||
#include <util/check.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/signalinterrupt.h>
|
||||
#include <util/string.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class arith_uint256;
|
||||
class CFeeRate;
|
||||
class Chainstate;
|
||||
class FastRandomContext;
|
||||
class uint160;
|
||||
class uint256;
|
||||
|
||||
/** Retrieve the command line arguments. */
|
||||
extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS;
|
||||
@@ -134,7 +129,6 @@ struct Testnet4Setup : public TestingSetup {
|
||||
};
|
||||
|
||||
class CBlock;
|
||||
struct CMutableTransaction;
|
||||
class CScript;
|
||||
|
||||
/**
|
||||
@@ -148,11 +142,9 @@ struct TestChain100Setup : public TestingSetup {
|
||||
/**
|
||||
* Create a new block with just given transactions, coinbase paying to
|
||||
* scriptPubKey, and try to add it to the current chain.
|
||||
* If no chainstate is specified, default to the active.
|
||||
*/
|
||||
CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate* chainstate = nullptr);
|
||||
const CScript& scriptPubKey);
|
||||
|
||||
/**
|
||||
* Create a new block with just given transactions, coinbase paying to
|
||||
@@ -160,8 +152,7 @@ struct TestChain100Setup : public TestingSetup {
|
||||
*/
|
||||
CBlock CreateBlock(
|
||||
const std::vector<CMutableTransaction>& txns,
|
||||
const CScript& scriptPubKey,
|
||||
Chainstate& chainstate);
|
||||
const CScript& scriptPubKey);
|
||||
|
||||
//! Mine a series of new blocks on the active chain.
|
||||
void mineBlocks(int num_blocks);
|
||||
|
||||
@@ -2,26 +2,39 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <node/miner.h>
|
||||
#include <interfaces/mining.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <pow.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <test/util/common.h>
|
||||
#include <test/util/random.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/common.h> // IWYU pragma: keep
|
||||
#include <test/util/script.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/time.h>
|
||||
#include <txmempool.h>
|
||||
#include <uint256.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using kernel::ChainstateRole;
|
||||
using node::BlockAssembler;
|
||||
|
||||
namespace validation_block_tests {
|
||||
struct MinerTestingSetup : public RegTestingSetup {
|
||||
@@ -67,10 +80,12 @@ std::shared_ptr<CBlock> MinerTestingSetup::Block(const uint256& prev_hash)
|
||||
static int i = 0;
|
||||
static uint64_t time = Params().GenesisBlock().nTime;
|
||||
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = CScript{} << i++ << OP_TRUE;
|
||||
auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
auto pblock = std::make_shared<CBlock>(ptemplate->block);
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = CScript{} << i++ << OP_TRUE,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
auto pblock = std::make_shared<CBlock>(block_template->getBlock());
|
||||
pblock->hashPrevBlock = prev_hash;
|
||||
pblock->nTime = ++time;
|
||||
|
||||
@@ -335,10 +350,12 @@ BOOST_AUTO_TEST_CASE(witness_commitment_index)
|
||||
LOCK(Assert(m_node.chainman)->GetMutex());
|
||||
CScript pubKey;
|
||||
pubKey << 1 << OP_TRUE;
|
||||
BlockAssembler::Options options;
|
||||
options.coinbase_output_script = pubKey;
|
||||
auto ptemplate = BlockAssembler{m_node.chainman->ActiveChainstate(), m_node.mempool.get(), options}.CreateNewBlock();
|
||||
CBlock pblock = ptemplate->block;
|
||||
auto mining{interfaces::MakeMining(m_node)};
|
||||
auto block_template{mining->createNewBlock({
|
||||
.coinbase_output_script = pubKey,
|
||||
}, /*cooldown=*/false)};
|
||||
BOOST_REQUIRE(block_template);
|
||||
CBlock pblock{block_template->getBlock()};
|
||||
|
||||
CTxOut witness;
|
||||
witness.scriptPubKey.resize(MINIMUM_WITNESS_COMMITMENT);
|
||||
|
||||
@@ -2,27 +2,34 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/amount.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/kernel_notifications.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <random.h>
|
||||
#include <rpc/blockchain.h>
|
||||
#include <script/script.h>
|
||||
#include <sync.h>
|
||||
#include <test/util/chainstate.h>
|
||||
#include <test/util/common.h>
|
||||
#include <test/util/common.h> // IWYU pragma: keep
|
||||
#include <test/util/coins.h>
|
||||
#include <test/util/random.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <tinyformat.h>
|
||||
#include <uint256.h>
|
||||
#include <util/byte_units.h>
|
||||
#include <util/check.h>
|
||||
#include <validation.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
class CTxMemPool;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(validation_chainstate_tests, ChainTestingSetup)
|
||||
|
||||
@@ -83,7 +90,7 @@ BOOST_FIXTURE_TEST_CASE(connect_tip_does_not_cache_inputs_on_failed_connect, Tes
|
||||
tx.vout.emplace_back(MAX_MONEY, CScript{} << OP_TRUE);
|
||||
|
||||
const auto tip{WITH_LOCK(cs_main, return chainstate.m_chain.Tip()->GetBlockHash())};
|
||||
const CBlock block{CreateBlock({tx}, CScript{} << OP_TRUE, chainstate)};
|
||||
const CBlock block{CreateBlock({tx}, CScript{} << OP_TRUE)};
|
||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(block), true, true, nullptr));
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
@@ -6,38 +6,42 @@
|
||||
import asyncio
|
||||
import time
|
||||
from contextlib import AsyncExitStack
|
||||
from decimal import Decimal
|
||||
from io import BytesIO
|
||||
from test_framework.blocktools import NULL_OUTPOINT, script_BIP34_coinbase_height
|
||||
from test_framework.messages import (
|
||||
MAX_BLOCK_WEIGHT,
|
||||
CBlockHeader,
|
||||
COIN,
|
||||
CTransaction,
|
||||
CTxIn,
|
||||
CTxOut,
|
||||
CTxInWitness,
|
||||
ser_uint256,
|
||||
COIN,
|
||||
CTxOut,
|
||||
DEFAULT_BLOCK_RESERVED_WEIGHT,
|
||||
MAX_BLOCK_SIGOPS_COST,
|
||||
MAX_BLOCK_WEIGHT,
|
||||
from_hex,
|
||||
msg_headers,
|
||||
ser_uint256,
|
||||
)
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
assert_greater_than_or_equal,
|
||||
assert_not_equal
|
||||
assert_not_equal,
|
||||
)
|
||||
from test_framework.wallet import MiniWallet
|
||||
from test_framework.p2p import P2PInterface
|
||||
from test_framework.ipc_util import (
|
||||
assert_capnp_failed,
|
||||
assert_create_new_block_fails,
|
||||
destroying,
|
||||
mining_create_block_template,
|
||||
load_capnp_modules,
|
||||
make_mining_ctx,
|
||||
mining_create_block_template,
|
||||
mining_get_block,
|
||||
mining_get_coinbase_tx,
|
||||
mining_wait_next_template,
|
||||
wait_and_do,
|
||||
make_mining_ctx,
|
||||
assert_capnp_failed
|
||||
)
|
||||
|
||||
# Test may be skipped and not have capnp installed
|
||||
@@ -291,8 +295,9 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
|
||||
def run_ipc_option_override_test(self):
|
||||
self.log.info("Running IPC option override test")
|
||||
# Set an absurd reserved weight. `-blockreservedweight` is RPC-only, so
|
||||
# with this setting RPC templates would be empty. IPC clients set
|
||||
# Confirm that BlockCreateOptions.blockReservedWeight takes precedence
|
||||
# over -blockreservedweight. Set an absurdly high -blockreservedweight
|
||||
# value that would result in empty blocks to verify this. IPC clients set
|
||||
# blockReservedWeight per template request and are unaffected; later in
|
||||
# the test the IPC template includes a mempool transaction.
|
||||
self.restart_node(0, extra_args=[f"-blockreservedweight={MAX_BLOCK_WEIGHT}"])
|
||||
@@ -317,11 +322,136 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
|
||||
self.log.debug("Enforce minimum reserved weight for IPC clients too")
|
||||
opts.blockReservedWeight = 0
|
||||
try:
|
||||
await mining.createNewBlock(ctx, opts)
|
||||
raise AssertionError("createNewBlock unexpectedly succeeded")
|
||||
except capnp.lib.capnp.KjException as e:
|
||||
assert_capnp_failed(e, "remote exception: std::exception: block_reserved_weight (0) must be at least 2000 weight units")
|
||||
await assert_create_new_block_fails(ctx, mining, opts,
|
||||
"block_reserved_weight (0) is lower than minimum safety value of (2000)")
|
||||
|
||||
async def async_routine_check_max_reserved_weight():
|
||||
self.log.debug("Enforce maximum reserved weight for IPC clients too")
|
||||
ctx, mining = await make_mining_ctx(self)
|
||||
opts = self.capnp_modules['mining'].BlockCreateOptions()
|
||||
opts.blockReservedWeight = MAX_BLOCK_WEIGHT + 1
|
||||
await assert_create_new_block_fails(ctx, mining, opts,
|
||||
f"block_reserved_weight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})")
|
||||
|
||||
async def async_routine_check_sigops_limit():
|
||||
self.log.debug("Enforce sigops limit for IPC clients too")
|
||||
ctx, mining = await make_mining_ctx(self)
|
||||
opts = self.capnp_modules['mining'].BlockCreateOptions()
|
||||
opts.coinbaseOutputMaxAdditionalSigops = MAX_BLOCK_SIGOPS_COST + 1
|
||||
await assert_create_new_block_fails(ctx, mining, opts,
|
||||
f"coinbase_output_max_additional_sigops ({MAX_BLOCK_SIGOPS_COST + 1}) exceeds consensus maximum block sigops cost ({MAX_BLOCK_SIGOPS_COST})")
|
||||
|
||||
asyncio.run(capnp.run(async_routine()))
|
||||
asyncio.run(capnp.run(async_routine_check_max_reserved_weight()))
|
||||
asyncio.run(capnp.run(async_routine_check_sigops_limit()))
|
||||
|
||||
def run_waitnext_mining_policy_test(self):
|
||||
"""Verify that waitNext() preserves the mining policy from -blockmintxfee
|
||||
instead of falling back to defaults."""
|
||||
self.log.info("Running waitNext mining policy test")
|
||||
block_min_tx_fee = Decimal("0.00002000")
|
||||
below_block_min_tx_fee = Decimal("0.00001000")
|
||||
above_block_min_tx_fee = Decimal("0.00003000")
|
||||
|
||||
self.restart_node(0, extra_args=[
|
||||
f"-blockmintxfee={block_min_tx_fee:.8f}",
|
||||
"-minrelaytxfee=0",
|
||||
"-persistmempool=0",
|
||||
])
|
||||
|
||||
async def async_routine():
|
||||
ctx, mining = await make_mining_ctx(self)
|
||||
|
||||
self.log.debug("Create a below -blockmintxfee transaction")
|
||||
low_fee_tx = self.miniwallet.send_self_transfer(
|
||||
fee_rate=below_block_min_tx_fee,
|
||||
from_node=self.nodes[0],
|
||||
confirmed_only=True,
|
||||
)
|
||||
assert low_fee_tx["txid"] in self.nodes[0].getrawmempool()
|
||||
|
||||
async with AsyncExitStack() as stack:
|
||||
self.log.debug("createNewBlock should respect -blockmintxfee")
|
||||
template = await mining_create_block_template(mining, stack, ctx, self.default_block_create_options)
|
||||
assert template is not None
|
||||
block = await mining_get_block(template, ctx)
|
||||
assert low_fee_tx["txid"] not in {tx.txid_hex for tx in block.vtx[1:]}
|
||||
|
||||
self.log.debug("waitNext should preserve the same mining policy")
|
||||
high_fee_tx = self.miniwallet.send_self_transfer(
|
||||
fee_rate=above_block_min_tx_fee,
|
||||
from_node=self.nodes[0],
|
||||
confirmed_only=True,
|
||||
)
|
||||
mempool_txids = self.nodes[0].getrawmempool()
|
||||
assert high_fee_tx["txid"] in mempool_txids
|
||||
assert low_fee_tx["txid"] in mempool_txids
|
||||
template_next = await mining_wait_next_template(template, stack, ctx, self.default_block_wait_options)
|
||||
assert template_next is not None
|
||||
|
||||
block_next = await mining_get_block(template_next, ctx)
|
||||
block_next_txids = {tx.txid_hex for tx in block_next.vtx[1:]}
|
||||
assert high_fee_tx["txid"] in block_next_txids
|
||||
assert low_fee_tx["txid"] not in block_next_txids
|
||||
|
||||
asyncio.run(capnp.run(async_routine()))
|
||||
|
||||
def run_block_max_weight_test(self):
|
||||
"""Verify IPC createNewBlock() and waitNext() preserve the -blockmaxweight policy."""
|
||||
self.log.info("Running block_max_weight test")
|
||||
|
||||
# Cap that leaves room for only a handful of mempool transactions
|
||||
# above DEFAULT_BLOCK_RESERVED_WEIGHT (8000). Well below MAX_BLOCK_WEIGHT
|
||||
# (4_000_000), so any truncation observed here is attributable to the
|
||||
# cap, not to consensus limits or wallet chain limits.
|
||||
small_cap = DEFAULT_BLOCK_RESERVED_WEIGHT + 4000
|
||||
NUM_TXS = 20
|
||||
|
||||
self.restart_node(0, extra_args=[
|
||||
f"-blockmaxweight={small_cap}",
|
||||
"-minrelaytxfee=0",
|
||||
"-persistmempool=0",
|
||||
])
|
||||
# Refresh miniwallet's UTXO view from the chain after restart.
|
||||
self.miniwallet.rescan_utxos()
|
||||
|
||||
# Fill the mempool enough that the configured block weight cap forces
|
||||
# template truncation.
|
||||
for _ in range(NUM_TXS):
|
||||
self.miniwallet.send_self_transfer(from_node=self.nodes[0], confirmed_only=True)
|
||||
assert_equal(self.nodes[0].getmempoolinfo()["size"], NUM_TXS)
|
||||
|
||||
async def async_routine():
|
||||
ctx, mining = await make_mining_ctx(self)
|
||||
async with AsyncExitStack() as stack:
|
||||
template = await mining_create_block_template(mining, stack, ctx, self.default_block_create_options)
|
||||
assert template is not None
|
||||
block = await mining_get_block(template, ctx)
|
||||
assert_greater_than_or_equal(small_cap, block.get_weight())
|
||||
# Exclude the coinbase; the cap must have forced truncation.
|
||||
initial_included = len(block.vtx) - 1
|
||||
assert initial_included < NUM_TXS, (
|
||||
f"Expected -blockmaxweight={small_cap} to truncate; "
|
||||
f"included {initial_included}/{NUM_TXS} mempool txs"
|
||||
)
|
||||
|
||||
self.log.debug("waitNext should preserve -blockmaxweight")
|
||||
high_fee_tx = self.miniwallet.send_self_transfer(
|
||||
from_node=self.nodes[0],
|
||||
confirmed_only=True,
|
||||
fee_rate=10,
|
||||
)
|
||||
template_next = await mining_wait_next_template(template, stack, ctx, self.default_block_wait_options)
|
||||
assert template_next is not None
|
||||
|
||||
block_next = await mining_get_block(template_next, ctx)
|
||||
assert_greater_than_or_equal(small_cap, block_next.get_weight())
|
||||
assert high_fee_tx["txid"] in {tx.txid_hex for tx in block_next.vtx[1:]}
|
||||
next_included = len(block_next.vtx) - 1
|
||||
assert next_included < NUM_TXS + 1, (
|
||||
f"Expected -blockmaxweight={small_cap} to remain capped after waitNext; "
|
||||
f"included {next_included}/{NUM_TXS + 1} mempool txs"
|
||||
)
|
||||
|
||||
asyncio.run(capnp.run(async_routine()))
|
||||
|
||||
@@ -421,8 +551,6 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
node.wait_for_rpc_connection()
|
||||
assert_equal(node.getblockcount(), 0)
|
||||
|
||||
miniwallet = MiniWallet(node)
|
||||
|
||||
async def async_routine():
|
||||
ctx, mining = await make_mining_ctx(self)
|
||||
opts = self.capnp_modules['mining'].BlockCreateOptions()
|
||||
@@ -437,7 +565,7 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
block = await mining_get_block(template, ctx)
|
||||
# Heights <= 16 need extra nonce padding.
|
||||
extra_nonce = b'\xaa\xbb\xcc\xdd' if height <= 16 else b""
|
||||
coinbase = await self.build_coinbase_test(template, ctx, miniwallet, extra_nonce=extra_nonce)
|
||||
coinbase = await self.build_coinbase_test(template, ctx, self.miniwallet, extra_nonce=extra_nonce)
|
||||
block.vtx[0] = coinbase
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.solve()
|
||||
@@ -450,10 +578,15 @@ class IPCMiningTest(BitcoinTestFramework):
|
||||
def run_test(self):
|
||||
self.miniwallet = MiniWallet(self.nodes[0])
|
||||
self.default_block_create_options = self.capnp_modules['mining'].BlockCreateOptions()
|
||||
self.default_block_wait_options = self.capnp_modules['mining'].BlockWaitOptions()
|
||||
self.default_block_wait_options.timeout = 1000.0 * self.options.timeout_factor
|
||||
self.default_block_wait_options.feeThreshold = 1
|
||||
self.run_mining_interface_test()
|
||||
self.run_early_startup_test()
|
||||
self.run_block_template_test()
|
||||
self.run_coinbase_and_submission_test()
|
||||
self.run_waitnext_mining_policy_test()
|
||||
self.run_block_max_weight_test()
|
||||
self.run_ipc_option_override_test()
|
||||
|
||||
# Needs to run last because it resets the chain.
|
||||
|
||||
@@ -357,21 +357,28 @@ class MiningTest(BitcoinTestFramework):
|
||||
self.stop_node(0)
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=[f"-blockreservedweight={MAX_BLOCK_WEIGHT + 1}"],
|
||||
expected_msg=f"Error: Specified -blockreservedweight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})",
|
||||
expected_msg=f"Error: -blockreservedweight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})",
|
||||
)
|
||||
|
||||
self.log.info(f"Test that node will fail to start when user provide -blockreservedweight below {MINIMUM_BLOCK_RESERVED_WEIGHT}")
|
||||
self.stop_node(0)
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=[f"-blockreservedweight={MINIMUM_BLOCK_RESERVED_WEIGHT - 1}"],
|
||||
expected_msg=f"Error: Specified -blockreservedweight ({MINIMUM_BLOCK_RESERVED_WEIGHT - 1}) is lower than minimum safety value of ({MINIMUM_BLOCK_RESERVED_WEIGHT})",
|
||||
expected_msg=f"Error: -blockreservedweight ({MINIMUM_BLOCK_RESERVED_WEIGHT - 1}) is lower than minimum safety value of ({MINIMUM_BLOCK_RESERVED_WEIGHT})",
|
||||
)
|
||||
|
||||
self.log.info("Test that node will fail to start when user provide invalid -blockmaxweight")
|
||||
self.stop_node(0)
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=[f"-blockmaxweight={MAX_BLOCK_WEIGHT + 1}"],
|
||||
expected_msg=f"Error: Specified -blockmaxweight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})",
|
||||
expected_msg=f"Error: -blockmaxweight ({MAX_BLOCK_WEIGHT + 1}) exceeds consensus maximum block weight ({MAX_BLOCK_WEIGHT})",
|
||||
)
|
||||
|
||||
self.log.info("Test that node will fail to start when -blockmaxweight is lower than -blockreservedweight")
|
||||
self.stop_node(0)
|
||||
self.nodes[0].assert_start_raises_init_error(
|
||||
extra_args=[f"-blockmaxweight={DEFAULT_BLOCK_RESERVED_WEIGHT - 1}"],
|
||||
expected_msg=f"Error: -blockreservedweight ({DEFAULT_BLOCK_RESERVED_WEIGHT}) exceeds -blockmaxweight ({DEFAULT_BLOCK_RESERVED_WEIGHT - 1})",
|
||||
)
|
||||
|
||||
def test_height_in_locktime(self):
|
||||
|
||||
@@ -162,3 +162,12 @@ async def make_mining_ctx(self):
|
||||
def assert_capnp_failed(e, description_prefix):
|
||||
assert e.description.startswith(description_prefix), f"Expected description starting with '{description_prefix}', got '{e.description}'"
|
||||
assert_equal(e.type, "FAILED")
|
||||
|
||||
|
||||
async def assert_create_new_block_fails(ctx, mining, opts, expected_msg):
|
||||
"""Assert that mining.createNewBlock fails with the expected remote exception."""
|
||||
try:
|
||||
await mining.createNewBlock(ctx, opts)
|
||||
raise AssertionError("createNewBlock unexpectedly succeeded")
|
||||
except capnp.lib.capnp.KjException as e:
|
||||
assert_capnp_failed(e, f"remote exception: std::exception: {expected_msg}")
|
||||
|
||||
@@ -36,6 +36,7 @@ from test_framework.util import (
|
||||
|
||||
MAX_LOCATOR_SZ = 101
|
||||
MAX_BLOCK_WEIGHT = 4000000
|
||||
MAX_BLOCK_SIGOPS_COST = 80000
|
||||
DEFAULT_BLOCK_RESERVED_WEIGHT = 8000
|
||||
MINIMUM_BLOCK_RESERVED_WEIGHT = 2000
|
||||
MAX_BLOOM_FILTER_SIZE = 36000
|
||||
|
||||
Reference in New Issue
Block a user