Skip to content

Commit 9d18c6e

Browse files
committed
Merge bytespersigopstrict-28+knots
2 parents 22193cc + cbecc46 commit 9d18c6e

File tree

5 files changed

+42
-1
lines changed

5 files changed

+42
-1
lines changed

src/init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ void SetupServerArgs(ArgsManager& argsman)
674674
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);
675675
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);
676676
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);
677+
argsman.AddArg("-bytespersigopstrict", strprintf("Minimum bytes per sigop in transactions we relay and mine (default: %u)", DEFAULT_BYTES_PER_SIGOP_STRICT), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
677678
argsman.AddArg("-datacarrier", strprintf("Relay and mine data carrier transactions (default: %u)", DEFAULT_ACCEPT_DATACARRIER), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY);
678679
argsman.AddArg("-datacarriersize",
679680
strprintf("Relay and mine transactions whose data-carrying raw scriptPubKey "
@@ -1082,6 +1083,7 @@ bool AppInitParameterInteraction(const ArgsManager& args)
10821083
}
10831084

10841085
nBytesPerSigOp = args.GetIntArg("-bytespersigop", nBytesPerSigOp);
1086+
nBytesPerSigOpStrict = args.GetIntArg("-bytespersigopstrict", nBytesPerSigOpStrict);
10851087

10861088
if (!g_wallet_init_interface.ParameterInteraction()) return false;
10871089

src/policy/policy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ static constexpr unsigned int MAX_STANDARD_TX_SIGOPS_COST{MAX_BLOCK_SIGOPS_COST/
4545
static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE{1000};
4646
/** Default for -bytespersigop */
4747
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP{20};
48+
/** Default for -bytespersigopstrict */
49+
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP_STRICT{20};
4850
/** Default for -permitbarepubkey */
4951
static constexpr bool DEFAULT_PERMIT_BAREPUBKEY{true};
5052
/** Default for -permitbaremultisig */

src/policy/settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
#include <policy/policy.h>
99

1010
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
11+
unsigned int nBytesPerSigOpStrict = DEFAULT_BYTES_PER_SIGOP_STRICT;

src/policy/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
#define BITCOIN_POLICY_SETTINGS_H
88

99
extern unsigned int nBytesPerSigOp;
10+
extern unsigned int nBytesPerSigOpStrict;
1011

1112
#endif // BITCOIN_POLICY_SETTINGS_H

src/validation.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,38 @@ bool CheckSequenceLocksAtTip(CBlockIndex* tip,
262262
// Returns the script flags which should be checked for a given block
263263
static unsigned int GetBlockScriptFlags(const CBlockIndex& block_index, const ChainstateManager& chainman);
264264

265+
/** Compute accurate total signature operation cost of a transaction.
266+
* Not consensus-critical, since legacy sigops counting is always used in the protocol.
267+
*/
268+
int64_t GetAccurateTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
269+
{
270+
if (tx.IsCoinBase()) {
271+
return 0;
272+
}
273+
274+
unsigned int nSigOps = 0;
275+
for (const auto& txin : tx.vin) {
276+
nSigOps += txin.scriptSig.GetSigOpCount(false);
277+
}
278+
279+
if (flags & SCRIPT_VERIFY_P2SH) {
280+
nSigOps += GetP2SHSigOpCount(tx, inputs);
281+
}
282+
283+
nSigOps *= WITNESS_SCALE_FACTOR;
284+
285+
if (flags & SCRIPT_VERIFY_WITNESS) {
286+
for (const auto& txin : tx.vin) {
287+
const Coin& coin = inputs.AccessCoin(txin.prevout);
288+
assert(!coin.IsSpent());
289+
const CTxOut &prevout = coin.out;
290+
nSigOps += CountWitnessSigOps(txin.scriptSig, prevout.scriptPubKey, &txin.scriptWitness, flags);
291+
}
292+
}
293+
294+
return nSigOps;
295+
}
296+
265297
void LimitMempoolSize(CTxMemPool& pool, CCoinsViewCache& coins_cache)
266298
EXCLUSIVE_LOCKS_REQUIRED(::cs_main, pool.cs)
267299
{
@@ -970,9 +1002,12 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
9701002
fSpendsCoinbase, nSigOpsCost, lock_points.value()));
9711003
ws.m_vsize = entry->GetTxSize();
9721004

973-
if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
1005+
// To avoid rejecting low-sigop bare-multisig transactions, the sigops
1006+
// are counted a second time more accurately.
1007+
if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOpStrict && GetAccurateTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS) > ws.m_vsize * WITNESS_SCALE_FACTOR / nBytesPerSigOpStrict)) {
9741008
MaybeRejectDbg(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
9751009
strprintf("%d", nSigOpsCost));
1010+
}
9761011

9771012
// No individual transactions are allowed below the min relay feerate except from disconnected blocks.
9781013
// This requirement, unlike CheckFeeRate, cannot be bypassed using m_package_feerates because,

0 commit comments

Comments
 (0)