aboutsummaryrefslogtreecommitdiff
path: root/src/test/transaction_tests.cpp
diff options
context:
space:
mode:
authorSebastian Falbesoner <sebastian.falbesoner@gmail.com>2019-12-11 09:52:57 +0100
committerSebastian Falbesoner <sebastian.falbesoner@gmail.com>2020-02-28 21:20:31 +0100
commit5aab011805ceb12801644170700b1a62e0bf4a5d (patch)
treea69a8555e56ad353d172010a94f1e0343150bd02 /src/test/transaction_tests.cpp
parenteae48ec84c4deacfe92139d07ee80e51136cb766 (diff)
downloadbitcoin-5aab011805ceb12801644170700b1a62e0bf4a5d.tar.xz
test: add unit test for non-standard "scriptsig-not-pushonly" txs
The function IsStandardTx() returns rejection reason "scriptsig-not-pushonly" if the transaction has at least one input for which the scriptSig consists of any other ops than just PUSHs.
Diffstat (limited to 'src/test/transaction_tests.cpp')
-rw-r--r--src/test/transaction_tests.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index bcf4033fe4..2c03f9ec56 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -819,6 +819,40 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
BOOST_CHECK_EQUAL(reason, "scriptsig-size");
+ // Check scriptSig format (non-standard if there are any other ops than just PUSHs)
+ t.vin[0].scriptSig = CScript()
+ << OP_TRUE << OP_0 << OP_1NEGATE << OP_16 // OP_n (single byte pushes: n = 1, 0, -1, 16)
+ << std::vector<unsigned char>(75, 0) // OP_PUSHx [...x bytes...]
+ << std::vector<unsigned char>(235, 0) // OP_PUSHDATA1 x [...x bytes...]
+ << std::vector<unsigned char>(1234, 0) // OP_PUSHDATA2 x [...x bytes...]
+ << OP_9;
+ BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+
+ const std::vector<unsigned char> non_push_ops = { // arbitrary set of non-push operations
+ OP_NOP, OP_VERIFY, OP_IF, OP_ROT, OP_3DUP, OP_SIZE, OP_EQUAL, OP_ADD, OP_SUB,
+ OP_HASH256, OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKLOCKTIMEVERIFY };
+
+ CScript::const_iterator pc = t.vin[0].scriptSig.begin();
+ while (pc < t.vin[0].scriptSig.end()) {
+ opcodetype opcode;
+ CScript::const_iterator prev_pc = pc;
+ t.vin[0].scriptSig.GetOp(pc, opcode); // advance to next op
+ // for the sake of simplicity, we only replace single-byte push operations
+ if (opcode >= 1 && opcode <= OP_PUSHDATA4)
+ continue;
+
+ int index = prev_pc - t.vin[0].scriptSig.begin();
+ unsigned char orig_op = *prev_pc; // save op
+ // replace current push-op with each non-push-op
+ for (auto op : non_push_ops) {
+ t.vin[0].scriptSig[index] = op;
+ BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
+ BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
+ }
+ t.vin[0].scriptSig[index] = orig_op; // restore op
+ BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
+ }
+
// Check tx-size (non-standard if transaction weight is > MAX_STANDARD_TX_WEIGHT)
t.vin.clear();
t.vin.resize(2438); // size per input (empty scriptSig): 41 bytes