Skip to content

Commit

Permalink
Merge pull request #2174 from gandrewstone/noSigopsPostFork2
Browse files Browse the repository at this point in the history
  • Loading branch information
gandrewstone committed Apr 16, 2020
2 parents e87fe36 + a529222 commit 2e0b0d0
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 24 deletions.
44 changes: 31 additions & 13 deletions src/miner.cpp
Expand Up @@ -317,7 +317,10 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript &sc
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
pblock->nNonce = 0;
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0], STANDARD_SCRIPT_VERIFY_FLAGS);
if (!may2020Enabled)
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0], STANDARD_SCRIPT_VERIFY_FLAGS);
else // coinbase May2020 Sigchecks is always 0 since no scripts executed in coinbase tx.
pblocktemplate->vTxSigOps[0] = 0;
}

CValidationState state;
Expand Down Expand Up @@ -364,6 +367,7 @@ bool BlockAssembler::TestPackageSigOps(uint64_t packageSize, unsigned int packag
maxSigOpsAllowed = GetMaxBlockSigOpsCount(nBlockSize + packageSize);
}

// Note that the may2020 rule should be > so this assembles a block with 1 less sigcheck than possible
if (nBlockSigOps + packageSigOps >= maxSigOpsAllowed)
return false;
return true;
Expand Down Expand Up @@ -404,24 +408,38 @@ bool BlockAssembler::IsIncrementallyGood(uint64_t nExtraSize, unsigned int nExtr
return false;
}

// Enforce the "old" sigops for <= 1MB blocks
if (nBlockSize + nExtraSize <= BLOCKSTREAM_CORE_MAX_BLOCK_SIZE)
if (!may2020Enabled)
{
// BU: be conservative about what is generated
if (nBlockSigOps + nExtraSigOps >= MAX_BLOCK_SIGOPS_PER_MB)
// Enforce the "old" sigops for <= 1MB blocks
if (nBlockSize + nExtraSize <= BLOCKSTREAM_CORE_MAX_BLOCK_SIZE)
{
// BU: so a block that is near the sigops limit might be shorter than it could be if
// the high sigops tx was backed out and other tx added.
if (nBlockSigOps > MAX_BLOCK_SIGOPS_PER_MB - 2)
blockFinished = true;
return false;
// BU: be conservative about what is generated
if (nBlockSigOps + nExtraSigOps >= MAX_BLOCK_SIGOPS_PER_MB)
{
// BU: so a block that is near the sigops limit might be shorter than it could be if
// the high sigops tx was backed out and other tx added.
if (nBlockSigOps > MAX_BLOCK_SIGOPS_PER_MB - 2)
blockFinished = true;
return false;
}
}
else
{
if (nBlockSigOps + nExtraSigOps > GetMaxBlockSigOpsCount(nBlockSize))
{
if (nBlockSigOps > GetMaxBlockSigOpsCount(nBlockSize) - 2)
// very close to the limit, so the block is finished. So a block that is near the sigops limit
// might be shorter than it could be if the high sigops tx was backed out and other tx added.
blockFinished = true;
return false;
}
}
}
else
else // may2020
{
if (nBlockSigOps + nExtraSigOps > GetMaxBlockSigOpsCount(nBlockSize))
if (nBlockSigOps + nExtraSigOps > maxSigOpsAllowed)
{
if (nBlockSigOps > GetMaxBlockSigOpsCount(nBlockSize) - 2)
if (nBlockSigOps > maxSigOpsAllowed - 2)
// very close to the limit, so the block is finished. So a block that is near the sigops limit
// might be shorter than it could be if the high sigops tx was backed out and other tx added.
blockFinished = true;
Expand Down
11 changes: 7 additions & 4 deletions src/policy/policy.cpp
Expand Up @@ -135,7 +135,7 @@ bool IsStandardTx(const CTransactionRef tx, std::string &reason)
return true;
}

bool AreInputsStandard(const CTransactionRef tx, const CCoinsViewCache &mapInputs)
bool AreInputsStandard(const CTransactionRef tx, const CCoinsViewCache &mapInputs, bool may2020Enabled)
{
if (tx->IsCoinBase())
return true; // Coinbases don't use vin normally
Expand Down Expand Up @@ -166,10 +166,13 @@ bool AreInputsStandard(const CTransactionRef tx, const CCoinsViewCache &mapInput
return false;
if (stack.empty())
return false;
CScript subscript(stack.back().begin(), stack.back().end());
if (subscript.GetSigOpCount(STANDARD_SCRIPT_VERIFY_FLAGS, true) > MAX_P2SH_SIGOPS)
if (!may2020Enabled)
{
return false;
CScript subscript(stack.back().begin(), stack.back().end());
if (subscript.GetSigOpCount(STANDARD_SCRIPT_VERIFY_FLAGS, true) > MAX_P2SH_SIGOPS)
{
return false;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/policy/policy.h
Expand Up @@ -72,6 +72,6 @@ bool IsStandardTx(const CTransactionRef tx, std::string &reason);
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
* @return True if all inputs (scriptSigs) use only standard transaction forms
*/
bool AreInputsStandard(const CTransactionRef tx, const CCoinsViewCache &mapInputs);
bool AreInputsStandard(const CTransactionRef tx, const CCoinsViewCache &mapInputs, bool isMay2020Enabled);

#endif // BITCOIN_POLICY_POLICY_H
20 changes: 19 additions & 1 deletion src/rpc/mining.cpp
Expand Up @@ -431,13 +431,15 @@ static UniValue MkFullMiningCandidateJson(std::set<std::string> setClientRules,
const int nMaxVersionPreVB,
const unsigned int nTransactionsUpdatedLast)
{
bool may2020Enabled = IsMay2020Enabled(Params().GetConsensus(), pindexPrev);
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
UniValue aCaps(UniValue::VARR);
aCaps.push_back("proposal");

UniValue transactions(UniValue::VARR);
map<uint256, int64_t> setTxIndex;
int i = 0;
int sigcheckTotal = 0;
for (const auto &it : pblock->vtx)
{
const CTransaction &tx = *it;
Expand All @@ -463,7 +465,15 @@ static UniValue MkFullMiningCandidateJson(std::set<std::string> setClientRules,

int index_in_template = i - 1;
entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]);
entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]);
if (!may2020Enabled)
entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]);
else
{
// sigops is deprecated and not part of this block's consensus so report 0
entry.pushKV("sigops", 0);
entry.pushKV("sigchecks", pblocktemplate->vTxSigOps[index_in_template]);
sigcheckTotal += pblocktemplate->vTxSigOps[index_in_template];
}

transactions.push_back(entry);
}
Expand Down Expand Up @@ -515,7 +525,15 @@ static UniValue MkFullMiningCandidateJson(std::set<std::string> setClientRules,
result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1);
result.pushKV("mutable", aMutable);
result.pushKV("noncerange", "00000000ffffffff");

// Deprecated after may 2020 but leave it in in case miners are using it in their code.
result.pushKV("sigoplimit", (int64_t)MAX_BLOCK_SIGOPS_PER_MB);
if (may2020Enabled)
{
result.pushKV("sigchecklimit", maxSigChecks.Value());
result.pushKV("sigchecktotal", sigcheckTotal);
}

result.pushKV("sizelimit", (int64_t)maxGeneratedBlock);
result.pushKV("curtime", pblock->GetBlockTime());
result.pushKV("bits", strprintf("%08x", pblock->nBits));
Expand Down
9 changes: 6 additions & 3 deletions src/test/script_P2SH_tests.cpp
Expand Up @@ -357,7 +357,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txTo.vin[3].scriptSig << OP_11 << OP_11 << vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
txTo.vin[4].scriptSig << vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());

BOOST_CHECK(::AreInputsStandard(MakeTransactionRef(CTransaction(txTo)), coins));
BOOST_CHECK(::AreInputsStandard(MakeTransactionRef(CTransaction(txTo)), coins, false));
BOOST_CHECK(::AreInputsStandard(MakeTransactionRef(CTransaction(txTo)), coins, true));
// 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
BOOST_CHECK_EQUAL(
GetP2SHSigOpCount(MakeTransactionRef(CTransaction(txTo)), coins, STANDARD_SCRIPT_VERIFY_FLAGS), 22U);
Expand All @@ -373,7 +374,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
txToNonStd1.vin[0].scriptSig << vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());

BOOST_CHECK(!::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd1)), coins));
BOOST_CHECK(!::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd1)), coins, false));
BOOST_CHECK(::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd1)), coins, true));
BOOST_CHECK_EQUAL(
GetP2SHSigOpCount(MakeTransactionRef(CTransaction(txToNonStd1)), coins, STANDARD_SCRIPT_VERIFY_FLAGS), 16U);
// Check that no sigops show up when P2SH is not activated.
Expand All @@ -388,7 +390,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
txToNonStd2.vin[0].scriptSig << vector<unsigned char>(twentySigops.begin(), twentySigops.end());

BOOST_CHECK(!::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd2)), coins));
BOOST_CHECK(!::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd2)), coins, false));
BOOST_CHECK(::AreInputsStandard(MakeTransactionRef(CTransaction(txToNonStd2)), coins, true));
BOOST_CHECK_EQUAL(
GetP2SHSigOpCount(MakeTransactionRef(CTransaction(txToNonStd2)), coins, STANDARD_SCRIPT_VERIFY_FLAGS), 20U);
// Check that no sigops show up when P2SH is not activated.
Expand Down
3 changes: 2 additions & 1 deletion src/test/transaction_tests.cpp
Expand Up @@ -308,7 +308,8 @@ BOOST_AUTO_TEST_CASE(test_Get)
t1.vout[0].nValue = 90 * CENT;
t1.vout[0].scriptPubKey << OP_1;

BOOST_CHECK(AreInputsStandard(MakeTransactionRef(CTransaction(t1)), coins));
BOOST_CHECK(AreInputsStandard(MakeTransactionRef(CTransaction(t1)), coins, false));
BOOST_CHECK(AreInputsStandard(MakeTransactionRef(CTransaction(t1)), coins, true));
BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50 + 21 + 22) * CENT);
}

Expand Down
2 changes: 1 addition & 1 deletion src/txadmission.cpp
Expand Up @@ -876,7 +876,7 @@ bool ParallelAcceptToMemoryPool(Snapshot &ss,
}

// Check for non-standard pay-to-script-hash in inputs
if (fRequireStandard && !AreInputsStandard(tx, view))
if (fRequireStandard && !AreInputsStandard(tx, view, may2020Enabled))
{
if (debugger)
{
Expand Down

0 comments on commit 2e0b0d0

Please sign in to comment.