Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0ca6839
Add concept of temporary softforks (buried only for now)
luke-jr Oct 4, 2025
69cdd1f
Define no-op "reduced_data" buried deployment (no activation params)
luke-jr Oct 4, 2025
6257eb2
Use TAPROOT_CONTROL_MAX_NODE_COUNT_REDUCED for non-consensus Taproot …
luke-jr Oct 3, 2025
0bd7de3
Policy: Enforce SCRIPT_VERIFY_REDUCED_DATA as a policy rule
luke-jr Oct 4, 2025
ab89af2
script: Define SCRIPT_VERIFY_REDUCED_DATA verification flag (unused) …
luke-jr Oct 6, 2025
4669be9
script: Limit Taproot annex to 256 bytes for SCRIPT_VERIFY_REDUCED_DA…
luke-jr Oct 3, 2025
869ea40
script: Forbid Taproot annex entirely with SCRIPT_VERIFY_REDUCED_DATA…
luke-jr Oct 3, 2025
cf21920
script: Forbid OP_IF in Tapscript with SCRIPT_VERIFY_REDUCED_DATA (st…
luke-jr Oct 3, 2025
e94bfc1
script: Limit Taproot control block to 257 bytes for SCRIPT_VERIFY_RE…
luke-jr Oct 3, 2025
1adc64b
consensus: Enforce SCRIPT_VERIFY_REDUCED_DATA if DEPLOYMENT_REDUCED_D…
luke-jr Oct 4, 2025
1019466
Limit datacarriersize config to MAX_OUTPUT_DATA_SIZE (=83 B)
luke-jr Oct 4, 2025
a42df5b
consensus: Add no-op flags to CheckTxInputs function
luke-jr Oct 3, 2025
6957cb4
consensus: Define CheckTxInputsRules::OutputSizeLimit flag (unused) t…
luke-jr Oct 7, 2025
a632853
consensus: When CheckTxInputsRules::OutputSizeLimit is enforced (stil…
luke-jr Oct 7, 2025
aceba7d
QA: rpc_getdescriptoractivity: Use RAW_OP_TRUE for test_no_address
luke-jr Oct 7, 2025
e579f20
QA: test_framework/wallet: Turn MiniWalletMode.RAW_P2PK into actually…
luke-jr Oct 7, 2025
0235c6a
RPC/Mempool: Provide tx memory usage in testmempoolaccept
luke-jr Oct 8, 2025
4a8054e
QA: test_framework/mempool_util: Calibrate fill_mempool bulk tx size …
luke-jr Oct 8, 2025
e6e26a8
Bugfix: QA: mempool_limit: Use "usage" rather than "bytes"
luke-jr Oct 8, 2025
368b84a
QA: test_framework: Use multiple OP_RETURNs to pad transactions rathe…
luke-jr Oct 7, 2025
bc2ed08
consensus: Enforce CheckTxInputsRules::OutputSizeLimit when DEPLOYMEN…
luke-jr Oct 4, 2025
2cc8124
Policy: Do not allow user to bypass SCRIPT_VERIFY_DISCOURAGE_{UPGRADA…
luke-jr Oct 4, 2025
90cd949
consensus: Enforce SCRIPT_VERIFY_DISCOURAGE_{UPGRADABLE_WITNESS_PROGR…
luke-jr Oct 4, 2025
14c0f5b
Simple check for and invalidating (TBD) bad block
luke-jr Oct 12, 2025
1c91125
Define a service bit for BIP148
luke-jr May 31, 2017
7c80bb6
Add questionmark to end of BIP148 service bit string, and add to bitc…
luke-jr Oct 20, 2025
e2e6691
Preferentially peer with nodes enforcing BIP148 to avoid partitioning…
luke-jr May 31, 2017
a0933c2
Append UA string with UASF-ReducedData:0.1/
luke-jr Oct 20, 2025
1231c4d
tests: fix feature_cltv, feature_dersig, mempool_accept, and mempool_…
moneybadger1 Nov 1, 2025
f767bab
tests: fix BIP148 service bit
moneybadger1 Nov 1, 2025
70eeda3
test: Adapt functional tests to MAX_OUTPUT_SCRIPT_SIZE=34 consensus l…
3c853b6299 Nov 1, 2025
68a7bbc
test: Skip test_segwit_versions subtest (conflicts with DEPLOYMENT_RE…
3c853b6299 Nov 2, 2025
414bdb2
Fix p2p_1p1c_network test by using dynamic feerates based on mempool …
dathonohm Nov 2, 2025
5c4302c
Fix interface_bitcoin_cli test to accept BIP148 service bit
dathonohm Nov 3, 2025
4a80c5f
Fix p2p_addrv2_relay test to handle BIP148 service bit CompactSize en…
dathonohm Nov 3, 2025
dc24f53
Fix addpeeraddress RPC to include NODE_BIP148 service flag
dathonohm Nov 3, 2025
7ffa7f4
Refactor: Include all reduced_data verify flags in REDUCED_DATA_MANDA…
luke-jr Nov 3, 2025
d9f6e13
validation: Extend CheckInputScripts to allow overriding script valid…
luke-jr Nov 3, 2025
706651b
validation: Exempt inputs spending UTXOs prior to ReducedDataHeightBe…
luke-jr Nov 3, 2025
ebb01d9
fixup! test: skip test_segwit_versions subtest conflicting with DEPLO…
luke-jr Nov 3, 2025
c37e856
Rename BIP148 service bit to BIP444
luke-jr Nov 3, 2025
85f7b0a
clientversion: Rename fork to UASF-BIP444
luke-jr Nov 3, 2025
c919c17
test: implement functional tests for UASF-ReducedData Spec
3c853b6299 Nov 5, 2025
7dd40db
test: Add UTXO height-based REDUCED_DATA enforcement test
dathonohm Nov 7, 2025
d859029
test: Update tests for REDUCED_DATA consensus limits
dathonohm Nov 7, 2025
7fd3cdc
test: Replace thresh() with and_v() in descriptor test
dathonohm Nov 7, 2025
bb118dc
test: Add NODE_BIP444 service flag to peer connection tests
dathonohm Nov 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/bitcoin-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,21 @@ class NetinfoRequestHandler : public BaseRequestHandler
std::string str;
for (size_t i = 0; i < services.size(); ++i) {
const std::string s{services[i].get_str()};
str += s == "NETWORK_LIMITED" ? 'l' : s == "P2P_V2" ? '2' : ToLower(s[0]);
if (s == "NETWORK_LIMITED") {
str += 'l';
} else if (s == "P2P_V2") {
str += '2';
} else if (s == "UTREEXO") {
str += 't';
} else if (s == "UTREEXO_ARCHIVE") {
str += 'T';
} else if (s == "UTREEXO_TMP?") {
str += 'y';
} else if (s == "BIP444?") {
str += '1';
} else {
str += ToLower(s[0]);
}
}
return str;
}
Expand Down Expand Up @@ -711,6 +725,12 @@ class NetinfoRequestHandler : public BaseRequestHandler
" \"c\" - COMPACT_FILTERS: peer can handle basic block filter requests (see BIPs 157 and 158)\n"
" \"l\" - NETWORK_LIMITED: peer limited to serving only the last 288 blocks (~2 days)\n"
" \"2\" - P2P_V2: peer supports version 2 P2P transport protocol, as defined in BIP 324\n"
" \"t\" - UTREEXO peer can handle Utreexo proof requests for blocks it serves\n"
" \"T\" - UTREEXO_ARCHIVE peer can handle Utreexo proof requests for all historical blocks\n"
" \"y\" - UTREEXO_TMP? peer can handle Utreexo proof requests\n"
" \"r\" - REPLACE_BY_FEE? peer supports replacement of transactions without BIP 125 signalling\n"
" \"4\" - BIP444? peer enforces the BIP444 User-Activated SoftFork\n"
" \"m\" - MALICIOUS? peer openly seeks to aid in bypassing network policy/spam filters (OR to sabotage nodes that seek to)\n"
" \"u\" - UNKNOWN: unrecognized bit flag\n"
" v Version of transport protocol used for the connection\n"
" mping Minimum observed ping time, in milliseconds (ms)\n"
Expand Down
11 changes: 10 additions & 1 deletion src/clientversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,16 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
{
std::string comments_str;
if (!comments.empty()) comments_str = strprintf("(%s)", Join(comments, "; "));
return strprintf("/%s:%s%s/", name, FormatVersion(nClientVersion), comments_str);
std::string ua = strprintf("/%s:%s%s/", name, FormatVersion(nClientVersion), comments_str);
if (!base_name_only) {
static const auto ua_knots = []() -> std::string {
const auto pos{CLIENT_BUILD.find(".knots")};
return "Knots:" + CLIENT_BUILD.substr(pos + 6) + "/";
}();
ua += ua_knots;
ua += "UASF-BIP444:0.1/";
}
return ua;
}

std::string CopyrightHolders(const std::string& strPrefix)
Expand Down
3 changes: 3 additions & 0 deletions src/consensus/consensus.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@ static constexpr unsigned int LOCKTIME_VERIFY_SEQUENCE = (1 << 0);
*/
static constexpr int64_t MAX_TIMEWARP = 600;

static constexpr unsigned int MAX_OUTPUT_SCRIPT_SIZE{34};
static constexpr unsigned int MAX_OUTPUT_DATA_SIZE{83};

#endif // BITCOIN_CONSENSUS_CONSENSUS_H
24 changes: 23 additions & 1 deletion src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ enum BuriedDeployment : int16_t {
DEPLOYMENT_DERSIG,
DEPLOYMENT_CSV,
DEPLOYMENT_SEGWIT,
DEPLOYMENT_REDUCED_DATA,
};
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_SEGWIT; }
constexpr bool ValidDeployment(BuriedDeployment dep) { return dep <= DEPLOYMENT_REDUCED_DATA; }

enum DeploymentPos : uint16_t {
DEPLOYMENT_TESTDUMMY,
Expand Down Expand Up @@ -103,6 +104,9 @@ struct Params {
* Note that segwit v0 script rules are enforced on all blocks except the
* BIP 16 exception blocks. */
int SegwitHeight;
/** Block heights during which Reduced Data is active */
int ReducedDataHeightBegin{std::numeric_limits<int>::max()};
int ReducedDataHeightEnd{std::numeric_limits<int>::max()};
/** Don't warn about unknown BIP 9 activations below this height.
* This prevents us from warning about the CSV and segwit activations. */
int MinBIP9WarningHeight;
Expand Down Expand Up @@ -148,6 +152,24 @@ struct Params {
return CSVHeight;
case DEPLOYMENT_SEGWIT:
return SegwitHeight;
case DEPLOYMENT_REDUCED_DATA:
return ReducedDataHeightBegin;
} // no default case, so the compiler can warn about missing cases
return std::numeric_limits<int>::max();
}

int DeploymentHeightEnd(BuriedDeployment dep) const
{
switch (dep) {
case DEPLOYMENT_HEIGHTINCB:
case DEPLOYMENT_CLTV:
case DEPLOYMENT_DERSIG:
case DEPLOYMENT_CSV:
case DEPLOYMENT_SEGWIT:
// These are forever
break;
case DEPLOYMENT_REDUCED_DATA:
return ReducedDataHeightEnd;
} // no default case, so the compiler can warn about missing cases
return std::numeric_limits<int>::max();
}
Expand Down
12 changes: 11 additions & 1 deletion src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,24 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
return nSigOps;
}

bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee)
bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, const CheckTxInputsRules rules)
{
// are the actual inputs available?
if (!inputs.HaveInputs(tx)) {
return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
strprintf("%s: inputs missing/spent", __func__));
}

// NOTE: CheckTransaction is arguably the more logical place to do this, but it's context-independent, so this is probably the next best place for now
if (rules.test(CheckTxInputsRules::OutputSizeLimit)) {
for (const auto& txout : tx.vout) {
if (txout.scriptPubKey.empty()) continue;
if (txout.scriptPubKey.size() > ((txout.scriptPubKey[0] == OP_RETURN) ? MAX_OUTPUT_DATA_SIZE : MAX_OUTPUT_SCRIPT_SIZE)) {
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-vout-script-toolarge");
}
}
}

CAmount nValueIn = 0;
for (unsigned int i = 0; i < tx.vin.size(); ++i) {
const COutPoint &prevout = tx.vin[i].prevout;
Expand Down
26 changes: 25 additions & 1 deletion src/consensus/tx_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,38 @@ class TxValidationState;

/** Transaction validation functions */

class CheckTxInputsRules {
using underlying_type = unsigned int;
underlying_type m_flags;
constexpr explicit CheckTxInputsRules(underlying_type flags) noexcept : m_flags(flags) {}

enum class Rule {
None = 0,
OutputSizeLimit = 1 << 0,
};

public:
using enum Rule;

constexpr CheckTxInputsRules(Rule rule) noexcept : m_flags(static_cast<underlying_type>(rule)) {}

[[nodiscard]] constexpr bool test(CheckTxInputsRules rules) const noexcept {
return (m_flags & rules.m_flags) == rules.m_flags;
}

[[nodiscard]] constexpr CheckTxInputsRules operator|(const CheckTxInputsRules other) const noexcept {
return CheckTxInputsRules{m_flags | other.m_flags};
}
};

namespace Consensus {
/**
* Check whether all inputs of this transaction are valid (no double spends and amounts)
* This does not modify the UTXO set. This does not check scripts and sigs.
* @param[out] txfee Set to the transaction fee if successful.
* Preconditions: tx.IsCoinBase() is false.
*/
[[nodiscard]] bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee);
[[nodiscard]] bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, CheckTxInputsRules rules);
} // namespace Consensus

/** Auxiliary functions for transaction validation (ideally should not be exposed) */
Expand Down
5 changes: 5 additions & 0 deletions src/deploymentinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ std::string DeploymentName(Consensus::BuriedDeployment dep)
return "csv";
case Consensus::DEPLOYMENT_SEGWIT:
return "segwit";
case Consensus::DEPLOYMENT_REDUCED_DATA:
return "reduced_data";
} // no default case, so the compiler can warn about missing cases
return "";
}
Expand All @@ -49,6 +51,9 @@ std::optional<Consensus::BuriedDeployment> GetBuriedDeployment(const std::string
return Consensus::BuriedDeployment::DEPLOYMENT_CLTV;
} else if (name == "csv") {
return Consensus::BuriedDeployment::DEPLOYMENT_CSV;
} else if (name == "reduced_data") {
return Consensus::BuriedDeployment::DEPLOYMENT_REDUCED_DATA;
}

return std::nullopt;
}
5 changes: 3 additions & 2 deletions src/deploymentstatus.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
return (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1) >= params.DeploymentHeight(dep);
const auto next_block_height = (pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1);
return next_block_height >= params.DeploymentHeight(dep) && next_block_height <= params.DeploymentHeightEnd(dep);
}

inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
Expand All @@ -27,7 +28,7 @@ inline bool DeploymentActiveAfter(const CBlockIndex* pindexPrev, const Consensus
inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::BuriedDeployment dep, [[maybe_unused]] VersionBitsCache& versionbitscache)
{
assert(Consensus::ValidDeployment(dep));
return index.nHeight >= params.DeploymentHeight(dep);
return index.nHeight >= params.DeploymentHeight(dep) && index.nHeight <= params.DeploymentHeightEnd(dep);
}

inline bool DeploymentActiveAt(const CBlockIndex& index, const Consensus::Params& params, Consensus::DeploymentPos dep, VersionBitsCache& versionbitscache)
Expand Down
27 changes: 24 additions & 3 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,8 +660,8 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
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("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-datacarriersize",
strprintf("Relay and mine transactions whose data-carrying raw scriptPubKeys in aggregate "
"are of this size or less, allowing multiple outputs (default: %u)",
strprintf("Maximum size of data in data carrier transactions we relay and mine, in bytes (maximum %s, default: %u)",
MAX_OUTPUT_DATA_SIZE,
MAX_OP_RETURN_RELAY),
ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
argsman.AddArg("-permitbaremultisig", strprintf("Relay transactions creating non-P2SH multisig outputs (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY,
Expand Down Expand Up @@ -835,7 +835,7 @@ namespace { // Variables internal to initialization process only

int nMaxConnections;
int available_fds;
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
ServiceFlags g_local_services = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_BIP444);
int64_t peer_connect_timeout;
std::set<BlockFilterType> g_enabled_filter_types;

Expand Down Expand Up @@ -1929,6 +1929,27 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
return;
}

constexpr uint256 bad_block_hash{"0000000000000000000000000000000000000000000000000000000000000000"};
BlockValidationState state;
CBlockIndex* pblockindex;
{
LOCK(chainman.GetMutex());
pblockindex = chainman.m_blockman.LookupBlockIndex(bad_block_hash);
if (pblockindex && !pblockindex->IsValid(BLOCK_VALID_UNKNOWN)) {
// Already marked invalid
pblockindex = nullptr;
}
}
if (pblockindex) {
if (!chainman.ActiveChainstate().InvalidateBlock(state, pblockindex)) {
state.Error("InvalidateBlock failed (is your node too pruned?)");
}
if (state.IsValid()) {
chainman.ActiveChainstate().ActivateBestChain(state);
}
Assert(state.IsValid());
}

// Start indexes initial sync
if (!StartIndexBackgroundSync(node)) {
bilingual_str err_str = _("Failed to start indexes, shutting down…");
Expand Down
5 changes: 5 additions & 0 deletions src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,11 @@ class CRegTestParams : public CChainParams
case Consensus::BuriedDeployment::DEPLOYMENT_CSV:
consensus.CSVHeight = int{height};
break;
case Consensus::BuriedDeployment::DEPLOYMENT_REDUCED_DATA:
consensus.ReducedDataHeightBegin = int(height);
// TODO: Make end height configurable
consensus.ReducedDataHeightEnd = consensus.ReducedDataHeightBegin + consensus.nPowTargetTimespan;
break;
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,13 +1667,14 @@ bool PeerManagerImpl::HasAllDesirableServiceFlags(ServiceFlags services) const

ServiceFlags PeerManagerImpl::GetDesirableServiceFlags(ServiceFlags services) const
{
// We want to preferentially peer with other nodes that enforce BIP444, in case of a chain split
if (services & NODE_NETWORK_LIMITED) {
// Limited peers are desirable when we are close to the tip.
if (ApproximateBestBlockDepth() < NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS) {
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS);
return ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS | NODE_BIP444);
}
}
return ServiceFlags(NODE_NETWORK | NODE_WITNESS);
return ServiceFlags(NODE_NETWORK | NODE_WITNESS | NODE_BIP444);
}

PeerRef PeerManagerImpl::GetPeerRef(NodeId id) const
Expand Down
4 changes: 4 additions & 0 deletions src/node/mempool_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP

if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) {
mempool_opts.max_datacarrier_bytes = argsman.GetIntArg("-datacarriersize", MAX_OP_RETURN_RELAY);
if (mempool_opts.max_datacarrier_bytes.value() > MAX_OUTPUT_DATA_SIZE) {
LogWarning("Limiting datacarriersize to %s", MAX_OUTPUT_DATA_SIZE);
mempool_opts.max_datacarrier_bytes = MAX_OUTPUT_DATA_SIZE;
}
} else {
mempool_opts.max_datacarrier_bytes = std::nullopt;
}
Expand Down
3 changes: 2 additions & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI
SCRIPT_VERIFY_CONST_SCRIPTCODE |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE |
REDUCED_DATA_MANDATORY_VERIFY_FLAGS};

/** For convenience, standard but not mandatory verify flags. */
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS};
Expand Down
6 changes: 6 additions & 0 deletions src/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ static std::string serviceFlagToStr(size_t bit)
case NODE_COMPACT_FILTERS: return "COMPACT_FILTERS";
case NODE_NETWORK_LIMITED: return "NETWORK_LIMITED";
case NODE_P2P_V2: return "P2P_V2";
case NODE_UTREEXO: return "UTREEXO";
case NODE_UTREEXO_ARCHIVE: return "UTREEXO_ARCHIVE";
case NODE_UTREEXO_TMP: return "UTREEXO_TMP?";
case NODE_REPLACE_BY_FEE: return "REPLACE_BY_FEE?";
case NODE_BIP444: return "BIP444?";
case NODE_MALICIOUS: return "MALICIOUS?";
// Not using default, so we get warned when a case is missing
}

Expand Down
9 changes: 9 additions & 0 deletions src/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,15 @@ enum ServiceFlags : uint64_t {
// collisions and other cases where nodes may be advertising a service they
// do not actually support. Other service bits should be allocated via the
// BIP process.

NODE_UTREEXO_TMP = (1 << 24),

NODE_REPLACE_BY_FEE = (1 << 26),

// NODE_BIP444 means the node enforces BIP 444 rules as applicable
NODE_BIP444 = (1 << 27),

NODE_MALICIOUS = (1 << 29),
Comment on lines +340 to +347

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its interesting utreexo stuff somehow ended up in here. Also NODE_MALICIOUS? Was that part of the bip444 implementation?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This repo is me cherry picking all UASF commits and just dropping them on v30 with llms doing auto merge conflicts.

here it is in the original proposed uasf code: https://github.com/UASF/bitcoin/blob/e5100daf50eea365f0930fbdb00a973cd0bc1371/src/protocol.cpp#L107

Copy link
Owner Author

@Rob1Ham Rob1Ham Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dathon told me it's a knots service bit that rejects libre relay

};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/psbt.h
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ struct PSBTOutput
s_tree >> depth;
s_tree >> leaf_ver;
s_tree >> script;
if (depth > TAPROOT_CONTROL_MAX_NODE_COUNT) {
if (depth > TAPROOT_CONTROL_MAX_NODE_COUNT_REDUCED) {
throw std::ios_base::failure("Output Taproot tree has as leaf greater than Taproot maximum depth");
}
if ((leaf_ver & ~TAPROOT_LEAF_MASK) != 0) {
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,9 @@ static void SoftForkDescPushBack(const CBlockIndex* blockindex, UniValue& softfo
// one below the activation height
rv.pushKV("active", DeploymentActiveAfter(blockindex, chainman, dep));
rv.pushKV("height", chainman.GetConsensus().DeploymentHeight(dep));
if (const auto height_end{chainman.GetConsensus().DeploymentHeightEnd(dep)}; height_end != std::numeric_limits<int>::max()) {
rv.pushKV("height_end", chainman.GetConsensus().DeploymentHeightEnd(dep));
}
softforks.pushKV(DeploymentName(dep), std::move(rv));
}

Expand Down Expand Up @@ -1422,6 +1425,7 @@ namespace {
const std::vector<RPCResult> RPCHelpForDeployment{
{RPCResult::Type::STR, "type", "one of \"buried\", \"bip9\""},
{RPCResult::Type::NUM, "height", /*optional=*/true, "height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
{RPCResult::Type::NUM, "height_end", /*optional=*/true, "height of the last block which the rules are or will be enforced (only for temporary deployments with a known end height"},
{RPCResult::Type::BOOL, "active", "true if the rules are enforced for the mempool and the next block"},
{RPCResult::Type::OBJ, "bip9", /*optional=*/true, "status of bip9 softforks (only for \"bip9\" type)",
{
Expand Down
Loading
Loading