Changeset View
Changeset View
Standalone View
Standalone View
src/test/sigopcount_tests.cpp
Show First 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | void BuildTxs(CMutableTransaction &spendingTx, CCoinsViewCache &coins, | ||||
spendingTx.vin.resize(1); | spendingTx.vin.resize(1); | ||||
spendingTx.vin[0].prevout.hash = creationTx.GetId(); | spendingTx.vin[0].prevout.hash = creationTx.GetId(); | ||||
spendingTx.vin[0].prevout.n = 0; | spendingTx.vin[0].prevout.n = 0; | ||||
spendingTx.vin[0].scriptSig = scriptSig; | spendingTx.vin[0].scriptSig = scriptSig; | ||||
spendingTx.vout.resize(1); | spendingTx.vout.resize(1); | ||||
spendingTx.vout[0].nValue = Amount(1); | spendingTx.vout[0].nValue = Amount(1); | ||||
spendingTx.vout[0].scriptPubKey = CScript(); | spendingTx.vout[0].scriptPubKey = CScript(); | ||||
AddCoins(coins, creationTx, 0); | AddCoins(coins, CTransaction(creationTx), 0); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(GetTxSigOpCost) { | BOOST_AUTO_TEST_CASE(GetTxSigOpCost) { | ||||
// Transaction creates outputs | // Transaction creates outputs | ||||
CMutableTransaction creationTx; | CMutableTransaction creationTx; | ||||
// Transaction that spends outputs and whose sig op cost is going to be | // Transaction that spends outputs and whose sig op cost is going to be | ||||
// tested | // tested | ||||
CMutableTransaction spendingTx; | CMutableTransaction spendingTx; | ||||
Show All 12 Lines | BOOST_AUTO_TEST_CASE(GetTxSigOpCost) { | ||||
{ | { | ||||
CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey) | CScript scriptPubKey = CScript() << 1 << ToByteVector(pubkey) | ||||
<< ToByteVector(pubkey) << 2 | << ToByteVector(pubkey) << 2 | ||||
<< OP_CHECKMULTISIGVERIFY; | << OP_CHECKMULTISIGVERIFY; | ||||
// Do not use a valid signature to avoid using wallet operations. | // Do not use a valid signature to avoid using wallet operations. | ||||
CScript scriptSig = CScript() << OP_0 << OP_0; | CScript scriptSig = CScript() << OP_0 << OP_0; | ||||
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig); | BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig); | ||||
// Legacy counting only includes signature operations in scriptSigs and | // Legacy counting only includes signature operations in scriptSigs and | ||||
// scriptPubKeys of a transaction and does not take the actual executed | // scriptPubKeys of a transaction and does not take the actual executed | ||||
// sig operations into account. spendingTx in itself does not contain a | // sig operations into account. spendingTx in itself does not contain a | ||||
// signature operation. | // signature operation. | ||||
assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins, | assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins, | ||||
flags) == 0); | flags) == 0); | ||||
// creationTx contains two signature operations in its scriptPubKey, but | // creationTx contains two signature operations in its scriptPubKey, but | ||||
// legacy counting is not accurate. | // legacy counting is not accurate. | ||||
assert(GetTransactionSigOpCount(CTransaction(creationTx), coins, | assert(GetTransactionSigOpCount(CTransaction(creationTx), coins, | ||||
flags) == MAX_PUBKEYS_PER_MULTISIG); | flags) == MAX_PUBKEYS_PER_MULTISIG); | ||||
// Sanity check: script verification fails because of an invalid | // Sanity check: script verification fails because of an invalid | ||||
// signature. | // signature. | ||||
assert(VerifyWithFlag(creationTx, spendingTx, flags) == | assert(VerifyWithFlag(CTransaction(creationTx), spendingTx, flags) == | ||||
SCRIPT_ERR_CHECKMULTISIGVERIFY); | SCRIPT_ERR_CHECKMULTISIGVERIFY); | ||||
} | } | ||||
// Multisig nested in P2SH | // Multisig nested in P2SH | ||||
{ | { | ||||
CScript redeemScript = CScript() << 1 << ToByteVector(pubkey) | CScript redeemScript = CScript() << 1 << ToByteVector(pubkey) | ||||
<< ToByteVector(pubkey) << 2 | << ToByteVector(pubkey) << 2 | ||||
<< OP_CHECKMULTISIGVERIFY; | << OP_CHECKMULTISIGVERIFY; | ||||
CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); | CScript scriptPubKey = GetScriptForDestination(CScriptID(redeemScript)); | ||||
CScript scriptSig = CScript() | CScript scriptSig = CScript() | ||||
<< OP_0 << OP_0 << ToByteVector(redeemScript); | << OP_0 << OP_0 << ToByteVector(redeemScript); | ||||
BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig); | BuildTxs(spendingTx, coins, creationTx, scriptPubKey, scriptSig); | ||||
assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins, | assert(GetTransactionSigOpCount(CTransaction(spendingTx), coins, | ||||
flags) == 2); | flags) == 2); | ||||
assert(VerifyWithFlag(creationTx, spendingTx, flags) == | assert(VerifyWithFlag(CTransaction(creationTx), spendingTx, flags) == | ||||
SCRIPT_ERR_CHECKMULTISIGVERIFY); | SCRIPT_ERR_CHECKMULTISIGVERIFY); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(test_consensus_sigops_limit) { | BOOST_AUTO_TEST_CASE(test_consensus_sigops_limit) { | ||||
BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1), MAX_BLOCK_SIGOPS_PER_MB); | BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1), MAX_BLOCK_SIGOPS_PER_MB); | ||||
BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(123456), MAX_BLOCK_SIGOPS_PER_MB); | BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(123456), MAX_BLOCK_SIGOPS_PER_MB); | ||||
BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1000000), MAX_BLOCK_SIGOPS_PER_MB); | BOOST_CHECK_EQUAL(GetMaxBlockSigOpsCount(1000000), MAX_BLOCK_SIGOPS_PER_MB); | ||||
Show All 20 Lines | BOOST_AUTO_TEST_CASE(test_max_sigops_per_tx) { | ||||
tx.vin[0].prevout.n = 0; | tx.vin[0].prevout.n = 0; | ||||
tx.vin[0].scriptSig = CScript(); | tx.vin[0].scriptSig = CScript(); | ||||
tx.vout.resize(1); | tx.vout.resize(1); | ||||
tx.vout[0].nValue = Amount(1); | tx.vout[0].nValue = Amount(1); | ||||
tx.vout[0].scriptPubKey = CScript(); | tx.vout[0].scriptPubKey = CScript(); | ||||
{ | { | ||||
CValidationState state; | CValidationState state; | ||||
BOOST_CHECK(CheckRegularTransaction(tx, state, false)); | BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state, false)); | ||||
} | } | ||||
// Get just before the limit. | // Get just before the limit. | ||||
for (size_t i = 0; i < MAX_TX_SIGOPS_COUNT; i++) { | for (size_t i = 0; i < MAX_TX_SIGOPS_COUNT; i++) { | ||||
tx.vout[0].scriptPubKey << OP_CHECKSIG; | tx.vout[0].scriptPubKey << OP_CHECKSIG; | ||||
} | } | ||||
{ | { | ||||
CValidationState state; | CValidationState state; | ||||
BOOST_CHECK(CheckRegularTransaction(tx, state, false)); | BOOST_CHECK(CheckRegularTransaction(CTransaction(tx), state, false)); | ||||
} | } | ||||
// And go over. | // And go over. | ||||
tx.vout[0].scriptPubKey << OP_CHECKSIG; | tx.vout[0].scriptPubKey << OP_CHECKSIG; | ||||
{ | { | ||||
CValidationState state; | CValidationState state; | ||||
BOOST_CHECK(!CheckRegularTransaction(tx, state, false)); | BOOST_CHECK(!CheckRegularTransaction(CTransaction(tx), state, false)); | ||||
BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops"); | BOOST_CHECK_EQUAL(state.GetRejectReason(), "bad-txn-sigops"); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |