mirror of https://github.com/bitcoin/bitcoin.git
Merge bitcoin/bitcoin#33473: [30.x] Backports & rc3
4e869a67aa
doc: update example bitcoin conf for 30.0rc3 (fanquake)a2ac6cce57
doc: update manual pages for v30.0rc3 (fanquake)e4b568917c
build: bump version to v30.0rc3 (fanquake)f957c2171d
contrib: fix using macdploy script without translations. (amisha)1eb578045d
depends: static libxcb_cursor (fanquake)e4f9ec2f05
test: add more TRUC reorg coverge (Greg Sanders)3485252584
Mempool: Do not enforce TRUC checks on reorg (Greg Sanders)a3a1dcb589
fuzz: don't bypass_limits for most mempool harnesses (Greg Sanders)fce1c60770
datacarrier: Undeprecate configuration option (Anthony Towns)b75afaccb8
doc: rpc: fix case typo in `finalizepsbt` help (final_scriptwitness) (Sebastian Falbesoner)45703931e5
miner: fix `addPackageTxs` unsigned integer overflow (ismaelsadeeq)1e348bc55a
rpc: fix getblock(header) returns target for tip (Sjors Provoost)4ec30d53ec
test: add block 2016 to mock mainnet (Sjors Provoost) Pull request description: Backports: * #33434 * #33446 * #33453 * #33475 * #33482 * #33484 * #33504 Includes changes for `v30.0rc3`: * Version bump * Regen manpages * Regen exmaple .conf ACKs for top commit: marcofleon: lgtm ACK4e869a67aa
dergoegge: ACK4e869a67aa
hebasto: ACK4e869a67aa
, I agree on the backported PRs. I've reproduced locally all backports, the manpages update, and the example `bitcoin.conf` updated, and obtained zero diff with this PR. Zero-1729: LGTM ACK4e869a67aa
Tree-SHA512: 90bffbb6dfe2b512167b5e08253ea163b714505ec3ef2247d798c40b30713a7db13cf0b5486b5f9e0e5b3ba53108dfaeea47276c40816eeb81065d42bd402379
This commit is contained in:
commit
d5e0077bef
|
@ -30,7 +30,7 @@ set(CLIENT_NAME "Bitcoin Core")
|
|||
set(CLIENT_VERSION_MAJOR 30)
|
||||
set(CLIENT_VERSION_MINOR 0)
|
||||
set(CLIENT_VERSION_BUILD 0)
|
||||
set(CLIENT_VERSION_RC 2)
|
||||
set(CLIENT_VERSION_RC 3)
|
||||
set(CLIENT_VERSION_IS_RELEASE "true")
|
||||
set(COPYRIGHT_YEAR "2025")
|
||||
|
||||
|
|
|
@ -112,7 +112,6 @@ ELF_ALLOWED_LIBRARIES = {
|
|||
'libfontconfig.so.1', # font support
|
||||
'libfreetype.so.6', # font parsing
|
||||
'libdl.so.2', # programming interface to dynamic linker
|
||||
'libxcb-cursor.so.0',
|
||||
'libxcb-icccm.so.4',
|
||||
'libxcb-image.so.0',
|
||||
'libxcb-shm.so.0',
|
||||
|
|
|
@ -466,18 +466,18 @@ if config.translations_dir:
|
|||
sys.stderr.write(f"Error: Could not find translation dir \"{config.translations_dir[0]}\"\n")
|
||||
sys.exit(1)
|
||||
|
||||
print("+ Adding Qt translations +")
|
||||
print("+ Adding Qt translations +")
|
||||
|
||||
translations = Path(config.translations_dir[0])
|
||||
translations = Path(config.translations_dir[0])
|
||||
|
||||
regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)')
|
||||
regex = re.compile('qt_[a-z]*(.qm|_[A-Z]*.qm)')
|
||||
|
||||
lang_files = [x for x in translations.iterdir() if regex.match(x.name)]
|
||||
lang_files = [x for x in translations.iterdir() if regex.match(x.name)]
|
||||
|
||||
for file in lang_files:
|
||||
if verbose:
|
||||
print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
for file in lang_files:
|
||||
if verbose:
|
||||
print(file.as_posix(), "->", os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
shutil.copy2(file.as_posix(), os.path.join(applicationBundle.resourcesPath, file.name))
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ $(package)_sha256_hash=0e9c5446dc6f3beb8af6ebfcc9e27bcc6da6fe2860f7fc07b99144dfa
|
|||
$(package)_dependencies=libxcb libxcb_util_render libxcb_util_image
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts = --disable-static
|
||||
$(package)_config_opts = --disable-shared
|
||||
$(package)_config_opts += --disable-dependency-tracking --enable-option-checking
|
||||
endef
|
||||
|
||||
|
|
|
@ -81,8 +81,6 @@ the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if yo
|
|||
|
||||
sudo apt-get install qt6-base-dev qt6-tools-dev qt6-l10n-tools qt6-tools-dev-tools libgl-dev
|
||||
|
||||
For Qt 6.5 and later, the `libxcb-cursor0` package must be installed at runtime.
|
||||
|
||||
Additionally, to support Wayland protocol for modern desktop environments:
|
||||
|
||||
sudo apt install qt6-wayland
|
||||
|
@ -133,8 +131,6 @@ the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if yo
|
|||
|
||||
sudo dnf install qt6-qtbase-devel qt6-qttools-devel
|
||||
|
||||
For Qt 6.5 and later, the `xcb-util-cursor` package must be installed at runtime.
|
||||
|
||||
Additionally, to support Wayland protocol for modern desktop environments:
|
||||
|
||||
sudo dnf install qt6-qtwayland
|
||||
|
@ -182,8 +178,6 @@ the necessary parts of Qt, the libqrencode and pass `-DBUILD_GUI=ON`. Skip if yo
|
|||
|
||||
apk add qt6-qtbase-dev qt6-qttools-dev
|
||||
|
||||
For Qt 6.5 and later, the `xcb-util-cursor` package must be installed at runtime.
|
||||
|
||||
The GUI will be able to encode addresses in QR codes unless this feature is explicitly disabled. To install libqrencode, run:
|
||||
|
||||
apk add libqrencode-dev
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-CLI "1" "September 2025" "bitcoin-cli v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-CLI "1" "October 2025" "bitcoin-cli v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-cli \- manual page for bitcoin-cli v30.0.0rc2
|
||||
bitcoin-cli \- manual page for bitcoin-cli v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-cli
|
||||
[\fI\,options\/\fR] \fI\,<command> \/\fR[\fI\,params\/\fR]
|
||||
|
@ -15,7 +15,7 @@ bitcoin-cli \- manual page for bitcoin-cli v30.0.0rc2
|
|||
.B bitcoin-cli
|
||||
[\fI\,options\/\fR] \fI\,help <command>\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core RPC client version v30.0.0rc2
|
||||
Bitcoin Core RPC client version v30.0.0rc3
|
||||
.PP
|
||||
The bitcoin\-cli utility provides a command line interface to interact with a Bitcoin Core RPC server.
|
||||
.PP
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-QT "1" "September 2025" "bitcoin-qt v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-QT "1" "October 2025" "bitcoin-qt v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-qt \- manual page for bitcoin-qt v30.0.0rc2
|
||||
bitcoin-qt \- manual page for bitcoin-qt v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-qt
|
||||
[\fI\,options\/\fR] [\fI\,URI\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core version v30.0.0rc2
|
||||
Bitcoin Core version v30.0.0rc3
|
||||
.PP
|
||||
The bitcoin\-qt application provides a graphical interface for interacting with Bitcoin Core.
|
||||
.PP
|
||||
|
@ -695,13 +695,13 @@ Equivalent bytes per sigop in transactions for relay and mining
|
|||
.HP
|
||||
\fB\-datacarrier\fR
|
||||
.IP
|
||||
(DEPRECATED) Relay and mine data carrier transactions (default: 1)
|
||||
Relay and mine data carrier transactions (default: 1)
|
||||
.HP
|
||||
\fB\-datacarriersize\fR
|
||||
.IP
|
||||
(DEPRECATED) Relay and mine transactions whose data\-carrying raw
|
||||
scriptPubKeys in aggregate are of this size or less, allowing
|
||||
multiple outputs (default: 100000)
|
||||
Relay and mine transactions whose data\-carrying raw scriptPubKeys in
|
||||
aggregate are of this size or less, allowing multiple outputs
|
||||
(default: 100000)
|
||||
.HP
|
||||
\fB\-minrelaytxfee=\fR<amt>
|
||||
.IP
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-TX "1" "September 2025" "bitcoin-tx v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-TX "1" "October 2025" "bitcoin-tx v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-tx \- manual page for bitcoin-tx v30.0.0rc2
|
||||
bitcoin-tx \- manual page for bitcoin-tx v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-tx
|
||||
[\fI\,options\/\fR] \fI\,<hex-tx> \/\fR[\fI\,commands\/\fR]
|
||||
|
@ -9,7 +9,7 @@ bitcoin-tx \- manual page for bitcoin-tx v30.0.0rc2
|
|||
.B bitcoin-tx
|
||||
[\fI\,options\/\fR] \fI\,-create \/\fR[\fI\,commands\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-tx utility version v30.0.0rc2
|
||||
Bitcoin Core bitcoin\-tx utility version v30.0.0rc3
|
||||
.PP
|
||||
The bitcoin\-tx tool is used for creating and modifying bitcoin transactions.
|
||||
.PP
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-UTIL "1" "September 2025" "bitcoin-util v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-UTIL "1" "October 2025" "bitcoin-util v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-util \- manual page for bitcoin-util v30.0.0rc2
|
||||
bitcoin-util \- manual page for bitcoin-util v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-util
|
||||
[\fI\,options\/\fR] [\fI\,command\/\fR]
|
||||
|
@ -9,7 +9,7 @@ bitcoin-util \- manual page for bitcoin-util v30.0.0rc2
|
|||
.B bitcoin-util
|
||||
[\fI\,options\/\fR] \fI\,grind <hex-block-header>\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-util utility version v30.0.0rc2
|
||||
Bitcoin Core bitcoin\-util utility version v30.0.0rc3
|
||||
.PP
|
||||
The bitcoin\-util tool provides bitcoin related functionality that does not rely on the ability to access a running node. Available [commands] are listed below.
|
||||
.SH OPTIONS
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN-WALLET "1" "September 2025" "bitcoin-wallet v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN-WALLET "1" "October 2025" "bitcoin-wallet v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin-wallet \- manual page for bitcoin-wallet v30.0.0rc2
|
||||
bitcoin-wallet \- manual page for bitcoin-wallet v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin-wallet
|
||||
[\fI\,options\/\fR] \fI\,<command>\/\fR
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core bitcoin\-wallet utility version v30.0.0rc2
|
||||
Bitcoin Core bitcoin\-wallet utility version v30.0.0rc3
|
||||
.PP
|
||||
bitcoin\-wallet is an offline tool for creating and interacting with Bitcoin Core wallet files.
|
||||
.PP
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIN "1" "September 2025" "bitcoin v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIN "1" "October 2025" "bitcoin v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoin \- manual page for bitcoin v30.0.0rc2
|
||||
bitcoin \- manual page for bitcoin v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoin
|
||||
[\fI\,OPTIONS\/\fR] \fI\,COMMAND\/\fR...
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.3.
|
||||
.TH BITCOIND "1" "September 2025" "bitcoind v30.0.0rc2" "User Commands"
|
||||
.TH BITCOIND "1" "October 2025" "bitcoind v30.0.0rc3" "User Commands"
|
||||
.SH NAME
|
||||
bitcoind \- manual page for bitcoind v30.0.0rc2
|
||||
bitcoind \- manual page for bitcoind v30.0.0rc3
|
||||
.SH SYNOPSIS
|
||||
.B bitcoind
|
||||
[\fI\,options\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Bitcoin Core daemon version v30.0.0rc2
|
||||
Bitcoin Core daemon version v30.0.0rc3
|
||||
.PP
|
||||
The Bitcoin Core daemon (bitcoind) is a headless program that connects to the Bitcoin network to validate and relay transactions and blocks, as well as relaying addresses.
|
||||
.PP
|
||||
|
@ -695,13 +695,13 @@ Equivalent bytes per sigop in transactions for relay and mining
|
|||
.HP
|
||||
\fB\-datacarrier\fR
|
||||
.IP
|
||||
(DEPRECATED) Relay and mine data carrier transactions (default: 1)
|
||||
Relay and mine data carrier transactions (default: 1)
|
||||
.HP
|
||||
\fB\-datacarriersize\fR
|
||||
.IP
|
||||
(DEPRECATED) Relay and mine transactions whose data\-carrying raw
|
||||
scriptPubKeys in aggregate are of this size or less, allowing
|
||||
multiple outputs (default: 100000)
|
||||
Relay and mine transactions whose data\-carrying raw scriptPubKeys in
|
||||
aggregate are of this size or less, allowing multiple outputs
|
||||
(default: 100000)
|
||||
.HP
|
||||
\fB\-minrelaytxfee=\fR<amt>
|
||||
.IP
|
||||
|
|
|
@ -576,12 +576,12 @@
|
|||
# (default: 20)
|
||||
#bytespersigop=1
|
||||
|
||||
# (DEPRECATED) Relay and mine data carrier transactions (default: 1)
|
||||
# Relay and mine data carrier transactions (default: 1)
|
||||
#datacarrier=1
|
||||
|
||||
# (DEPRECATED) Relay and mine transactions whose data-carrying raw
|
||||
# scriptPubKeys in aggregate are of this size or less, allowing
|
||||
# multiple outputs (default: 100000)
|
||||
# Relay and mine transactions whose data-carrying raw scriptPubKeys in
|
||||
# aggregate are of this size or less, allowing multiple outputs
|
||||
# (default: 100000)
|
||||
#datacarriersize=1
|
||||
|
||||
# Fees (in BTC/kvB) smaller than this are considered zero fee for
|
||||
|
|
|
@ -658,9 +658,9 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
|
|||
argsman.AddArg("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define dust, the value of an output such that it will cost more than its value in fees at this fee rate to spend it. (default: %s)", CURRENCY_UNIT, FormatMoney(DUST_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-acceptstalefeeestimates", strprintf("Read fee estimates even if they are stale (%sdefault: %u) fee estimates are considered stale if they are %s hours old", "regtest only; ", DEFAULT_ACCEPT_STALE_FEE_ESTIMATES, Ticks<std::chrono::hours>(MAX_FILE_AGE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||
argsman.AddArg("-bytespersigop", strprintf("Equivalent bytes per sigop in transactions for relay and mining (default: %u)", DEFAULT_BYTES_PER_SIGOP), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarrier", strprintf("(DEPRECATED) Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
argsman.AddArg("-datacarriersize",
|
||||
strprintf("(DEPRECATED) Relay and mine transactions whose data-carrying raw scriptPubKeys in aggregate "
|
||||
strprintf("Relay and mine transactions whose data-carrying raw scriptPubKeys in aggregate "
|
||||
"are of this size or less, allowing multiple outputs (default: %u)",
|
||||
MAX_OP_RETURN_RELAY),
|
||||
ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
|
||||
|
@ -903,10 +903,6 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
|||
InitWarning(_("Option '-checkpoints' is set but checkpoints were removed. This option has no effect."));
|
||||
}
|
||||
|
||||
if (args.IsArgSet("-datacarriersize") || args.IsArgSet("-datacarrier")) {
|
||||
InitWarning(_("Options '-datacarrier' or '-datacarriersize' are set but are marked as deprecated and are expected to be removed in a future version."));
|
||||
}
|
||||
|
||||
// We no longer limit the orphanage based on number of transactions but keep the option to warn users who still have it in their config.
|
||||
if (args.IsArgSet("-maxorphantx")) {
|
||||
InitWarning(_("Option '-maxorphantx' is set but no longer has any effect (see release notes). Please remove it from your configuration."));
|
||||
|
|
|
@ -397,8 +397,8 @@ void BlockAssembler::addPackageTxs(int& nPackagesSelected, int& nDescendantsUpda
|
|||
|
||||
++nConsecutiveFailed;
|
||||
|
||||
if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight >
|
||||
m_options.nBlockMaxWeight - BLOCK_FULL_ENOUGH_WEIGHT_DELTA) {
|
||||
if (nConsecutiveFailed > MAX_CONSECUTIVE_FAILURES && nBlockWeight +
|
||||
BLOCK_FULL_ENOUGH_WEIGHT_DELTA > m_options.nBlockMaxWeight) {
|
||||
// Give up if we're close to full and haven't succeeded in a while
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex
|
|||
result.pushKV("mediantime", blockindex.GetMedianTimePast());
|
||||
result.pushKV("nonce", blockindex.nNonce);
|
||||
result.pushKV("bits", strprintf("%08x", blockindex.nBits));
|
||||
result.pushKV("target", GetTarget(tip, pow_limit).GetHex());
|
||||
result.pushKV("target", GetTarget(blockindex, pow_limit).GetHex());
|
||||
result.pushKV("difficulty", GetDifficulty(blockindex));
|
||||
result.pushKV("chainwork", blockindex.nChainWork.GetHex());
|
||||
result.pushKV("nTx", blockindex.nTx);
|
||||
|
|
|
@ -1608,7 +1608,7 @@ static RPCHelpMan finalizepsbt()
|
|||
return RPCHelpMan{"finalizepsbt",
|
||||
"Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
|
||||
"network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
|
||||
"created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n"
|
||||
"created which has the final_scriptSig and final_scriptwitness fields filled for inputs that are complete.\n"
|
||||
"Implements the Finalizer and Extractor roles.\n",
|
||||
{
|
||||
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
|
||||
|
|
|
@ -325,7 +325,7 @@ FUZZ_TARGET(ephemeral_package_eval, .init = initialize_tx_pool)
|
|||
return ProcessNewPackage(chainstate, tx_pool, txs, /*test_accept=*/single_submit, /*client_maxfeerate=*/{}));
|
||||
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, txs.back(), GetTime(),
|
||||
/*bypass_limits=*/fuzzed_data_provider.ConsumeBool(), /*test_accept=*/!single_submit));
|
||||
/*bypass_limits=*/false, /*test_accept=*/!single_submit));
|
||||
|
||||
if (!single_submit && result_package.m_state.GetResult() != PackageValidationResult::PCKG_POLICY) {
|
||||
// We don't know anything about the validity since transactions were randomly generated, so
|
||||
|
|
|
@ -296,7 +296,6 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
|||
std::set<CTransactionRef> added;
|
||||
auto txr = std::make_shared<TransactionsDelta>(removed, added);
|
||||
node.validation_signals->RegisterSharedValidationInterface(txr);
|
||||
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
||||
|
||||
// Make sure ProcessNewPackage on one transaction works.
|
||||
// The result is not guaranteed to be the same as what is returned by ATMP.
|
||||
|
@ -311,7 +310,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
|||
it->second.m_result_type == MempoolAcceptResult::ResultType::INVALID);
|
||||
}
|
||||
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), /*bypass_limits=*/false, /*test_accept=*/false));
|
||||
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||
node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||
node.validation_signals->UnregisterSharedValidationInterface(txr);
|
||||
|
@ -394,6 +393,9 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
|
|||
|
||||
chainstate.SetMempool(&tx_pool);
|
||||
|
||||
// If we ever bypass limits, do not do TRUC invariants checks
|
||||
bool ever_bypassed_limits{false};
|
||||
|
||||
LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300)
|
||||
{
|
||||
const auto mut_tx = ConsumeTransaction(fuzzed_data_provider, txids);
|
||||
|
@ -412,13 +414,17 @@ FUZZ_TARGET(tx_pool, .init = initialize_tx_pool)
|
|||
tx_pool.PrioritiseTransaction(txid, delta);
|
||||
}
|
||||
|
||||
const bool bypass_limits{fuzzed_data_provider.ConsumeBool()};
|
||||
ever_bypassed_limits |= bypass_limits;
|
||||
|
||||
const auto tx = MakeTransactionRef(mut_tx);
|
||||
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
||||
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||
if (accepted) {
|
||||
txids.push_back(tx->GetHash());
|
||||
CheckMempoolTRUCInvariants(tx_pool);
|
||||
if (!ever_bypassed_limits) {
|
||||
CheckMempoolTRUCInvariants(tx_pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
Finish(fuzzed_data_provider, tx_pool, chainstate);
|
||||
|
|
|
@ -1044,26 +1044,28 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// Even though just checking direct mempool parents for inheritance would be sufficient, we
|
||||
// check using the full ancestor set here because it's more convenient to use what we have
|
||||
// already calculated.
|
||||
if (const auto err{SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
|
||||
// Single transaction contexts only.
|
||||
if (args.m_allow_sibling_eviction && err->second != nullptr) {
|
||||
// We should only be considering where replacement is considered valid as well.
|
||||
Assume(args.m_allow_replacement);
|
||||
if (!args.m_bypass_limits) {
|
||||
if (const auto err{SingleTRUCChecks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
|
||||
// Single transaction contexts only.
|
||||
if (args.m_allow_sibling_eviction && err->second != nullptr) {
|
||||
// We should only be considering where replacement is considered valid as well.
|
||||
Assume(args.m_allow_replacement);
|
||||
|
||||
// Potential sibling eviction. Add the sibling to our list of mempool conflicts to be
|
||||
// included in RBF checks.
|
||||
ws.m_conflicts.insert(err->second->GetHash());
|
||||
// Adding the sibling to m_iters_conflicting here means that it doesn't count towards
|
||||
// RBF Carve Out above. This is correct, since removing to-be-replaced transactions from
|
||||
// the descendant count is done separately in SingleTRUCChecks for TRUC transactions.
|
||||
ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
|
||||
ws.m_sibling_eviction = true;
|
||||
// The sibling will be treated as part of the to-be-replaced set in ReplacementChecks.
|
||||
// Note that we are not checking whether it opts in to replaceability via BIP125 or TRUC
|
||||
// (which is normally done in PreChecks). However, the only way a TRUC transaction can
|
||||
// have a non-TRUC and non-BIP125 descendant is due to a reorg.
|
||||
} else {
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
|
||||
// Potential sibling eviction. Add the sibling to our list of mempool conflicts to be
|
||||
// included in RBF checks.
|
||||
ws.m_conflicts.insert(err->second->GetHash());
|
||||
// Adding the sibling to m_iters_conflicting here means that it doesn't count towards
|
||||
// RBF Carve Out above. This is correct, since removing to-be-replaced transactions from
|
||||
// the descendant count is done separately in SingleTRUCChecks for TRUC transactions.
|
||||
ws.m_iters_conflicting.insert(m_pool.GetIter(err->second->GetHash()).value());
|
||||
ws.m_sibling_eviction = true;
|
||||
// The sibling will be treated as part of the to-be-replaced set in ReplacementChecks.
|
||||
// Note that we are not checking whether it opts in to replaceability via BIP125 or TRUC
|
||||
// (which is normally done in PreChecks). However, the only way a TRUC transaction can
|
||||
// have a non-TRUC and non-BIP125 descendant is due to a reorg.
|
||||
} else {
|
||||
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "TRUC-violation", err->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,10 @@ The alternate mainnet chain was generated as follows:
|
|||
- restart node with a faketime 2 minutes later
|
||||
|
||||
```sh
|
||||
for i in {1..2015}
|
||||
for i in {1..2016}
|
||||
do
|
||||
faketime "`date -d @"$(( 1231006505 + $i * 120 ))" +'%Y-%m-%d %H:%M:%S'`" \
|
||||
t=$(( 1231006505 + $i * 120 ))
|
||||
faketime "`date -d @$t +'%Y-%m-%d %H:%M:%S'`" \
|
||||
bitcoind -connect=0 -nocheckpoints -stopatheight=$i
|
||||
done
|
||||
```
|
||||
|
@ -21,7 +22,9 @@ done
|
|||
The CPU miner is kept running as follows:
|
||||
|
||||
```sh
|
||||
./minerd --coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r --no-stratum --algo sha256d --no-longpoll --scantime 3 --retry-pause 1
|
||||
./minerd -u ... -p ... -o http://127.0.0.1:8332 --no-stratum \
|
||||
--coinbase-addr 1NQpH6Nf8QtR2HphLRcvuVqfhXBXsiWn8r \
|
||||
--algo sha256d --no-longpoll --scantime 3 --retry-pause 1
|
||||
```
|
||||
|
||||
The payout address is derived from first BIP32 test vector master key:
|
||||
|
@ -40,3 +43,8 @@ The timestamp was not kept constant because at difficulty 1 it's not sufficient
|
|||
to only grind the nonce. Grinding the extra_nonce or version field instead
|
||||
would have required additional (stratum) software. It would also make it more
|
||||
complicated to reconstruct the blocks in this test.
|
||||
|
||||
The `getblocktemplate` RPC code needs to be patched to ignore not being connected
|
||||
to any peers, and to ignore the IBD status check.
|
||||
|
||||
On macOS use `faketime "@$t"` instead.
|
||||
|
|
|
@ -2014,7 +2014,8 @@
|
|||
1231247971,
|
||||
1231248071,
|
||||
1231248198,
|
||||
1231248322
|
||||
1231248322,
|
||||
1231248621
|
||||
],
|
||||
"nonces": [
|
||||
2345621585,
|
||||
|
@ -4031,6 +4032,7 @@
|
|||
3658502865,
|
||||
2519048297,
|
||||
1915965760,
|
||||
1183846025
|
||||
1183846025,
|
||||
2713372123
|
||||
]
|
||||
}
|
||||
|
|
|
@ -100,17 +100,5 @@ class DataCarrierTest(BitcoinTestFramework):
|
|||
self.test_null_data_transaction(node=self.nodes[2], data=one_byte, success=True)
|
||||
self.test_null_data_transaction(node=self.nodes[3], data=one_byte, success=False)
|
||||
|
||||
# Clean shutdown boilerplate due to deprecation
|
||||
self.expected_stderr = [
|
||||
"", # node 0 has no deprecated options
|
||||
"Warning: Options '-datacarrier' or '-datacarriersize' are set but are marked as deprecated and are expected to be removed in a future version.",
|
||||
"Warning: Options '-datacarrier' or '-datacarriersize' are set but are marked as deprecated and are expected to be removed in a future version.",
|
||||
"Warning: Options '-datacarrier' or '-datacarriersize' are set but are marked as deprecated and are expected to be removed in a future version.",
|
||||
]
|
||||
|
||||
for i in range(self.num_nodes):
|
||||
self.stop_node(i, expected_stderr=self.expected_stderr[i])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
DataCarrierTest(__file__).main()
|
||||
|
|
|
@ -165,23 +165,36 @@ class MempoolTRUC(BitcoinTestFramework):
|
|||
def test_truc_reorg(self):
|
||||
node = self.nodes[0]
|
||||
self.log.info("Test that, during a reorg, TRUC rules are not enforced")
|
||||
tx_v2_block = self.wallet.send_self_transfer(from_node=node, version=2)
|
||||
tx_v3_block = self.wallet.send_self_transfer(from_node=node, version=3)
|
||||
tx_v3_block2 = self.wallet.send_self_transfer(from_node=node, version=3)
|
||||
self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"]])
|
||||
self.check_mempool([])
|
||||
|
||||
# Testing 2<-3 versions allowed
|
||||
tx_v2_block = self.wallet.create_self_transfer(version=2)
|
||||
|
||||
# Testing 3<-2 versions allowed
|
||||
tx_v3_block = self.wallet.create_self_transfer(version=3)
|
||||
|
||||
# Testing overly-large child size
|
||||
tx_v3_block2 = self.wallet.create_self_transfer(version=3)
|
||||
|
||||
# Also create a linear chain of 3 TRUC transactions that will be directly mined, followed by one v2 in-mempool after block is made
|
||||
tx_chain_1 = self.wallet.create_self_transfer(version=3)
|
||||
tx_chain_2 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_1["new_utxo"], version=3)
|
||||
tx_chain_3 = self.wallet.create_self_transfer(utxo_to_spend=tx_chain_2["new_utxo"], version=3)
|
||||
|
||||
tx_to_mine = [tx_v3_block["hex"], tx_v2_block["hex"], tx_v3_block2["hex"], tx_chain_1["hex"], tx_chain_2["hex"], tx_chain_3["hex"]]
|
||||
block = self.generateblock(node, output="raw(42)", transactions=tx_to_mine)
|
||||
|
||||
block = self.generate(node, 1)
|
||||
self.check_mempool([])
|
||||
tx_v2_from_v3 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block["new_utxo"], version=2)
|
||||
tx_v3_from_v2 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v2_block["new_utxo"], version=3)
|
||||
tx_v3_child_large = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_v3_block2["new_utxo"], target_vsize=1250, version=3)
|
||||
assert_greater_than(node.getmempoolentry(tx_v3_child_large["txid"])["vsize"], TRUC_CHILD_MAX_VSIZE)
|
||||
self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"]])
|
||||
node.invalidateblock(block[0])
|
||||
self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"]])
|
||||
# This is needed because generate() will create the exact same block again.
|
||||
node.reconsiderblock(block[0])
|
||||
tx_chain_4 = self.wallet.send_self_transfer(from_node=node, utxo_to_spend=tx_chain_3["new_utxo"], version=2)
|
||||
self.check_mempool([tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_4["txid"]])
|
||||
|
||||
# Reorg should have all block transactions re-accepted, ignoring TRUC enforcement
|
||||
node.invalidateblock(block["hash"])
|
||||
self.check_mempool([tx_v3_block["txid"], tx_v2_block["txid"], tx_v3_block2["txid"], tx_v2_from_v3["txid"], tx_v3_from_v2["txid"], tx_v3_child_large["txid"], tx_chain_1["txid"], tx_chain_2["txid"], tx_chain_3["txid"], tx_chain_4["txid"]])
|
||||
|
||||
@cleanup(extra_args=["-limitdescendantsize=10"])
|
||||
def test_nondefault_package_limits(self):
|
||||
|
|
|
@ -53,15 +53,15 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||
help='Block data file (default: %(default)s)',
|
||||
)
|
||||
|
||||
def mine(self, height, prev_hash, blocks, node, fees=0):
|
||||
def mine(self, height, prev_hash, blocks, node):
|
||||
self.log.debug(f"height={height}")
|
||||
block = CBlock()
|
||||
block.nVersion = 0x20000000
|
||||
block.hashPrevBlock = int(prev_hash, 16)
|
||||
block.nTime = blocks['timestamps'][height - 1]
|
||||
block.nBits = DIFF_1_N_BITS
|
||||
block.nBits = DIFF_1_N_BITS if height < 2016 else DIFF_4_N_BITS
|
||||
block.nNonce = blocks['nonces'][height - 1]
|
||||
block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), retarget_period=2016)]
|
||||
block.vtx = [create_coinbase(height=height, script_pubkey=bytes.fromhex(COINBASE_SCRIPT_PUBKEY), halving_period=210000)]
|
||||
# The alternate mainnet chain was mined with non-timelocked coinbase txs.
|
||||
block.vtx[0].nLockTime = 0
|
||||
block.vtx[0].vin[0].nSequence = SEQUENCE_FINAL
|
||||
|
@ -82,12 +82,15 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||
self.log.info("Load alternative mainnet blocks")
|
||||
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), self.options.datafile)
|
||||
prev_hash = node.getbestblockhash()
|
||||
blocks = None
|
||||
with open(path, encoding='utf-8') as f:
|
||||
blocks = json.load(f)
|
||||
n_blocks = len(blocks['timestamps'])
|
||||
assert_equal(n_blocks, 2015)
|
||||
for i in range(2015):
|
||||
prev_hash = self.mine(i + 1, prev_hash, blocks, node)
|
||||
assert_equal(n_blocks, 2016)
|
||||
|
||||
# Mine up to the last block of the first retarget period
|
||||
for i in range(2015):
|
||||
prev_hash = self.mine(i + 1, prev_hash, blocks, node)
|
||||
|
||||
assert_equal(node.getblockcount(), 2015)
|
||||
|
||||
|
@ -102,5 +105,21 @@ class MiningMainnetTest(BitcoinTestFramework):
|
|||
assert_equal(mining_info['next']['bits'], nbits_str(DIFF_4_N_BITS))
|
||||
assert_equal(mining_info['next']['target'], target_str(DIFF_4_TARGET))
|
||||
|
||||
# Mine first block of the second retarget period
|
||||
height = 2016
|
||||
prev_hash = self.mine(height, prev_hash, blocks, node)
|
||||
assert_equal(node.getblockcount(), height)
|
||||
|
||||
mining_info = node.getmininginfo()
|
||||
assert_equal(mining_info['difficulty'], 4)
|
||||
|
||||
self.log.info("getblock RPC should show historical target")
|
||||
block_info = node.getblock(node.getblockhash(1))
|
||||
|
||||
assert_equal(block_info['difficulty'], 1)
|
||||
assert_equal(block_info['bits'], nbits_str(DIFF_1_N_BITS))
|
||||
assert_equal(block_info['target'], target_str(DIFF_1_TARGET))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
MiningMainnetTest(__file__).main()
|
||||
|
|
|
@ -144,7 +144,7 @@ def script_BIP34_coinbase_height(height):
|
|||
return CScript([CScriptNum(height)])
|
||||
|
||||
|
||||
def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, retarget_period=REGTEST_RETARGET_PERIOD):
|
||||
def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_script=None, fees=0, nValue=50, halving_period=REGTEST_RETARGET_PERIOD):
|
||||
"""Create a coinbase transaction.
|
||||
|
||||
If pubkey is passed in, the coinbase output will be a P2PK output;
|
||||
|
@ -158,7 +158,7 @@ def create_coinbase(height, pubkey=None, *, script_pubkey=None, extra_output_scr
|
|||
coinbaseoutput = CTxOut()
|
||||
coinbaseoutput.nValue = nValue * COIN
|
||||
if nValue == 50:
|
||||
halvings = int(height / retarget_period)
|
||||
halvings = int(height / halving_period)
|
||||
coinbaseoutput.nValue >>= halvings
|
||||
coinbaseoutput.nValue += fees
|
||||
if pubkey is not None:
|
||||
|
|
Loading…
Reference in New Issue