Changeset View
Changeset View
Standalone View
Standalone View
src/test/transaction_tests.cpp
Show First 20 Lines • Show All 792 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(test_IsStandard) { | ||||
t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1647, 0); // 1650 | t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1647, 0); // 1650 | ||||
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | ||||
t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1648, 0); // 1651 | t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(1648, 0); // 1651 | ||||
reason.clear(); | reason.clear(); | ||||
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); | BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); | ||||
BOOST_CHECK_EQUAL(reason, "scriptsig-size"); | 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_n (single byte pushes: n = 1, 0, -1, 16) | |||||
<< OP_TRUE << OP_0 << OP_1NEGATE | |||||
<< OP_16 | |||||
// OP_PUSHx [...x bytes...] | |||||
<< std::vector<uint8_t>(75, 0) | |||||
// OP_PUSHDATA1 x [...x bytes...] | |||||
<< std::vector<uint8_t>(235, 0) | |||||
// OP_PUSHDATA2 x [...x bytes...] | |||||
<< std::vector<uint8_t>(1234, 0) << OP_9; | |||||
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | |||||
const std::vector<uint8_t> 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; | |||||
// advance to next op | |||||
t.vin[0].scriptSig.GetOp(pc, opcode); | |||||
// 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(); | |||||
// save op | |||||
uint8_t orig_op = *prev_pc; | |||||
// 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"); | |||||
} | |||||
// restore op | |||||
t.vin[0].scriptSig[index] = orig_op; | |||||
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | |||||
} | |||||
// Check bare multisig (standard if policy flag fIsBareMultisigStd is set) | // Check bare multisig (standard if policy flag fIsBareMultisigStd is set) | ||||
fIsBareMultisigStd = true; | fIsBareMultisigStd = true; | ||||
// simple 1-of-1 | // simple 1-of-1 | ||||
t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); | t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); | ||||
t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(65, 0); | t.vin[0].scriptSig = CScript() << std::vector<uint8_t>(65, 0); | ||||
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); | ||||
fIsBareMultisigStd = false; | fIsBareMultisigStd = false; | ||||
Show All 24 Lines |