2022-12-24 23:49:50 +00:00
|
|
|
// Copyright (c) 2011-2022 The Bitcoin Core developers
|
2014-12-13 12:09:33 +08:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2014-03-18 10:11:00 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2019-11-05 15:18:59 -05:00
|
|
|
#include <test/util/setup_common.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
|
2022-06-30 23:47:41 -04:00
|
|
|
#include <kernel/validation_cache_sizes.h>
|
|
|
|
|
2020-10-23 09:34:27 +01:00
|
|
|
#include <addrman.h>
|
2017-10-05 16:40:43 -04:00
|
|
|
#include <banman.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <chainparams.h>
|
2023-05-08 11:32:13 +02:00
|
|
|
#include <common/system.h>
|
2022-10-14 13:55:53 +08:00
|
|
|
#include <common/url.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <consensus/consensus.h>
|
2018-06-16 22:38:13 +02:00
|
|
|
#include <consensus/params.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <consensus/validation.h>
|
|
|
|
#include <crypto/sha256.h>
|
2019-06-20 09:34:45 -04:00
|
|
|
#include <init.h>
|
2022-03-02 20:04:12 -05:00
|
|
|
#include <init/common.h>
|
2020-05-28 16:35:15 -04:00
|
|
|
#include <interfaces/chain.h>
|
2022-11-30 10:37:13 +00:00
|
|
|
#include <kernel/mempool_entry.h>
|
2023-07-29 13:06:01 +02:00
|
|
|
#include <logging.h>
|
2019-06-24 17:22:28 +02:00
|
|
|
#include <net.h>
|
2020-01-22 20:23:48 +00:00
|
|
|
#include <net_processing.h>
|
2021-11-11 14:40:50 -05:00
|
|
|
#include <node/blockstorage.h>
|
|
|
|
#include <node/chainstate.h>
|
pool: Add and use MemPoolOptions, ApplyArgsManOptions
Reviewers: Note that CTxMemPool now requires a non-defaulted
CTxMemPool::Options for its constructor. Meaning that there's no need to
worry about a stray CTxMemPool constructor somewhere defaulting to
something incorrect. All instances of CTxMemPool construction are
addressed here in this commit.
We set options for CTxMemPool and construct it in many different ways. A
good example can be seen in how we determine CTxMemPool's check_ratio in
AppInitMain(...).
1. We first set the default based on chainparams's
DefaultConsistencyChecks()
2. Then, we apply the ArgsManager option on top of that default
3. Finally, we clamp the result of that between 0 and 1 Million
With this patch, most CTxMemPool construction are along the lines of:
MemPoolOptions mempool_opts{...default overrides...};
ApplyArgsManOptions(argsman, mempool_opts);
...hard overrides...
CTxMemPool pool{mempool_opts};
This "compositional" style of building options means that we can omit
unnecessary/irrelevant steps wherever we want but also maintain full
customizability.
For example:
- For users of libbitcoinkernel, where we eventually want to remove
ArgsManager, they simply won't call (or even know about)
ApplyArgsManOptions.
- See src/init.cpp to see how the check_ratio CTxMemPool option works
after this change.
A MemPoolOptionsForTest helper was also added and used by tests/fuzz
tests where a local CTxMemPool needed to be created.
The change in src/test/fuzz/tx_pool.cpp seemingly changes behaviour by
applying ArgsManager options on top of the CTxMemPool::Options defaults.
However, in future commits where we introduce flags like -maxmempool,
the call to ApplyArgsManOptions is actually what preserves the existing
behaviour. Previously, although it wasn't obvious, our CTxMemPool would
consult gArgs for flags like -maxmempool when it needed it, so it
already relied on ArgsManager information. This patchset just laid bare
the obfuscatory perils of globals.
[META] As this patchset progresses, we will move more and more
CTxMemPool-relevant options into MemPoolOptions and add their
ArgsMan-related logic to ApplyArgsManOptions.
2022-03-18 13:51:37 -04:00
|
|
|
#include <node/context.h>
|
2023-05-10 22:29:17 +02:00
|
|
|
#include <node/kernel_notifications.h>
|
2022-08-02 15:21:47 +02:00
|
|
|
#include <node/mempool_args.h>
|
2022-04-16 11:16:32 +08:00
|
|
|
#include <node/miner.h>
|
2023-04-20 13:05:23 +02:00
|
|
|
#include <node/peerman_args.h>
|
2022-06-30 23:47:41 -04:00
|
|
|
#include <node/validation_cache_args.h>
|
2022-04-16 11:16:32 +08:00
|
|
|
#include <noui.h>
|
2020-07-28 19:12:50 +02:00
|
|
|
#include <policy/fees.h>
|
2021-12-08 16:19:31 -05:00
|
|
|
#include <policy/fees_args.h>
|
2018-05-13 23:39:53 -07:00
|
|
|
#include <pow.h>
|
2023-05-11 11:44:39 -07:00
|
|
|
#include <random.h>
|
2019-09-17 19:05:26 -04:00
|
|
|
#include <rpc/blockchain.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <rpc/register.h>
|
2018-08-13 16:13:29 -04:00
|
|
|
#include <rpc/server.h>
|
2020-05-28 08:46:50 -04:00
|
|
|
#include <scheduler.h>
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <script/sigcache.h>
|
2021-11-11 14:40:50 -05:00
|
|
|
#include <shutdown.h>
|
2018-08-13 16:13:29 -04:00
|
|
|
#include <streams.h>
|
2022-04-16 11:16:32 +08:00
|
|
|
#include <test/util/net.h>
|
2023-01-22 09:57:19 -08:00
|
|
|
#include <test/util/random.h>
|
2022-10-10 14:27:31 +02:00
|
|
|
#include <test/util/txmempool.h>
|
2022-03-01 16:14:12 -05:00
|
|
|
#include <timedata.h>
|
2019-06-24 17:22:28 +02:00
|
|
|
#include <txdb.h>
|
pool: Add and use MemPoolOptions, ApplyArgsManOptions
Reviewers: Note that CTxMemPool now requires a non-defaulted
CTxMemPool::Options for its constructor. Meaning that there's no need to
worry about a stray CTxMemPool constructor somewhere defaulting to
something incorrect. All instances of CTxMemPool construction are
addressed here in this commit.
We set options for CTxMemPool and construct it in many different ways. A
good example can be seen in how we determine CTxMemPool's check_ratio in
AppInitMain(...).
1. We first set the default based on chainparams's
DefaultConsistencyChecks()
2. Then, we apply the ArgsManager option on top of that default
3. Finally, we clamp the result of that between 0 and 1 Million
With this patch, most CTxMemPool construction are along the lines of:
MemPoolOptions mempool_opts{...default overrides...};
ApplyArgsManOptions(argsman, mempool_opts);
...hard overrides...
CTxMemPool pool{mempool_opts};
This "compositional" style of building options means that we can omit
unnecessary/irrelevant steps wherever we want but also maintain full
customizability.
For example:
- For users of libbitcoinkernel, where we eventually want to remove
ArgsManager, they simply won't call (or even know about)
ApplyArgsManOptions.
- See src/init.cpp to see how the check_ratio CTxMemPool option works
after this change.
A MemPoolOptionsForTest helper was also added and used by tests/fuzz
tests where a local CTxMemPool needed to be created.
The change in src/test/fuzz/tx_pool.cpp seemingly changes behaviour by
applying ArgsManager options on top of the CTxMemPool::Options defaults.
However, in future commits where we introduce flags like -maxmempool,
the call to ApplyArgsManOptions is actually what preserves the existing
behaviour. Previously, although it wasn't obvious, our CTxMemPool would
consult gArgs for flags like -maxmempool when it needed it, so it
already relied on ArgsManager information. This patchset just laid bare
the obfuscatory perils of globals.
[META] As this patchset progresses, we will move more and more
CTxMemPool-relevant options into MemPoolOptions and add their
ArgsMan-related logic to ApplyArgsManOptions.
2022-03-18 13:51:37 -04:00
|
|
|
#include <txmempool.h>
|
2023-04-17 22:20:59 +02:00
|
|
|
#include <util/chaintype.h>
|
2022-10-03 10:56:00 +01:00
|
|
|
#include <util/rbf.h>
|
2019-06-24 17:22:28 +02:00
|
|
|
#include <util/strencodings.h>
|
2020-02-12 23:01:45 -05:00
|
|
|
#include <util/string.h>
|
2021-04-13 20:44:46 +03:00
|
|
|
#include <util/thread.h>
|
|
|
|
#include <util/threadnames.h>
|
2019-06-24 17:22:28 +02:00
|
|
|
#include <util/time.h>
|
2019-06-17 10:56:52 +03:00
|
|
|
#include <util/translation.h>
|
2020-04-08 20:02:20 -04:00
|
|
|
#include <util/vector.h>
|
2018-08-13 16:13:29 -04:00
|
|
|
#include <validation.h>
|
2019-06-24 17:22:28 +02:00
|
|
|
#include <validationinterface.h>
|
2020-05-28 16:35:15 -04:00
|
|
|
#include <walletinitinterface.h>
|
2018-08-13 16:13:29 -04:00
|
|
|
|
2022-04-20 14:04:11 -07:00
|
|
|
#include <algorithm>
|
2019-06-17 10:56:52 +03:00
|
|
|
#include <functional>
|
2021-10-08 18:11:40 +02:00
|
|
|
#include <stdexcept>
|
2019-06-17 10:56:52 +03:00
|
|
|
|
2023-08-02 07:50:22 +02:00
|
|
|
using kernel::BlockTreeDB;
|
2022-06-30 23:47:41 -04:00
|
|
|
using kernel::ValidationCacheSizes;
|
|
|
|
using node::ApplyArgsManOptions;
|
2021-11-12 10:06:00 -05:00
|
|
|
using node::BlockAssembler;
|
2023-02-18 18:17:33 +01:00
|
|
|
using node::BlockManager;
|
2021-11-12 10:06:00 -05:00
|
|
|
using node::CalculateCacheSizes;
|
2023-05-10 22:29:17 +02:00
|
|
|
using node::KernelNotifications;
|
2021-11-12 10:06:00 -05:00
|
|
|
using node::LoadChainstate;
|
|
|
|
using node::RegenerateCommitments;
|
|
|
|
using node::VerifyLoadedChainstate;
|
|
|
|
|
2018-08-13 16:13:29 -04:00
|
|
|
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
|
2020-04-02 08:35:10 -04:00
|
|
|
UrlDecodeFn* const URL_DECODE = nullptr;
|
2013-04-13 00:13:08 -05:00
|
|
|
|
2019-09-26 09:14:19 -04:00
|
|
|
/** Random context to get unique temp data dirs. Separate from g_insecure_rand_ctx, which can be seeded from a const env var */
|
|
|
|
static FastRandomContext g_insecure_rand_ctx_temp_path;
|
|
|
|
|
2018-04-18 08:01:48 -04:00
|
|
|
std::ostream& operator<<(std::ostream& os, const uint256& num)
|
|
|
|
{
|
|
|
|
os << num.ToString();
|
|
|
|
return os;
|
|
|
|
}
|
|
|
|
|
2023-04-17 22:20:59 +02:00
|
|
|
BasicTestingSetup::BasicTestingSetup(const ChainType chainType, const std::vector<const char*>& extra_args)
|
2021-04-18 11:37:06 +02:00
|
|
|
: m_path_root{fs::temp_directory_path() / "test_common_" PACKAGE_NAME / g_insecure_rand_ctx_temp_path.rand256().ToString()},
|
|
|
|
m_args{}
|
2015-03-03 07:49:12 -08:00
|
|
|
{
|
2017-12-05 15:57:12 -05:00
|
|
|
m_node.args = &gArgs;
|
2021-10-08 18:11:40 +02:00
|
|
|
std::vector<const char*> arguments = Cat(
|
2020-04-08 20:02:20 -04:00
|
|
|
{
|
|
|
|
"dummy",
|
|
|
|
"-printtoconsole=0",
|
2020-08-25 20:22:28 +00:00
|
|
|
"-logsourcelocations",
|
2020-04-08 20:02:20 -04:00
|
|
|
"-logtimemicros",
|
2020-05-20 11:21:55 -04:00
|
|
|
"-logthreadnames",
|
Create BCLog::Level::Trace log severity level
for verbose log messages for development or debugging only, as bitcoind may run
more slowly, that are more granular/frequent than the Debug log level, i.e. for
very high-frequency, low-level messages to be logged distinctly from
higher-level, less-frequent debug logging that could still be usable in production.
An example would be to log higher-level peer events (connection, disconnection,
misbehavior, eviction) as Debug, versus Trace for low-level, high-volume p2p
messages in the BCLog::NET category. This will enable the user to log only the
former without the latter, in order to focus on high-level peer management events.
With respect to the name, "trace" is suggested as the most granular level
in resources like the following:
- https://sematext.com/blog/logging-levels
- https://howtodoinjava.com/log4j2/logging-levels
Update the test framework and add test coverage.
2022-06-01 13:44:59 +02:00
|
|
|
"-loglevel=trace",
|
2020-04-08 20:02:20 -04:00
|
|
|
"-debug",
|
|
|
|
"-debugexclude=libevent",
|
|
|
|
"-debugexclude=leveldb",
|
|
|
|
},
|
|
|
|
extra_args);
|
2021-10-08 18:11:40 +02:00
|
|
|
if (G_TEST_COMMAND_LINE_ARGUMENTS) {
|
|
|
|
arguments = Cat(arguments, G_TEST_COMMAND_LINE_ARGUMENTS());
|
|
|
|
}
|
2020-05-20 11:21:55 -04:00
|
|
|
util::ThreadRename("test");
|
2019-06-19 17:52:35 -04:00
|
|
|
fs::create_directories(m_path_root);
|
2021-09-10 00:17:20 -04:00
|
|
|
m_args.ForceSetArg("-datadir", fs::PathToString(m_path_root));
|
|
|
|
gArgs.ForceSetArg("-datadir", fs::PathToString(m_path_root));
|
2021-02-26 09:52:50 +01:00
|
|
|
gArgs.ClearPathCache();
|
2020-04-08 20:02:20 -04:00
|
|
|
{
|
2017-12-05 15:57:12 -05:00
|
|
|
SetupServerArgs(*m_node.args);
|
2020-04-08 20:02:20 -04:00
|
|
|
std::string error;
|
2021-10-08 18:11:40 +02:00
|
|
|
if (!m_node.args->ParseParameters(arguments.size(), arguments.data(), error)) {
|
|
|
|
m_node.args->ClearArgs();
|
|
|
|
throw std::runtime_error{error};
|
|
|
|
}
|
2020-04-08 20:02:20 -04:00
|
|
|
}
|
2023-04-17 22:20:59 +02:00
|
|
|
SelectParams(chainType);
|
2019-09-26 09:14:19 -04:00
|
|
|
SeedInsecureRand();
|
2019-09-27 11:53:34 -04:00
|
|
|
if (G_TEST_LOG_FUN) LogInstance().PushBackCallback(G_TEST_LOG_FUN);
|
2020-08-21 20:13:40 +02:00
|
|
|
InitLogging(*m_node.args);
|
|
|
|
AppInitParameterInteraction(*m_node.args);
|
2019-06-20 09:34:45 -04:00
|
|
|
LogInstance().StartLogging();
|
2022-05-25 14:31:54 -04:00
|
|
|
m_node.kernel = std::make_unique<kernel::Context>();
|
2018-07-11 23:44:12 -04:00
|
|
|
SetupEnvironment();
|
|
|
|
SetupNetworking();
|
2022-06-30 23:47:41 -04:00
|
|
|
|
|
|
|
ValidationCacheSizes validation_cache_sizes{};
|
|
|
|
ApplyArgsManOptions(*m_node.args, validation_cache_sizes);
|
|
|
|
Assert(InitSignatureCache(validation_cache_sizes.signature_cache_bytes));
|
|
|
|
Assert(InitScriptExecutionCache(validation_cache_sizes.script_execution_cache_bytes));
|
|
|
|
|
2020-05-28 16:35:15 -04:00
|
|
|
m_node.chain = interfaces::MakeChain(m_node);
|
2019-03-29 09:55:21 +01:00
|
|
|
static bool noui_connected = false;
|
|
|
|
if (!noui_connected) {
|
|
|
|
noui_connect();
|
|
|
|
noui_connected = true;
|
|
|
|
}
|
2015-03-12 09:34:42 +01:00
|
|
|
}
|
2015-03-03 09:59:32 -05:00
|
|
|
|
2015-03-12 09:34:42 +01:00
|
|
|
BasicTestingSetup::~BasicTestingSetup()
|
|
|
|
{
|
2023-10-24 08:38:06 +02:00
|
|
|
m_node.kernel.reset();
|
2021-04-14 10:30:01 +02:00
|
|
|
SetMockTime(0s); // Reset mocktime for following tests
|
2019-06-20 09:34:45 -04:00
|
|
|
LogInstance().DisconnectTestLogger();
|
2018-07-11 23:44:12 -04:00
|
|
|
fs::remove_all(m_path_root);
|
2020-04-08 20:02:20 -04:00
|
|
|
gArgs.ClearArgs();
|
2018-07-11 23:44:12 -04:00
|
|
|
}
|
|
|
|
|
2023-04-17 22:20:59 +02:00
|
|
|
ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vector<const char*>& extra_args)
|
|
|
|
: BasicTestingSetup(chainType, extra_args)
|
2015-03-12 09:34:42 +01:00
|
|
|
{
|
2022-01-18 21:34:16 +10:00
|
|
|
const CChainParams& chainparams = Params();
|
|
|
|
|
2019-02-28 14:51:11 -05:00
|
|
|
// We have to run a scheduler thread to prevent ActivateBestChain
|
|
|
|
// from blocking due to queue overrun.
|
2021-03-10 17:28:08 +08:00
|
|
|
m_node.scheduler = std::make_unique<CScheduler>();
|
2021-04-13 21:17:55 +03:00
|
|
|
m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
|
2020-04-17 11:28:45 -04:00
|
|
|
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
|
2019-02-28 14:51:11 -05:00
|
|
|
|
2023-06-14 22:39:26 +01:00
|
|
|
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES);
|
pool: Add and use MemPoolOptions, ApplyArgsManOptions
Reviewers: Note that CTxMemPool now requires a non-defaulted
CTxMemPool::Options for its constructor. Meaning that there's no need to
worry about a stray CTxMemPool constructor somewhere defaulting to
something incorrect. All instances of CTxMemPool construction are
addressed here in this commit.
We set options for CTxMemPool and construct it in many different ways. A
good example can be seen in how we determine CTxMemPool's check_ratio in
AppInitMain(...).
1. We first set the default based on chainparams's
DefaultConsistencyChecks()
2. Then, we apply the ArgsManager option on top of that default
3. Finally, we clamp the result of that between 0 and 1 Million
With this patch, most CTxMemPool construction are along the lines of:
MemPoolOptions mempool_opts{...default overrides...};
ApplyArgsManOptions(argsman, mempool_opts);
...hard overrides...
CTxMemPool pool{mempool_opts};
This "compositional" style of building options means that we can omit
unnecessary/irrelevant steps wherever we want but also maintain full
customizability.
For example:
- For users of libbitcoinkernel, where we eventually want to remove
ArgsManager, they simply won't call (or even know about)
ApplyArgsManOptions.
- See src/init.cpp to see how the check_ratio CTxMemPool option works
after this change.
A MemPoolOptionsForTest helper was also added and used by tests/fuzz
tests where a local CTxMemPool needed to be created.
The change in src/test/fuzz/tx_pool.cpp seemingly changes behaviour by
applying ArgsManager options on top of the CTxMemPool::Options defaults.
However, in future commits where we introduce flags like -maxmempool,
the call to ApplyArgsManOptions is actually what preserves the existing
behaviour. Previously, although it wasn't obvious, our CTxMemPool would
consult gArgs for flags like -maxmempool when it needed it, so it
already relied on ArgsManager information. This patchset just laid bare
the obfuscatory perils of globals.
[META] As this patchset progresses, we will move more and more
CTxMemPool-relevant options into MemPoolOptions and add their
ArgsMan-related logic to ApplyArgsManOptions.
2022-03-18 13:51:37 -04:00
|
|
|
m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node));
|
2020-07-28 07:40:49 +02:00
|
|
|
|
2021-09-21 14:09:23 -04:00
|
|
|
m_cache_sizes = CalculateCacheSizes(m_args);
|
|
|
|
|
2023-05-09 11:15:46 +02:00
|
|
|
m_node.notifications = std::make_unique<KernelNotifications>(m_node.exit_status);
|
2023-05-10 22:29:17 +02:00
|
|
|
|
2022-03-01 16:14:12 -05:00
|
|
|
const ChainstateManager::Options chainman_opts{
|
2022-07-13 14:16:15 -04:00
|
|
|
.chainparams = chainparams,
|
2022-08-16 23:32:55 -04:00
|
|
|
.datadir = m_args.GetDataDirNet(),
|
2022-07-13 14:16:15 -04:00
|
|
|
.adjusted_time_callback = GetAdjustedTime,
|
2022-07-26 12:59:48 +02:00
|
|
|
.check_block_index = true,
|
2023-05-10 22:29:17 +02:00
|
|
|
.notifications = *m_node.notifications,
|
2022-03-01 16:14:12 -05:00
|
|
|
};
|
2023-02-18 18:17:33 +01:00
|
|
|
const BlockManager::Options blockman_opts{
|
2023-05-04 12:19:35 +02:00
|
|
|
.chainparams = chainman_opts.chainparams,
|
2023-02-18 18:17:33 +01:00
|
|
|
.blocks_dir = m_args.GetBlocksDirPath(),
|
2023-06-15 23:09:37 +02:00
|
|
|
.notifications = chainman_opts.notifications,
|
2023-05-04 12:19:35 +02:00
|
|
|
};
|
2023-05-17 12:43:23 +02:00
|
|
|
m_node.chainman = std::make_unique<ChainstateManager>(m_node.kernel->interrupt, chainman_opts, blockman_opts);
|
2023-08-02 07:50:22 +02:00
|
|
|
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<BlockTreeDB>(DBParams{
|
2022-08-16 23:32:55 -04:00
|
|
|
.path = m_args.GetDataDirNet() / "blocks" / "index",
|
|
|
|
.cache_bytes = static_cast<size_t>(m_cache_sizes.block_tree_db),
|
|
|
|
.memory_only = true});
|
2019-02-28 14:51:11 -05:00
|
|
|
|
2019-11-02 17:14:38 -04:00
|
|
|
constexpr int script_check_threads = 2;
|
2020-08-21 09:24:05 +03:00
|
|
|
StartScriptCheckWorkerThreads(script_check_threads);
|
2015-03-03 07:49:12 -08:00
|
|
|
}
|
|
|
|
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
ChainTestingSetup::~ChainTestingSetup()
|
2015-03-03 07:49:12 -08:00
|
|
|
{
|
2020-02-28 12:02:10 +10:00
|
|
|
if (m_node.scheduler) m_node.scheduler->stop();
|
2020-08-21 09:24:05 +03:00
|
|
|
StopScriptCheckWorkerThreads();
|
2018-12-13 14:33:28 -05:00
|
|
|
GetMainSignals().FlushBackgroundCallbacks();
|
|
|
|
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
2019-09-17 18:59:36 -04:00
|
|
|
m_node.connman.reset();
|
|
|
|
m_node.banman.reset();
|
2020-10-23 09:34:27 +01:00
|
|
|
m_node.addrman.reset();
|
2021-08-31 18:40:18 +01:00
|
|
|
m_node.netgroupman.reset();
|
2020-04-08 19:47:56 -04:00
|
|
|
m_node.args = nullptr;
|
2020-07-19 20:30:46 +02:00
|
|
|
m_node.mempool.reset();
|
2023-10-24 08:38:06 +02:00
|
|
|
m_node.fee_estimator.reset();
|
2020-10-06 17:35:11 -04:00
|
|
|
m_node.chainman.reset();
|
2023-10-24 08:38:06 +02:00
|
|
|
m_node.scheduler.reset();
|
2015-03-03 07:49:12 -08:00
|
|
|
}
|
2011-10-03 16:14:13 -04:00
|
|
|
|
2023-05-05 13:12:30 +02:00
|
|
|
void ChainTestingSetup::LoadVerifyActivateChainstate()
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
{
|
2023-01-16 17:23:18 +01:00
|
|
|
auto& chainman{*Assert(m_node.chainman)};
|
2021-12-01 18:16:29 -05:00
|
|
|
node::ChainstateLoadOptions options;
|
|
|
|
options.mempool = Assert(m_node.mempool.get());
|
2022-04-13 15:16:26 -04:00
|
|
|
options.block_tree_db_in_memory = m_block_tree_db_in_memory;
|
|
|
|
options.coins_db_in_memory = m_coins_db_in_memory;
|
2021-12-01 18:16:29 -05:00
|
|
|
options.reindex = node::fReindex;
|
|
|
|
options.reindex_chainstate = m_args.GetBoolArg("-reindex-chainstate", false);
|
2023-01-16 17:23:18 +01:00
|
|
|
options.prune = chainman.m_blockman.IsPruneMode();
|
2021-12-01 18:16:29 -05:00
|
|
|
options.check_blocks = m_args.GetIntArg("-checkblocks", DEFAULT_CHECKBLOCKS);
|
|
|
|
options.check_level = m_args.GetIntArg("-checklevel", DEFAULT_CHECKLEVEL);
|
2022-10-06 17:11:02 -04:00
|
|
|
options.require_full_verification = m_args.IsArgSet("-checkblocks") || m_args.IsArgSet("-checklevel");
|
2023-01-16 17:23:18 +01:00
|
|
|
auto [status, error] = LoadChainstate(chainman, m_cache_sizes, options);
|
2021-12-01 18:16:29 -05:00
|
|
|
assert(status == node::ChainstateLoadStatus::SUCCESS);
|
2021-12-23 16:40:03 -05:00
|
|
|
|
2023-01-16 17:23:18 +01:00
|
|
|
std::tie(status, error) = VerifyLoadedChainstate(chainman, options);
|
2021-12-01 18:16:29 -05:00
|
|
|
assert(status == node::ChainstateLoadStatus::SUCCESS);
|
2021-12-03 11:57:56 -05:00
|
|
|
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
BlockValidationState state;
|
2023-01-16 17:23:18 +01:00
|
|
|
if (!chainman.ActiveChainstate().ActivateBestChain(state)) {
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
|
|
|
|
}
|
2022-04-28 10:57:25 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
TestingSetup::TestingSetup(
|
2023-04-17 22:20:59 +02:00
|
|
|
const ChainType chainType,
|
2022-04-28 10:57:25 -04:00
|
|
|
const std::vector<const char*>& extra_args,
|
|
|
|
const bool coins_db_in_memory,
|
|
|
|
const bool block_tree_db_in_memory)
|
2023-04-17 22:20:59 +02:00
|
|
|
: ChainTestingSetup(chainType, extra_args)
|
2022-04-28 10:57:25 -04:00
|
|
|
{
|
2023-05-05 13:12:30 +02:00
|
|
|
m_coins_db_in_memory = coins_db_in_memory;
|
|
|
|
m_block_tree_db_in_memory = block_tree_db_in_memory;
|
2022-04-28 10:57:25 -04:00
|
|
|
// Ideally we'd move all the RPC tests to the functional testing framework
|
|
|
|
// instead of unit tests, but for now we need these here.
|
|
|
|
RegisterAllCoreRPCCommands(tableRPC);
|
|
|
|
|
|
|
|
LoadVerifyActivateChainstate();
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
|
2021-08-31 18:40:18 +01:00
|
|
|
m_node.netgroupman = std::make_unique<NetGroupManager>(/*asmap=*/std::vector<bool>());
|
|
|
|
m_node.addrman = std::make_unique<AddrMan>(*m_node.netgroupman,
|
2021-10-26 17:56:19 +02:00
|
|
|
/*deterministic=*/false,
|
|
|
|
m_node.args->GetIntArg("-checkaddrman", 0));
|
2021-01-14 09:33:04 +01:00
|
|
|
m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
|
2023-09-12 13:42:36 +02:00
|
|
|
m_node.connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman, *m_node.netgroupman, Params()); // Deterministic randomness for tests.
|
2023-04-20 13:05:23 +02:00
|
|
|
PeerManager::Options peerman_opts;
|
|
|
|
ApplyArgsManOptions(*m_node.args, peerman_opts);
|
2023-10-02 14:41:08 +01:00
|
|
|
peerman_opts.deterministic_rng = true;
|
2022-05-18 18:29:04 +02:00
|
|
|
m_node.peerman = PeerManager::make(*m_node.connman, *m_node.addrman,
|
2021-07-28 16:18:53 -06:00
|
|
|
m_node.banman.get(), *m_node.chainman,
|
2023-04-20 13:05:23 +02:00
|
|
|
*m_node.mempool, peerman_opts);
|
|
|
|
|
test: Add new ChainTestingSetup and use it
Previously, the validation_chainstatemanager_tests test suite
instantiated its own duplicate ChainstateManager on which tests were
performed.
This wasn't a problem for the specific actions performed in
that suite. However, the existence of this duplicate ChainstateManager
and the fact that many of our validation static functions reach for
g_chainman, ::Chain(state|)Active means we may end up acting on two
different CChainStates should we write more extensive tests in the
future.
This change adds a new ChainTestingSetup which performs all
initialization previously done by TestingSetup except:
1. RPC command registration
2. ChainState initialization
3. Genesis Activation
4. {Ban,Conn,Peer}Man initialization
Means that we will no longer need to initialize a duplicate
ChainstateManger in order to test the initialization codepaths of
CChainState and ChainstateManager.
Lastly, this change has the additional benefit of allowing for
review-only assertions meant to show correctness to work in future work
de-globalizing g_chainman.
In the test chainstatemanager_rebalance_caches, an additional
LoadGenesisBlock call is added as MaybeReblanaceCaches eventually calls
FlushBlockFile, which tries to access vinfoBlockFile[nLastBlockFile],
which is out of bounds when LoadGenesisBlock hasn't been called yet.
-----
Note for the future:
The class con/destructor inheritance structure we have for these
TestingSetup classes is probably not the most suitable abstraction. In
particular, for both TestingSetup and ChainTestingSetup, we need to stop
the scheduler first before anything else. Otherwise classes depending on
the scheduler may be referenced by the scheduler after said classes are
freed. This means that there's no clear parallel between our teardown
code and C++'s destructuring order for class hierarchies.
Future work should strive to coalesce (as much as possible) test and
non-test init codepaths and perhaps structure it in a more fail-proof
way.
2020-10-13 16:55:20 -04:00
|
|
|
{
|
|
|
|
CConnman::Options options;
|
|
|
|
options.m_msgproc = m_node.peerman.get();
|
|
|
|
m_node.connman->Init(options);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-13 15:16:26 -04:00
|
|
|
TestChain100Setup::TestChain100Setup(
|
2023-04-17 22:20:59 +02:00
|
|
|
const ChainType chain_type,
|
2022-04-13 15:16:26 -04:00
|
|
|
const std::vector<const char*>& extra_args,
|
|
|
|
const bool coins_db_in_memory,
|
|
|
|
const bool block_tree_db_in_memory)
|
2023-04-17 22:20:59 +02:00
|
|
|
: TestingSetup{ChainType::REGTEST, extra_args, coins_db_in_memory, block_tree_db_in_memory}
|
2015-03-03 09:59:32 -05:00
|
|
|
{
|
2021-04-04 10:50:12 +02:00
|
|
|
SetMockTime(1598887952);
|
|
|
|
constexpr std::array<unsigned char, 32> vchKey = {
|
|
|
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}};
|
|
|
|
coinbaseKey.Set(vchKey.begin(), vchKey.end(), true);
|
2020-08-31 12:39:39 -04:00
|
|
|
|
2015-03-03 09:59:32 -05:00
|
|
|
// Generate a 100-block chain:
|
2020-08-31 12:39:39 -04:00
|
|
|
this->mineBlocks(COINBASE_MATURITY);
|
|
|
|
|
2021-04-04 10:50:12 +02:00
|
|
|
{
|
2020-08-31 12:39:39 -04:00
|
|
|
LOCK(::cs_main);
|
|
|
|
assert(
|
|
|
|
m_node.chainman->ActiveChain().Tip()->GetBlockHash().ToString() ==
|
2021-04-04 11:52:44 +02:00
|
|
|
"571d80a9967ae599cec0448b0b0ba1cfb606f584d8069bd7166b86854ba7a191");
|
2020-08-31 12:39:39 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestChain100Setup::mineBlocks(int num_blocks)
|
|
|
|
{
|
2020-08-21 15:37:38 +02:00
|
|
|
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
|
2021-04-04 10:50:12 +02:00
|
|
|
for (int i = 0; i < num_blocks; i++) {
|
2015-03-03 09:59:32 -05:00
|
|
|
std::vector<CMutableTransaction> noTxns;
|
|
|
|
CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
|
2021-04-04 10:50:12 +02:00
|
|
|
SetMockTime(GetTime() + 1);
|
2018-04-11 13:51:28 -04:00
|
|
|
m_coinbase_txns.push_back(b.vtx[0]);
|
2015-03-03 09:59:32 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-08 10:06:10 -04:00
|
|
|
CBlock TestChain100Setup::CreateBlock(
|
|
|
|
const std::vector<CMutableTransaction>& txns,
|
|
|
|
const CScript& scriptPubKey,
|
2022-03-09 12:37:19 -05:00
|
|
|
Chainstate& chainstate)
|
2015-03-03 09:59:32 -05:00
|
|
|
{
|
2022-05-25 22:06:23 -04:00
|
|
|
CBlock block = BlockAssembler{chainstate, nullptr}.CreateNewBlock(scriptPubKey)->block;
|
2015-03-03 09:59:32 -05:00
|
|
|
|
2020-08-21 15:20:10 +02:00
|
|
|
Assert(block.vtx.size() == 1);
|
2020-08-21 15:37:38 +02:00
|
|
|
for (const CMutableTransaction& tx : txns) {
|
2016-11-10 17:34:17 -08:00
|
|
|
block.vtx.push_back(MakeTransactionRef(tx));
|
2017-11-06 23:08:55 +01:00
|
|
|
}
|
2021-04-23 15:24:47 -04:00
|
|
|
RegenerateCommitments(block, *Assert(m_node.chainman));
|
2015-03-03 09:59:32 -05:00
|
|
|
|
2022-05-18 18:36:31 +02:00
|
|
|
while (!CheckProofOfWork(block.GetHash(), block.nBits, m_node.chainman->GetConsensus())) ++block.nNonce;
|
2015-03-03 09:59:32 -05:00
|
|
|
|
2021-04-08 10:06:10 -04:00
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
CBlock TestChain100Setup::CreateAndProcessBlock(
|
|
|
|
const std::vector<CMutableTransaction>& txns,
|
|
|
|
const CScript& scriptPubKey,
|
2022-03-09 12:37:19 -05:00
|
|
|
Chainstate* chainstate)
|
2021-04-08 10:06:10 -04:00
|
|
|
{
|
|
|
|
if (!chainstate) {
|
|
|
|
chainstate = &Assert(m_node.chainman)->ActiveChainstate();
|
|
|
|
}
|
|
|
|
|
2022-12-27 15:25:51 +00:00
|
|
|
CBlock block = this->CreateBlock(txns, scriptPubKey, *chainstate);
|
2016-12-04 00:17:30 -08:00
|
|
|
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
|
2022-08-02 16:48:57 -04:00
|
|
|
Assert(m_node.chainman)->ProcessNewBlock(shared_pblock, true, true, nullptr);
|
2015-03-03 09:59:32 -05:00
|
|
|
|
2020-08-21 15:37:38 +02:00
|
|
|
return block;
|
2015-03-03 09:59:32 -05:00
|
|
|
}
|
|
|
|
|
2022-10-03 10:56:00 +01:00
|
|
|
std::pair<CMutableTransaction, CAmount> TestChain100Setup::CreateValidTransaction(const std::vector<CTransactionRef>& input_transactions,
|
|
|
|
const std::vector<COutPoint>& inputs,
|
|
|
|
int input_height,
|
|
|
|
const std::vector<CKey>& input_signing_keys,
|
|
|
|
const std::vector<CTxOut>& outputs,
|
|
|
|
const std::optional<CFeeRate>& feerate,
|
|
|
|
const std::optional<uint32_t>& fee_output)
|
2021-01-25 11:51:38 -08:00
|
|
|
{
|
|
|
|
CMutableTransaction mempool_txn;
|
2022-10-03 10:56:00 +01:00
|
|
|
mempool_txn.vin.reserve(inputs.size());
|
|
|
|
mempool_txn.vout.reserve(outputs.size());
|
2021-01-25 11:51:38 -08:00
|
|
|
|
2022-10-03 10:56:00 +01:00
|
|
|
for (const auto& outpoint : inputs) {
|
|
|
|
mempool_txn.vin.emplace_back(outpoint, CScript(), MAX_BIP125_RBF_SEQUENCE);
|
|
|
|
}
|
|
|
|
mempool_txn.vout = outputs;
|
2021-01-25 11:51:38 -08:00
|
|
|
|
|
|
|
// - Add the signing key to a keystore
|
|
|
|
FillableSigningProvider keystore;
|
2022-10-03 10:56:00 +01:00
|
|
|
for (const auto& input_signing_key : input_signing_keys) {
|
|
|
|
keystore.AddKey(input_signing_key);
|
|
|
|
}
|
2021-01-25 11:51:38 -08:00
|
|
|
// - Populate a CoinsViewCache with the unspent output
|
|
|
|
CCoinsView coins_view;
|
|
|
|
CCoinsViewCache coins_cache(&coins_view);
|
2022-10-03 10:56:00 +01:00
|
|
|
for (const auto& input_transaction : input_transactions) {
|
|
|
|
AddCoins(coins_cache, *input_transaction.get(), input_height);
|
|
|
|
}
|
|
|
|
// Build Outpoint to Coin map for SignTransaction
|
2021-01-25 11:51:38 -08:00
|
|
|
std::map<COutPoint, Coin> input_coins;
|
2022-10-03 10:56:00 +01:00
|
|
|
CAmount inputs_amount{0};
|
|
|
|
for (const auto& outpoint_to_spend : inputs) {
|
|
|
|
// - Use GetCoin to properly populate utxo_to_spend,
|
|
|
|
Coin utxo_to_spend;
|
|
|
|
assert(coins_cache.GetCoin(outpoint_to_spend, utxo_to_spend));
|
|
|
|
input_coins.insert({outpoint_to_spend, utxo_to_spend});
|
|
|
|
inputs_amount += utxo_to_spend.out.nValue;
|
|
|
|
}
|
2021-01-25 11:51:38 -08:00
|
|
|
// - Default signature hashing type
|
|
|
|
int nHashType = SIGHASH_ALL;
|
2021-06-23 17:28:54 -04:00
|
|
|
std::map<int, bilingual_str> input_errors;
|
2021-01-25 11:51:38 -08:00
|
|
|
assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors));
|
2022-10-03 10:56:00 +01:00
|
|
|
CAmount current_fee = inputs_amount - std::accumulate(outputs.begin(), outputs.end(), CAmount(0),
|
|
|
|
[](const CAmount& acc, const CTxOut& out) {
|
|
|
|
return acc + out.nValue;
|
|
|
|
});
|
|
|
|
// Deduct fees from fee_output to meet feerate if set
|
|
|
|
if (feerate.has_value()) {
|
|
|
|
assert(fee_output.has_value());
|
|
|
|
assert(fee_output.value() < mempool_txn.vout.size());
|
|
|
|
CAmount target_fee = feerate.value().GetFee(GetVirtualTransactionSize(CTransaction{mempool_txn}));
|
|
|
|
CAmount deduction = target_fee - current_fee;
|
|
|
|
if (deduction > 0) {
|
|
|
|
// Only deduct fee if there's anything to deduct. If the caller has put more fees than
|
|
|
|
// the target feerate, don't change the fee.
|
|
|
|
mempool_txn.vout[fee_output.value()].nValue -= deduction;
|
|
|
|
// Re-sign since an output has changed
|
|
|
|
input_errors.clear();
|
|
|
|
assert(SignTransaction(mempool_txn, &keystore, input_coins, nHashType, input_errors));
|
|
|
|
current_fee = target_fee;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return {mempool_txn, current_fee};
|
|
|
|
}
|
2021-01-25 11:51:38 -08:00
|
|
|
|
2022-10-03 10:56:00 +01:00
|
|
|
CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(const std::vector<CTransactionRef>& input_transactions,
|
|
|
|
const std::vector<COutPoint>& inputs,
|
|
|
|
int input_height,
|
|
|
|
const std::vector<CKey>& input_signing_keys,
|
|
|
|
const std::vector<CTxOut>& outputs,
|
|
|
|
bool submit)
|
|
|
|
{
|
|
|
|
CMutableTransaction mempool_txn = CreateValidTransaction(input_transactions, inputs, input_height, input_signing_keys, outputs, std::nullopt, std::nullopt).first;
|
2021-05-04 08:05:43 -07:00
|
|
|
// If submit=true, add transaction to the mempool.
|
|
|
|
if (submit) {
|
2021-01-25 11:51:38 -08:00
|
|
|
LOCK(cs_main);
|
2021-09-27 17:47:21 +01:00
|
|
|
const MempoolAcceptResult result = m_node.chainman->ProcessTransaction(MakeTransactionRef(mempool_txn));
|
2021-01-25 11:51:38 -08:00
|
|
|
assert(result.m_result_type == MempoolAcceptResult::ResultType::VALID);
|
|
|
|
}
|
|
|
|
return mempool_txn;
|
|
|
|
}
|
|
|
|
|
2022-10-03 10:56:00 +01:00
|
|
|
CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactionRef input_transaction,
|
|
|
|
uint32_t input_vout,
|
|
|
|
int input_height,
|
|
|
|
CKey input_signing_key,
|
|
|
|
CScript output_destination,
|
|
|
|
CAmount output_amount,
|
|
|
|
bool submit)
|
|
|
|
{
|
|
|
|
COutPoint input{input_transaction->GetHash(), input_vout};
|
|
|
|
CTxOut output{output_amount, output_destination};
|
|
|
|
return CreateValidMempoolTransaction(/*input_transactions=*/{input_transaction},
|
|
|
|
/*inputs=*/{input},
|
|
|
|
/*input_height=*/input_height,
|
|
|
|
/*input_signing_keys=*/{input_signing_key},
|
|
|
|
/*outputs=*/{output},
|
|
|
|
/*submit=*/submit);
|
|
|
|
}
|
|
|
|
|
2022-04-20 14:04:11 -07:00
|
|
|
std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit)
|
|
|
|
{
|
|
|
|
std::vector<CTransactionRef> mempool_transactions;
|
|
|
|
std::deque<std::pair<COutPoint, CAmount>> unspent_prevouts;
|
|
|
|
std::transform(m_coinbase_txns.begin(), m_coinbase_txns.end(), std::back_inserter(unspent_prevouts),
|
|
|
|
[](const auto& tx){ return std::make_pair(COutPoint(tx->GetHash(), 0), tx->vout[0].nValue); });
|
|
|
|
while (num_transactions > 0 && !unspent_prevouts.empty()) {
|
|
|
|
// The number of inputs and outputs are random, between 1 and 24.
|
|
|
|
CMutableTransaction mtx = CMutableTransaction();
|
|
|
|
const size_t num_inputs = det_rand.randrange(24) + 1;
|
|
|
|
CAmount total_in{0};
|
|
|
|
for (size_t n{0}; n < num_inputs; ++n) {
|
|
|
|
if (unspent_prevouts.empty()) break;
|
|
|
|
const auto& [prevout, amount] = unspent_prevouts.front();
|
2023-10-04 13:53:40 +02:00
|
|
|
mtx.vin.emplace_back(prevout, CScript());
|
2022-04-20 14:04:11 -07:00
|
|
|
total_in += amount;
|
|
|
|
unspent_prevouts.pop_front();
|
|
|
|
}
|
|
|
|
const size_t num_outputs = det_rand.randrange(24) + 1;
|
2022-12-13 16:02:29 +00:00
|
|
|
const CAmount fee = 100 * det_rand.randrange(30);
|
|
|
|
const CAmount amount_per_output = (total_in - fee) / num_outputs;
|
2022-04-20 14:04:11 -07:00
|
|
|
for (size_t n{0}; n < num_outputs; ++n) {
|
|
|
|
CScript spk = CScript() << CScriptNum(num_transactions + n);
|
2023-10-04 13:53:40 +02:00
|
|
|
mtx.vout.emplace_back(amount_per_output, spk);
|
2022-04-20 14:04:11 -07:00
|
|
|
}
|
|
|
|
CTransactionRef ptx = MakeTransactionRef(mtx);
|
|
|
|
mempool_transactions.push_back(ptx);
|
2022-12-13 16:02:29 +00:00
|
|
|
if (amount_per_output > 3000) {
|
2022-04-20 14:04:11 -07:00
|
|
|
// If the value is high enough to fund another transaction + fees, keep track of it so
|
|
|
|
// it can be used to build a more complex transaction graph. Insert randomly into
|
|
|
|
// unspent_prevouts for extra randomness in the resulting structures.
|
|
|
|
for (size_t n{0}; n < num_outputs; ++n) {
|
2023-10-04 13:53:40 +02:00
|
|
|
unspent_prevouts.emplace_back(COutPoint(ptx->GetHash(), n), amount_per_output);
|
2022-04-20 14:04:11 -07:00
|
|
|
std::swap(unspent_prevouts.back(), unspent_prevouts[det_rand.randrange(unspent_prevouts.size())]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (submit) {
|
2022-12-16 14:14:25 +00:00
|
|
|
LOCK2(cs_main, m_node.mempool->cs);
|
2022-04-20 14:04:11 -07:00
|
|
|
LockPoints lp;
|
2022-12-13 16:02:29 +00:00
|
|
|
m_node.mempool->addUnchecked(CTxMemPoolEntry(ptx, /*fee=*/(total_in - num_outputs * amount_per_output),
|
2023-06-05 09:15:31 +10:00
|
|
|
/*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
|
2022-12-13 16:02:29 +00:00
|
|
|
/*spends_coinbase=*/false, /*sigops_cost=*/4, lp));
|
2022-04-20 14:04:11 -07:00
|
|
|
}
|
|
|
|
--num_transactions;
|
|
|
|
}
|
|
|
|
return mempool_transactions;
|
|
|
|
}
|
|
|
|
|
2023-01-17 11:00:49 +00:00
|
|
|
void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
|
|
|
|
{
|
|
|
|
LOCK2(cs_main, m_node.mempool->cs);
|
|
|
|
// Transactions in the mempool will affect the new minimum feerate.
|
|
|
|
assert(m_node.mempool->size() == 0);
|
|
|
|
// The target feerate cannot be too low...
|
|
|
|
// ...otherwise the transaction's feerate will need to be negative.
|
|
|
|
assert(target_feerate > m_node.mempool->m_incremental_relay_feerate);
|
|
|
|
// ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
|
|
|
|
assert(target_feerate > m_node.mempool->m_min_relay_feerate);
|
|
|
|
|
|
|
|
// Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
|
|
|
|
// achieve the exact target feerate.
|
|
|
|
CMutableTransaction mtx = CMutableTransaction();
|
2023-10-11 14:53:04 +01:00
|
|
|
mtx.vin.emplace_back(COutPoint{Txid::FromUint256(g_insecure_rand_ctx.rand256()), 0});
|
2023-10-04 13:53:40 +02:00
|
|
|
mtx.vout.emplace_back(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE)));
|
2023-01-17 11:00:49 +00:00
|
|
|
const auto tx{MakeTransactionRef(mtx)};
|
|
|
|
LockPoints lp;
|
|
|
|
// The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
|
|
|
|
const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
|
|
|
|
m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
|
|
|
|
m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee,
|
2023-06-05 09:15:31 +10:00
|
|
|
/*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
|
2023-01-17 11:00:49 +00:00
|
|
|
/*spends_coinbase=*/true, /*sigops_cost=*/1, lp));
|
|
|
|
m_node.mempool->TrimToSize(0);
|
|
|
|
assert(m_node.mempool->GetMinFee() == target_feerate);
|
|
|
|
}
|
2017-09-11 17:43:48 -07:00
|
|
|
/**
|
|
|
|
* @returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
|
|
|
|
* with 9 txs.
|
|
|
|
*/
|
|
|
|
CBlock getBlock13b8a()
|
|
|
|
{
|
|
|
|
CBlock block;
|
|
|
|
CDataStream stream(ParseHex("0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb6800000000000005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558da2fdb261b4d4c86041b1ab1bf930901000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0146ffffffff0100f2052a01000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf254bb5c7b949450c3e997c2dc1242487a8169507b631eb3771f2b425483fb13102c4eb5d858eef260fe70fbfae0ac00000000010000000196608ccbafa16abada902780da4dc35dafd7af05fa0da08cf833575f8cf9e836000000004a493046022100dab24889213caf43ae6adc41cf1c9396c08240c199f5225acf45416330fd7dbd022100fe37900e0644bf574493a07fc5edba06dbc07c311b947520c2d514bc5725dcb401ffffffff0100f2052a010000001976a914f15d1921f52e4007b146dfa60f369ed2fc393ce288ac000000000100000001fb766c1288458c2bafcfec81e48b24d98ec706de6b8af7c4e3c29419bfacb56d000000008c493046022100f268ba165ce0ad2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f022100da7c0f21adc6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d7290141042b4e8625a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b8d898235e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff0280969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388ac80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd388ac000000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3889e0c6c41aa8d0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2fafd60a129ed94504c4ac7bdc67b56fe67512658b3e014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffffca5065ff9617cbcba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb000000008a473044022068010362a13c7f9919fa832b2dee4e788f61f6f5d344a7c2a0da6ae740605658022006d1af525b9a14a35c003b78b72bd59738cd676f845d1ff3fc25049e01003614014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffff01001ec4110200000043410469ab4181eceb28985b9b4e895c13fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28ec9999ee3e021e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf2f758e91c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b48304502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddcce1fd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac002d3101000000001976a9141befba0cdc1ad56529371864d9f6cb042faa06b588ac000000000100000001b4a47603e71b61bc3326efd90111bf02d2f549b067f4c4a8fa183b57a0f800cb010000008a4730440220177c37f9a505c3f1a1f0ce2da777c339bd8339ffa02c7cb41f0a5804f473c9230220585b25a2ee80eb59292e52b987dad92acb0c64eced92ed9ee105ad153cdb12d001410443bd44f683467e549dae7d20d1d79cbdb6df985c6e9c029c8d0c6cb46cc1a4d3cf7923c5021b27f7a0b562ada113bc85d5fda5a1b41e87fe6e8802817cf69996ffffffff0280651406000000001976a9145505614859643ab7b547cd7f1f5e7e2a12322d3788ac00aa0271000000001976a914ea4720a7a52fc166c55ff2298e07baf70ae67e1b88ac00000000010000000586c62cd602d219bb60edb14a3e204de0705176f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba2534becbdf062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7ee0b95600db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e58ccdac3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b2179010000008b483045022100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3ca2f2020ffcf702200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b491d119d10624c83014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff2acfcab629bbc8685792603762c921580030ba144af553d271716a95089e107b010000008b483045022100fa579a840ac258871365dd48cd7552f96c8eea69bd00d84f05b283a0da
|
2023-09-07 19:16:57 +10:00
|
|
|
stream >> TX_WITH_WITNESS(block);
|
2017-09-11 17:43:48 -07:00
|
|
|
return block;
|
|
|
|
}
|