Permalink
Browse files

Restore original bytespersigop as bytespersigopstrict

Plus a bugfix to accurately count sigops for this purpose
  • Loading branch information...
1 parent 3f65ba2 commit 6ae2e2dc6b6c2735dfd05b7947f125ca41ca971d @luke-jr luke-jr committed Aug 8, 2016
Showing with 37 additions and 1 deletion.
  1. +1 −0 src/init.cpp
  2. +32 −1 src/main.cpp
  3. +1 −0 src/policy/policy.cpp
  4. +3 −0 src/policy/policy.h
View
@@ -447,6 +447,7 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
strUsage += HelpMessageOpt("-acceptnonstdtxn", strprintf("Relay and mine \"non-standard\" transactions (%sdefault: %u)", "testnet/regtest only; ", !Params(CBaseChainParams::TESTNET).RequireStandard()));
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));
View
@@ -1046,6 +1046,34 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
return nSigOps;
}
+/** 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& tx, const CCoinsViewCache& inputs, int flags)
+{
+ if (tx.IsCoinBase())
+ return 0;
+
+ unsigned int nSigOps = 0;
+ BOOST_FOREACH(const CTxIn& 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 (unsigned int i = 0; i < tx.vin.size(); i++) {
+ const CTxOut &prevout = inputs.GetOutputFor(tx.vin[i]);
+ nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, i < tx.wit.vtxinwit.size() ? &tx.wit.vtxinwit[i].scriptWitness : NULL, flags);
+ }
+ }
+
+ return nSigOps;
+}
@@ -1296,7 +1324,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
// 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.
+ int64_t nAccurateSigOpsCost = GetAccurateTransactionSigOpCost(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS);
+ if ((nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) || (nBytesPerSigOpStrict && nAccurateSigOpsCost > nSize * WITNESS_SCALE_FACTOR / nBytesPerSigOpStrict))
return state.DoS(0, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops", false,
strprintf("%d", nSigOpsCost));
@@ -155,6 +155,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
}
unsigned int nBytesPerSigOp = DEFAULT_BYTES_PER_SIGOP;
+unsigned int nBytesPerSigOpStrict = DEFAULT_BYTES_PER_SIGOP_STRICT;
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
{
View
@@ -30,6 +30,8 @@ static const unsigned int MAX_STANDARD_TX_SIGOPS_COST = MAX_BLOCK_SIGOPS_COST/5;
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE = 300;
/** 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;
/**
* Standard script verification flags that standard transactions will comply
* with. However scripts violating these flags may still be present in valid
@@ -69,6 +71,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason, const bool witnes
bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs);
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);

0 comments on commit 6ae2e2d

Please sign in to comment.