Skip to content

Commit 94c50ba

Browse files
committed
Add annex data carrier option behind -annexcarrier option
Allow 0 to 126 byte pushes in annex of the format: 0x50 <1 byte data len> <len bytes>
1 parent 6eab309 commit 94c50ba

File tree

14 files changed

+70
-12
lines changed

14 files changed

+70
-12
lines changed

src/init.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ void SetupServerArgs(ArgsManager& argsman)
567567
argsman.AddArg("-mempoolfullrbf", strprintf("Accept transaction replace-by-fee without requiring replaceability signaling (default: %u)", DEFAULT_MEMPOOL_FULL_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
568568
argsman.AddArg("-permitbaremultisig", strprintf("Relay non-P2SH multisig (default: %u)", DEFAULT_PERMIT_BAREMULTISIG), ArgsManager::ALLOW_ANY,
569569
OptionsCategory::NODE_RELAY);
570+
argsman.AddArg("-annexcarrier", strprintf("Relay and mine transactions with annex data, up to %u bytes of payload (default: %u)", MAX_ANNEX_DATA, DEFAULT_ACCEPT_ANNEXDATA), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
570571
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
571572
CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
572573
argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);

src/kernel/mempool_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct MemPoolOptions {
5050
* If nullopt, any size is nonstandard.
5151
*/
5252
std::optional<unsigned> max_datacarrier_bytes{DEFAULT_ACCEPT_DATACARRIER ? std::optional{MAX_OP_RETURN_RELAY} : std::nullopt};
53+
bool annex_datacarrier = DEFAULT_ACCEPT_ANNEXDATA;
5354
bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
5455
bool require_standard{true};
5556
bool full_rbf{DEFAULT_MEMPOOL_FULL_RBF};

src/node/mempool_args.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& argsman, con
8787
mempool_opts.max_datacarrier_bytes = std::nullopt;
8888
}
8989

90+
mempool_opts.annex_datacarrier = argsman.GetBoolArg("-annexcarrier", DEFAULT_ACCEPT_ANNEXDATA);
91+
9092
mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
9193
if (!chainparams.IsTestChain() && !mempool_opts.require_standard) {
9294
return strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.NetworkIDString());

src/policy/policy.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
213213
return true;
214214
}
215215

216-
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
216+
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, bool allow_annex_data)
217217
{
218+
bool annex_data_already_found = false;
218219
if (tx.IsCoinBase())
219220
return true; // Coinbases are skipped
220221

@@ -271,8 +272,14 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
271272
// Taproot spend (non-P2SH-wrapped, version 1, witness program size 32; see BIP 341)
272273
Span stack{tx.vin[i].scriptWitness.stack};
273274
if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
274-
// Annexes are nonstandard as long as no semantics are defined for them.
275-
return false;
275+
const std::vector<unsigned char> &annex = stack.back();
276+
// For now allow 0 to MAX_ANNEX_DATA bytes push to allow drop-in replacement via BIP PR#1381
277+
// But only one annex per transaction to avoid witness stuffing.
278+
if (!allow_annex_data || annex_data_already_found ||
279+
annex.size() < 2 || annex.size() > 1 + 1 + MAX_ANNEX_DATA || (size_t)annex[1] != annex.size() - 2) {
280+
return false;
281+
}
282+
annex_data_already_found = true;
276283
}
277284
if (stack.size() >= 2) {
278285
// Script path spend (2 or more stack elements after removing optional annex)

src/policy/policy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
132132
* 3600bytes witnessScript size, 80bytes per witness stack element, 100 witness stack elements
133133
* These limits are adequate for multisignatures up to n-of-100 using OP_CHECKSIG, OP_ADD, and OP_EQUAL.
134134
*
135-
* Also enforce a maximum stack item size limit and no annexes for tapscript spends.
135+
* Also enforce a maximum stack item size limit and limited annexes for tapscript spends.
136136
*/
137-
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
137+
bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs, bool allow_annex_data);
138138

139139
/** Compute the virtual transaction size (weight reinterpreted as bytes). */
140140
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop);

src/script/standard.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <variant>
1818

1919
static const bool DEFAULT_ACCEPT_DATACARRIER = true;
20+
static const bool DEFAULT_ACCEPT_ANNEXDATA = true;
2021

2122
class CKeyID;
2223
class CScript;
@@ -38,6 +39,17 @@ class CScriptID : public BaseHash<uint160>
3839
*/
3940
static const unsigned int MAX_OP_RETURN_RELAY = 83;
4041

42+
/**
43+
* Allows up to one annex data to be embedded in a transaction, counting towards the
44+
* same data carrier limit as OP_RETURN values
45+
*/
46+
extern bool accept_annex_data;
47+
48+
/**
49+
* Static maximum of annex data per transaction
50+
*/
51+
static const unsigned int MAX_ANNEX_DATA = 126;
52+
4153
/**
4254
* Mandatory script verification flags that all new blocks must comply with for
4355
* them to be valid. (but old blocks may not comply with) Currently just P2SH,

src/test/fuzz/coins_view.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ FUZZ_TARGET_INIT(coins_view, initialize_coins_view)
265265
(void)GetTransactionSigOpCost(transaction, coins_view_cache, flags);
266266
},
267267
[&] {
268-
(void)IsWitnessStandard(CTransaction{random_mutable_transaction}, coins_view_cache);
268+
(void)IsWitnessStandard(CTransaction{random_mutable_transaction}, coins_view_cache, /* allow_annex_data= */ true);
269269
});
270270
}
271271
}

src/test/fuzz/transaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ FUZZ_TARGET_INIT(transaction, initialize_transaction)
9898
CCoinsView coins_view;
9999
const CCoinsViewCache coins_view_cache(&coins_view);
100100
(void)AreInputsStandard(tx, coins_view_cache);
101-
(void)IsWitnessStandard(tx, coins_view_cache);
101+
(void)IsWitnessStandard(tx, coins_view_cache, /* allow_annex_data= */true);
102102

103103
UniValue u(UniValue::VOBJ);
104104
TxToUniv(tx, /*block_hash=*/uint256::ZERO, /*entry=*/u);

src/txmempool.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ CTxMemPool::CTxMemPool(const Options& opts)
433433
m_dust_relay_feerate{opts.dust_relay_feerate},
434434
m_permit_bare_multisig{opts.permit_bare_multisig},
435435
m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
436+
m_annex_datacarrier{opts.annex_datacarrier},
436437
m_require_standard{opts.require_standard},
437438
m_full_rbf{opts.full_rbf},
438439
m_limits{opts.limits}

src/txmempool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ class CTxMemPool
573573
const CFeeRate m_dust_relay_feerate;
574574
const bool m_permit_bare_multisig;
575575
const std::optional<unsigned> m_max_datacarrier_bytes;
576+
const bool m_annex_datacarrier;
576577
const bool m_require_standard;
577578
const bool m_full_rbf;
578579

0 commit comments

Comments
 (0)