Skip to content

Commit 8f7393a

Browse files
committed
Policy: Add acceptnonstddatacarrier option to reject non-standard datacarrier regardless of size
1 parent 3945ebf commit 8f7393a

File tree

9 files changed

+64
-38
lines changed

9 files changed

+64
-38
lines changed

src/init.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,10 @@ void SetupServerArgs(ArgsManager& argsman)
638638

639639
SetupChainParamsBaseOptions(argsman);
640640

641+
argsman.AddArg("-acceptnonstddatacarrier",
642+
strprintf("Relay and mine non-OP_RETURN datacarrier injection (default: %u)",
643+
DEFAULT_ACCEPT_NON_STD_DATACARRIER),
644+
ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
641645
argsman.AddArg("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (default: %u)", DEFAULT_ACCEPT_NON_STD_TXN), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
642646
argsman.AddArg("-incrementalrelayfee=<amt>", strprintf("Fee rate (in %s/kvB) used to define cost of relay, used for mempool limiting and replacement policy. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_INCREMENTAL_RELAY_FEE)), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::NODE_RELAY);
643647
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);

src/kernel/mempool_options.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ static constexpr RBFPolicy DEFAULT_MEMPOOL_RBF_POLICY{RBFPolicy::Always};
3030
static constexpr TRUCPolicy DEFAULT_MEMPOOL_TRUC_POLICY{TRUCPolicy::Enforce};
3131
/** Whether to fall back to legacy V1 serialization when writing mempool.dat */
3232
static constexpr bool DEFAULT_PERSIST_V1_DAT{false};
33+
/** Default for -acceptnonstddatacarrier */
34+
static constexpr bool DEFAULT_ACCEPT_NON_STD_DATACARRIER{true};
3335
/** Default for -acceptnonstdtxn */
3436
static constexpr bool DEFAULT_ACCEPT_NON_STD_TXN{false};
3537

@@ -61,6 +63,7 @@ struct MemPoolOptions {
6163
bool datacarrier_fullcount{DEFAULT_DATACARRIER_FULLCOUNT};
6264
bool permit_bare_pubkey{DEFAULT_PERMIT_BAREPUBKEY};
6365
bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
66+
bool accept_non_std_datacarrier{DEFAULT_ACCEPT_NON_STD_DATACARRIER};
6467
bool require_standard{true};
6568
RBFPolicy rbf_policy{DEFAULT_MEMPOOL_RBF_POLICY};
6669
TRUCPolicy truc_policy{DEFAULT_MEMPOOL_TRUC_POLICY};

src/node/mempool_args.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
9191
mempool_opts.max_datacarrier_bytes = std::nullopt;
9292
}
9393
mempool_opts.datacarrier_fullcount = argsman.GetBoolArg("-datacarrierfullcount", DEFAULT_DATACARRIER_FULLCOUNT);
94+
mempool_opts.accept_non_std_datacarrier = argsman.GetBoolArg("-acceptnonstddatacarrier", DEFAULT_ACCEPT_NON_STD_DATACARRIER);
9495

9596
mempool_opts.require_standard = !argsman.GetBoolArg("-acceptnonstdtxn", DEFAULT_ACCEPT_NON_STD_TXN);
9697

src/policy/policy.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <algorithm>
2424
#include <cstddef>
25+
#include <utility>
2526
#include <vector>
2627

2728
CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
@@ -420,17 +421,21 @@ std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prevScript
420421
return std::make_pair(CScript(), 0);
421422
}
422423

423-
size_t DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view)
424+
std::pair<size_t, size_t> DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view)
424425
{
425-
size_t ret{0};
426+
std::pair<size_t, size_t> ret{0, 0};
426427

427428
for (const CTxIn& txin : tx.vin) {
428429
const CTxOut &utxo = view.AccessCoin(txin.prevout).out;
429430
auto[script, consensus_weight_per_byte] = GetScriptForTransactionInput(utxo.scriptPubKey, txin);
430-
ret += script.DatacarrierBytes();
431+
const auto dcb = script.DatacarrierBytes();
432+
ret.first += dcb.first;
433+
ret.second += dcb.second;
431434
}
432435
for (const CTxOut& txout : tx.vout) {
433-
ret += txout.scriptPubKey.DatacarrierBytes();
436+
const auto dcb = txout.scriptPubKey.DatacarrierBytes();
437+
ret.first += dcb.first;
438+
ret.second += dcb.second;
434439
}
435440

436441
return ret;
@@ -446,12 +451,14 @@ int32_t CalculateExtraTxWeight(const CTransaction& tx, const CCoinsViewCache& vi
446451
const CTxOut &utxo = view.AccessCoin(txin.prevout).out;
447452
auto[script, consensus_weight_per_byte] = GetScriptForTransactionInput(utxo.scriptPubKey, txin);
448453
if (weight_per_data_byte > consensus_weight_per_byte) {
449-
mod_weight += script.DatacarrierBytes() * (weight_per_data_byte - consensus_weight_per_byte);
454+
const auto dcb = script.DatacarrierBytes();
455+
mod_weight += (dcb.first + dcb.second) * (weight_per_data_byte - consensus_weight_per_byte);
450456
}
451457
}
452458
if (weight_per_data_byte > WITNESS_SCALE_FACTOR) {
453459
for (const CTxOut& txout : tx.vout) {
454-
mod_weight += txout.scriptPubKey.DatacarrierBytes() * (weight_per_data_byte - WITNESS_SCALE_FACTOR);
460+
const auto dcb = txout.scriptPubKey.DatacarrierBytes();
461+
mod_weight += (dcb.first + dcb.second) * (weight_per_data_byte - WITNESS_SCALE_FACTOR);
455462
}
456463
}
457464
}

src/policy/policy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ static inline int64_t GetVirtualTransactionInputSize(const CTxIn& tx)
198198

199199
std::pair<CScript, unsigned int> GetScriptForTransactionInput(CScript prevScript, const CTxIn&);
200200

201-
size_t DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view);
201+
std::pair<size_t, size_t> DatacarrierBytes(const CTransaction& tx, const CCoinsViewCache& view);
202202

203203
int32_t CalculateExtraTxWeight(const CTransaction& tx, const CCoinsViewCache& view, const unsigned int weight_per_data_byte);
204204

src/script/script.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ bool CScript::HasValidOps() const
303303
return true;
304304
}
305305

306-
size_t CScript::DatacarrierBytes() const
306+
std::pair<size_t, size_t> CScript::DatacarrierBytes() const
307307
{
308308
size_t counted{0};
309309
opcodetype opcode, last_opcode{OP_INVALIDOPCODE};
@@ -314,17 +314,17 @@ size_t CScript::DatacarrierBytes() const
314314
opcode_it = it;
315315
if (!GetOp(it, opcode, push_data)) {
316316
// Invalid scripts are necessarily all data
317-
return size();
317+
return {0, size()};
318318
}
319319

320320
if (opcode == OP_IF || opcode == OP_NOTIF) {
321321
++inside_conditional;
322322
} else if (opcode == OP_ENDIF) {
323-
if (!inside_conditional) return size(); // invalid
323+
if (!inside_conditional) return {0, size()}; // invalid
324324
--inside_conditional;
325325
} else if (opcode == OP_RETURN && !inside_conditional) {
326326
// unconditional OP_RETURN is unspendable
327-
return size();
327+
return {size(), 0};
328328
}
329329

330330
// Match OP_FALSE OP_IF
@@ -350,7 +350,7 @@ size_t CScript::DatacarrierBytes() const
350350
counted += it - data_began;
351351
}
352352
}
353-
return counted;
353+
return {0, counted};
354354
}
355355

356356
bool GetScriptOp(CScriptBase::const_iterator& pc, CScriptBase::const_iterator end, opcodetype& opcodeRet, std::vector<unsigned char>* pvchRet)

src/script/script.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ class CScript : public CScriptBase
562562
return (size() > 0 && *begin() == OP_RETURN) || (size() > MAX_SCRIPT_SIZE);
563563
}
564564

565-
size_t DatacarrierBytes() const;
565+
std::pair<size_t, size_t> DatacarrierBytes() const;
566566

567567
void clear()
568568
{

src/test/script_tests.cpp

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,28 +1482,33 @@ BOOST_AUTO_TEST_CASE(script_HasValidOps)
14821482
BOOST_CHECK(!script.HasValidOps());
14831483
}
14841484

1485+
static std::string DatacarrierBytesStr(const CScript &script) {
1486+
auto dcb = script.DatacarrierBytes();
1487+
return strprintf("%s+%s", dcb.first, dcb.second);
1488+
}
1489+
14851490
BOOST_AUTO_TEST_CASE(script_DataCarrierBytes)
14861491
{
14871492
using zeros = std::vector<unsigned char>;
14881493

14891494
// empty script
1490-
BOOST_CHECK_EQUAL(0, (CScript()).DatacarrierBytes());
1495+
BOOST_CHECK_EQUAL("0+0", DatacarrierBytesStr(CScript()));
14911496
// series of pushes are not data
1492-
BOOST_CHECK_EQUAL(0, (CScript() << OP_0 << OP_0 << OP_0).DatacarrierBytes());
1497+
BOOST_CHECK_EQUAL("0+0", DatacarrierBytesStr(CScript() << OP_0 << OP_0 << OP_0));
14931498
// unspendable if first op is OP_RETURN, then length(1), zeros(11)
1494-
BOOST_CHECK_EQUAL(13, (CScript() << OP_RETURN << zeros(11)).DatacarrierBytes());
1499+
BOOST_CHECK_EQUAL("13+0", DatacarrierBytesStr(CScript() << OP_RETURN << zeros(11)));
14951500
// invalid script (no data following PUSHDATA) makes it all data
1496-
BOOST_CHECK_EQUAL(2, (CScript() << OP_0 << OP_PUSHDATA4).DatacarrierBytes());
1501+
BOOST_CHECK_EQUAL("0+2", DatacarrierBytesStr(CScript() << OP_0 << OP_PUSHDATA4));
14971502
// no data here
1498-
BOOST_CHECK_EQUAL(0, (CScript() << OP_TRUE << OP_IF << OP_ENDIF).DatacarrierBytes());
1503+
BOOST_CHECK_EQUAL("0+0", DatacarrierBytesStr(CScript() << OP_TRUE << OP_IF << OP_ENDIF));
14991504
// specific data pattern, entire script is data
1500-
BOOST_CHECK_EQUAL(4, (CScript() << OP_FALSE << OP_IF << OP_7 << OP_ENDIF).DatacarrierBytes());
1505+
BOOST_CHECK_EQUAL("0+4", DatacarrierBytesStr(CScript() << OP_FALSE << OP_IF << OP_7 << OP_ENDIF));
15011506
// consecutive data
1502-
BOOST_CHECK_EQUAL(6, (CScript() << OP_FALSE << OP_IF << OP_ENDIF << OP_FALSE << OP_IF << OP_ENDIF).DatacarrierBytes());
1507+
BOOST_CHECK_EQUAL("0+6", DatacarrierBytesStr(CScript() << OP_FALSE << OP_IF << OP_ENDIF << OP_FALSE << OP_IF << OP_ENDIF));
15031508
// nested data (all is data)
1504-
BOOST_CHECK_EQUAL(6, (CScript() << OP_FALSE << OP_IF << OP_TRUE << OP_IF << OP_ENDIF << OP_ENDIF).DatacarrierBytes());
1509+
BOOST_CHECK_EQUAL("0+6", DatacarrierBytesStr(CScript() << OP_FALSE << OP_IF << OP_TRUE << OP_IF << OP_ENDIF << OP_ENDIF));
15051510
// pushing then immediately dropping is data: length(1), zero(11), OP_DROP
1506-
BOOST_CHECK_EQUAL(13, (CScript() << zeros(11) << OP_DROP).DatacarrierBytes());
1511+
BOOST_CHECK_EQUAL("0+13", DatacarrierBytesStr(CScript() << zeros(11) << OP_DROP));
15071512
}
15081513

15091514
BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
@@ -1518,7 +1523,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15181523
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
15191524
BOOST_CHECK(ret_script == tx_in.scriptSig);
15201525
BOOST_CHECK_EQUAL(scale, WITNESS_SCALE_FACTOR);
1521-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1526+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
15221527
}
15231528
{ // P2PKH - no datacarrier bytes
15241529
CScript prev_script; // scriptPubKey
@@ -1529,7 +1534,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15291534
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
15301535
BOOST_CHECK(ret_script == tx_in.scriptSig);
15311536
BOOST_CHECK_EQUAL(scale, WITNESS_SCALE_FACTOR);
1532-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1537+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
15331538
}
15341539
{ // P2SH - no datacarrier bytes
15351540
CScript prev_script; // scriptPubKey
@@ -1542,7 +1547,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15421547
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
15431548
BOOST_CHECK(ret_script == redeem_script);
15441549
BOOST_CHECK_EQUAL(scale, WITNESS_SCALE_FACTOR);
1545-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1550+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
15461551
}
15471552
{ // P2SH - with datacarrier bytes
15481553
CScript prev_script; // scriptPubKey
@@ -1557,7 +1562,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15571562
BOOST_CHECK(ret_script == redeem_script);
15581563
BOOST_CHECK_EQUAL(scale, WITNESS_SCALE_FACTOR);
15591564
// OP_RETURN(1), length(1), zeros(27) = 29
1560-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 29);
1565+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "29+0");
15611566
}
15621567
{ // P2WPKH - no datacarrier bytes
15631568
CScript prev_script; // scriptPubKey
@@ -1573,7 +1578,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15731578
// should have no script at all since it's wrapped P2WPKH
15741579
BOOST_CHECK(ret_script == CScript());
15751580
BOOST_CHECK_EQUAL(scale, 0);
1576-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1581+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
15771582
}
15781583
{ // P2WSH - no datacarrier bytes
15791584
CScript prev_script; // scriptPubKey
@@ -1589,7 +1594,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
15891594
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
15901595
BOOST_CHECK(ret_script == redeem_script);
15911596
BOOST_CHECK_EQUAL(scale, 1);
1592-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1597+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
15931598
}
15941599
{ // P2WSH - some datacarrier bytes
15951600
CScript prev_script; // scriptPubKey
@@ -1606,7 +1611,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16061611
BOOST_CHECK(ret_script == redeem_script);
16071612
BOOST_CHECK_EQUAL(scale, 1);
16081613
// OP_FALSE(1), OP_IF(1), length(1), zeros(10), OP_ENDIF(1)
1609-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 14);
1614+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+14");
16101615
}
16111616
{ // P2SH-P2WPKH - no datacarrier bytes
16121617
CScript prev_script; // scriptPubKey
@@ -1621,7 +1626,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16211626
BOOST_CHECK(ret_script == CScript());
16221627
// data bytes in the witness get discounted (*1 instead of *4)
16231628
BOOST_CHECK_EQUAL(scale, 0);
1624-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1629+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
16251630
}
16261631
{ // P2SH-P2WSH - no datacarrier bytes
16271632
CScript prev_script; // scriptPubKey
@@ -1645,7 +1650,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16451650
BOOST_CHECK(ret_script == witness_redeem_script);
16461651
// data bytes in the witness get discounted (*1 instead of *4)
16471652
BOOST_CHECK_EQUAL(scale, 1);
1648-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1653+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
16491654
}
16501655
{ // P2SH-P2WSH - some datacarrier bytes
16511656
CScript prev_script; // scriptPubKey
@@ -1670,7 +1675,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16701675
// data bytes in the witness get discounted (*1 instead of *4)
16711676
BOOST_CHECK_EQUAL(scale, 1);
16721677
// OP_FALSE(1), OP_IF(1), length(1), zeros(10), OP_ENDIF(1) = 14
1673-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 14);
1678+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+14");
16741679
}
16751680
{ // P2TR keypath - no datacarrier bytes
16761681
CScript prev_script; // scriptPubKey
@@ -1682,7 +1687,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16821687
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
16831688
BOOST_CHECK(ret_script == CScript());
16841689
BOOST_CHECK_EQUAL(scale, 0);
1685-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1690+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
16861691
}
16871692
{ // P2TR keypath - annex but no script - no datacarrier bytes
16881693
CScript prev_script; // scriptPubKey
@@ -1696,7 +1701,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
16961701
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
16971702
BOOST_CHECK(ret_script == CScript());
16981703
BOOST_CHECK_EQUAL(scale, 0);
1699-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1704+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
17001705
}
17011706
{ // P2TR scriptpath - no datacarrier bytes
17021707
CScript prev_script; // scriptPubKey
@@ -1715,7 +1720,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
17151720
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
17161721
BOOST_CHECK(ret_script == script);
17171722
BOOST_CHECK_EQUAL(scale, 1);
1718-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 0);
1723+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "0+0");
17191724
}
17201725
{ // P2TR scriptpath - some datacarrier bytes
17211726
CScript prev_script; // scriptPubKey
@@ -1733,7 +1738,7 @@ BOOST_AUTO_TEST_CASE(script_GetScriptForTransactionInput)
17331738
auto [ret_script, scale] = GetScriptForTransactionInput(prev_script, tx_in);
17341739
BOOST_CHECK(ret_script == script);
17351740
BOOST_CHECK_EQUAL(scale, 1);
1736-
BOOST_CHECK_EQUAL(ret_script.DatacarrierBytes(), 3);
1741+
BOOST_CHECK_EQUAL(DatacarrierBytesStr(ret_script), "3+0");
17371742
}
17381743
}
17391744

src/validation.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,8 +968,14 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
968968
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, reason);
969969
}
970970

971-
if (m_pool.m_opts.datacarrier_fullcount && (!ignore_rejects.count("txn-datacarrier-exceeded")) && DatacarrierBytes(tx, m_view) > m_pool.m_opts.max_datacarrier_bytes.value_or(0)) {
972-
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "txn-datacarrier-exceeded");
971+
if (m_pool.m_opts.datacarrier_fullcount || !m_pool.m_opts.accept_non_std_datacarrier) {
972+
const auto dcb = DatacarrierBytes(tx, m_view);
973+
if (dcb.second > 0 && !(m_pool.m_opts.accept_non_std_datacarrier || ignore_rejects.count("txn-datacarrier-nonstandard"))) {
974+
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "txn-datacarrier-nonstandard");
975+
}
976+
if (m_pool.m_opts.datacarrier_fullcount && (!ignore_rejects.count("txn-datacarrier-exceeded")) && dcb.first + dcb.second > m_pool.m_opts.max_datacarrier_bytes.value_or(0)) {
977+
return state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "txn-datacarrier-exceeded");
978+
}
973979
}
974980

975981
// Check for non-standard witnesses.

0 commit comments

Comments
 (0)