Skip to content

Commit

Permalink
Restore original bytespersigop as bytespersigopstrict
Browse files Browse the repository at this point in the history
Plus a bugfix to accurately count sigops for this purpose
  • Loading branch information
luke-jr committed Mar 19, 2018
1 parent e44861a commit 1fe7029
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/init.cpp
Expand Up @@ -473,6 +473,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-dustrelayfee=<amt>", strprintf("Fee rate (in %s/kB) used to defined 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)));
}
strUsage += HelpMessageOpt("-bytespersigop", strprintf(_("Equivalent bytes per sigop in transactions for relay and mining (default: %u)"), DEFAULT_BYTES_PER_SIGOP));
strUsage += HelpMessageOpt("-bytespersigopstrict", strprintf(_("Minimum bytes per sigop in transactions we relay and mine (default: %u)"), DEFAULT_BYTES_PER_SIGOP_STRICT));
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), DEFAULT_ACCEPT_DATACARRIER));
strUsage += HelpMessageOpt("-datacarriersize", strprintf(_("Maximum size of data in data carrier transactions we relay and mine (default: %u)"), MAX_OP_RETURN_RELAY));
strUsage += HelpMessageOpt("-mempoolreplacement", strprintf(_("Enable transaction replacement in the memory pool (default: %u)"), DEFAULT_ENABLE_REPLACEMENT));
Expand Down
31 changes: 31 additions & 0 deletions src/policy/policy.cpp
Expand Up @@ -7,6 +7,7 @@

#include <policy/policy.h>

#include <consensus/tx_verify.h>
#include <consensus/validation.h>
#include <validation.h>
#include <coins.h>
Expand Down Expand Up @@ -291,6 +292,7 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs,
CFeeRate incrementalRelayFee = CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE);
CFeeRate dustRelayFee = CFeeRate(DUST_RELAY_TX_FEE);
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
unsigned int nBytesPerSigOpStrict = DEFAULT_BYTES_PER_SIGOP_STRICT;

int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
{
Expand All @@ -301,3 +303,32 @@ int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost)
{
return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost);
}

int64_t GetAccurateTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
{
if (tx.IsCoinBase()) {
return 0;
}

unsigned int nSigOps = 0;
for (const auto& txin : tx.vin) {
nSigOps += txin.scriptSig.GetSigOpCount(false);
}

if (flags & SCRIPT_VERIFY_P2SH) {
nSigOps += GetP2SHSigOpCount(tx, inputs);
}

nSigOps *= WITNESS_SCALE_FACTOR;

if (flags & SCRIPT_VERIFY_WITNESS) {
for (const auto& txin : tx.vin) {
const Coin& coin = inputs.AccessCoin(txin.prevout);
assert(!coin.IsSpent());
const CTxOut &prevout = coin.out;
nSigOps += CountWitnessSigOps(txin.scriptSig, prevout.scriptPubKey, &txin.scriptWitness, flags);
}
}

return nSigOps;
}
8 changes: 8 additions & 0 deletions src/policy/policy.h
Expand Up @@ -33,6 +33,8 @@ static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE = 1000;
/** Default for -bytespersigop */
static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20;
/** Default for -bytespersigopstrict */
static const unsigned int DEFAULT_BYTES_PER_SIGOP_STRICT = 20;
/** The maximum number of witness stack items in a standard P2WSH script */
static const unsigned int MAX_STANDARD_P2WSH_STACK_ITEMS = 100;
/** The maximum size of each witness stack item in a standard P2WSH script */
Expand Down Expand Up @@ -108,9 +110,15 @@ bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs,
extern CFeeRate incrementalRelayFee;
extern CFeeRate dustRelayFee;
extern unsigned int nBytesPerSigOp;
extern unsigned int nBytesPerSigOpStrict;

/** Compute the virtual transaction size (weight reinterpreted as bytes). */
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost);
int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost = 0);

/** Compute accurate total signature operation cost of a transaction.
* Not consensus-critical, since legacy sigops counting is always used in the protocol.
*/
int64_t GetAccurateTransactionSigOpCost(const CTransaction&, const CCoinsViewCache& inputs, int flags);

#endif // BITCOIN_POLICY_POLICY_H
5 changes: 4 additions & 1 deletion src/validation.cpp
Expand Up @@ -738,9 +738,12 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
// itself can contain sigops MAX_STANDARD_TX_SIGOPS is less than
// MAX_BLOCK_SIGOPS; we still consider this an invalid rather than
// merely non-standard transaction.
if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
// To avoid rejecting low-sigop bare-multisig transactions, the sigops
// are counted a second time more accurately.
if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOpStrict && GetAccurateTransactionSigOpCost(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS) > nSize * WITNESS_SCALE_FACTOR / nBytesPerSigOpStrict)) {
MaybeRejectDbg(REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false,
strprintf("%d", nSigOpsCost));
}

poolMinFeeRate = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
CAmount mempoolRejectFee = poolMinFeeRate.GetFee(nSize);
Expand Down

0 comments on commit 1fe7029

Please sign in to comment.