Skip to content

Commit

Permalink
Add a -permitbarepubkey option
Browse files Browse the repository at this point in the history
  • Loading branch information
vostrnad committed May 1, 2024
1 parent d73245a commit ffc6c0b
Show file tree
Hide file tree
Showing 11 changed files with 24 additions and 10 deletions.
2 changes: 2 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ void SetupServerArgs(ArgsManager& argsman)
MAX_OP_RETURN_RELAY),
ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
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);
argsman.AddArg("-permitbarepubkey", strprintf("Relay legacy pubkey outputs (default: %u)", DEFAULT_PERMIT_BAREPUBKEY), 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,
OptionsCategory::NODE_RELAY);
argsman.AddArg("-minrelaytxfee=<amt>", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)",
Expand Down
1 change: 1 addition & 0 deletions src/kernel/mempool_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ struct MemPoolOptions {
* If nullopt, any size is nonstandard.
*/
std::optional<unsigned> max_datacarrier_bytes{DEFAULT_ACCEPT_DATACARRIER ? std::optional{MAX_OP_RETURN_RELAY} : std::nullopt};
bool permit_bare_pubkey{DEFAULT_PERMIT_BAREPUBKEY};
bool permit_bare_multisig{DEFAULT_PERMIT_BAREMULTISIG};
bool require_standard{true};
bool full_rbf{DEFAULT_MEMPOOL_FULL_RBF};
Expand Down
2 changes: 2 additions & 0 deletions src/node/mempool_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ util::Result<void> ApplyArgsManOptions(const ArgsManager& argsman, const CChainP
}
}

mempool_opts.permit_bare_pubkey = argsman.GetBoolArg("-permitbarepubkey", DEFAULT_PERMIT_BAREPUBKEY);

mempool_opts.permit_bare_multisig = argsman.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);

if (argsman.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER)) {
Expand Down
6 changes: 5 additions & 1 deletion src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_
return true;
}

bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason)
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_pubkey, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason)
{
if (tx.nVersion > TX_MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
Expand Down Expand Up @@ -138,6 +138,10 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat

if (whichType == TxoutType::NULL_DATA)
nDataOut++;
else if ((whichType == TxoutType::PUBKEY) && (!permit_bare_pubkey)) {
reason = "bare-pubkey";
return false;
}
else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
reason = "bare-multisig";
return false;
Expand Down
4 changes: 3 additions & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/
static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000};
/** Default for -bytespersigop */
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP{20};
/** Default for -permitbarepubkey */
static constexpr bool DEFAULT_PERMIT_BAREPUBKEY{true};
/** Default for -permitbaremultisig */
static constexpr bool DEFAULT_PERMIT_BAREMULTISIG{true};
/** The maximum number of witness stack items in a standard P2WSH script */
Expand Down Expand Up @@ -137,7 +139,7 @@ static constexpr decltype(CTransaction::nVersion) TX_MAX_STANDARD_VERSION{2};
* Check for standard transaction types
* @return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason);
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_pubkey, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason);
/**
* Check for standard transaction types
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
Expand Down
4 changes: 2 additions & 2 deletions src/test/fuzz/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ FUZZ_TARGET(transaction, .init = initialize_transaction)

const CFeeRate dust_relay_fee{DUST_RELAY_TX_FEE};
std::string reason;
const bool is_standard_with_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ true, dust_relay_fee, reason);
const bool is_standard_without_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_multisig= */ false, dust_relay_fee, reason);
const bool is_standard_with_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_pubkey= */ true, /* permit_bare_multisig= */ true, dust_relay_fee, reason);
const bool is_standard_without_permit_bare_multisig = IsStandardTx(tx, std::nullopt, /* permit_bare_pubkey= */ true, /* permit_bare_multisig= */ false, dust_relay_fee, reason);
if (is_standard_without_permit_bare_multisig) {
assert(is_standard_with_permit_bare_multisig);
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/script_p2sh_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
// Helpers:
static bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, std::string& reason)
{
return IsStandardTx(tx, std::nullopt, permit_bare_multisig, CFeeRate{DUST_RELAY_TX_FEE}, reason);
return IsStandardTx(tx, std::nullopt, /*permit_bare_pubkey=*/true, permit_bare_multisig, CFeeRate{DUST_RELAY_TX_FEE}, reason);
}

static bool IsStandardTx(const CTransaction& tx, std::string& reason)
{
return IsStandardTx(tx, std::nullopt, /*permit_bare_multisig=*/true, CFeeRate{DUST_RELAY_TX_FEE}, reason) &&
IsStandardTx(tx, std::nullopt, /*permit_bare_multisig=*/false, CFeeRate{DUST_RELAY_TX_FEE}, reason);
return IsStandardTx(tx, std::nullopt, /*permit_bare_pubkey=*/true, /*permit_bare_multisig=*/true, CFeeRate{DUST_RELAY_TX_FEE}, reason) &&
IsStandardTx(tx, std::nullopt, /*permit_bare_pubkey=*/true, /*permit_bare_multisig=*/false, CFeeRate{DUST_RELAY_TX_FEE}, reason);
}

static std::vector<unsigned char> Serialize(const CScript& s)
Expand Down
5 changes: 3 additions & 2 deletions src/test/transaction_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
typedef std::vector<unsigned char> valtype;

static CFeeRate g_dust{DUST_RELAY_TX_FEE};
static bool g_bare_pubkey{DEFAULT_PERMIT_BAREPUBKEY};
static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};

static std::map<std::string, unsigned int> mapFlagNames = {
Expand Down Expand Up @@ -758,12 +759,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)

constexpr auto CheckIsStandard = [](const auto& t) {
std::string reason;
BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi, g_dust, reason));
BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_pubkey, g_bare_multi, g_dust, reason));
BOOST_CHECK(reason.empty());
};
constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in) {
std::string reason;
BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi, g_dust, reason));
BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_pubkey, g_bare_multi, g_dust, reason));
BOOST_CHECK_EQUAL(reason_in, reason);
};

Expand Down
1 change: 1 addition & 0 deletions src/txmempool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ CTxMemPool::CTxMemPool(const Options& opts)
m_incremental_relay_feerate{opts.incremental_relay_feerate},
m_min_relay_feerate{opts.min_relay_feerate},
m_dust_relay_feerate{opts.dust_relay_feerate},
m_permit_bare_pubkey{opts.permit_bare_pubkey},
m_permit_bare_multisig{opts.permit_bare_multisig},
m_max_datacarrier_bytes{opts.max_datacarrier_bytes},
m_require_standard{opts.require_standard},
Expand Down
1 change: 1 addition & 0 deletions src/txmempool.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ class CTxMemPool
const CFeeRate m_incremental_relay_feerate;
const CFeeRate m_min_relay_feerate;
const CFeeRate m_dust_relay_feerate;
const bool m_permit_bare_pubkey;
const bool m_permit_bare_multisig;
const std::optional<unsigned> m_max_datacarrier_bytes;
const bool m_require_standard;
Expand Down
2 changes: 1 addition & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)

// Rather not work on nonstandard transactions (unless -testnet/-regtest)
std::string reason;
if (m_pool.m_require_standard && !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason)) {
if (m_pool.m_require_standard && !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_pubkey, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason)) {
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
}

Expand Down

0 comments on commit ffc6c0b

Please sign in to comment.