Skip to content

Commit 5aab011

Browse files
committed
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.
1 parent eae48ec commit 5aab011

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/test/transaction_tests.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,40 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
819819
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
820820
BOOST_CHECK_EQUAL(reason, "scriptsig-size");
821821

822+
// Check scriptSig format (non-standard if there are any other ops than just PUSHs)
823+
t.vin[0].scriptSig = CScript()
824+
<< OP_TRUE << OP_0 << OP_1NEGATE << OP_16 // OP_n (single byte pushes: n = 1, 0, -1, 16)
825+
<< std::vector<unsigned char>(75, 0) // OP_PUSHx [...x bytes...]
826+
<< std::vector<unsigned char>(235, 0) // OP_PUSHDATA1 x [...x bytes...]
827+
<< std::vector<unsigned char>(1234, 0) // OP_PUSHDATA2 x [...x bytes...]
828+
<< OP_9;
829+
BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
830+
831+
const std::vector<unsigned char> non_push_ops = { // arbitrary set of non-push operations
832+
OP_NOP, OP_VERIFY, OP_IF, OP_ROT, OP_3DUP, OP_SIZE, OP_EQUAL, OP_ADD, OP_SUB,
833+
OP_HASH256, OP_CODESEPARATOR, OP_CHECKSIG, OP_CHECKLOCKTIMEVERIFY };
834+
835+
CScript::const_iterator pc = t.vin[0].scriptSig.begin();
836+
while (pc < t.vin[0].scriptSig.end()) {
837+
opcodetype opcode;
838+
CScript::const_iterator prev_pc = pc;
839+
t.vin[0].scriptSig.GetOp(pc, opcode); // advance to next op
840+
// for the sake of simplicity, we only replace single-byte push operations
841+
if (opcode >= 1 && opcode <= OP_PUSHDATA4)
842+
continue;
843+
844+
int index = prev_pc - t.vin[0].scriptSig.begin();
845+
unsigned char orig_op = *prev_pc; // save op
846+
// replace current push-op with each non-push-op
847+
for (auto op : non_push_ops) {
848+
t.vin[0].scriptSig[index] = op;
849+
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
850+
BOOST_CHECK_EQUAL(reason, "scriptsig-not-pushonly");
851+
}
852+
t.vin[0].scriptSig[index] = orig_op; // restore op
853+
BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
854+
}
855+
822856
// Check tx-size (non-standard if transaction weight is > MAX_STANDARD_TX_WEIGHT)
823857
t.vin.clear();
824858
t.vin.resize(2438); // size per input (empty scriptSig): 41 bytes

0 commit comments

Comments
 (0)