Skip to content

Instantly share code, notes, and snippets.

@jl2012
Last active November 23, 2018 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jl2012/9315ee59290fd48db7c8a416444aa6fb to your computer and use it in GitHub Desktop.
Save jl2012/9315ee59290fd48db7c8a416444aa6fb to your computer and use it in GitHub Desktop.
int FindAndMask(CScript& script)
{
int masked = 0;
bool skip_next = false;
CScript result;
CScript::const_iterator pc = script.begin(), pc2 = script.begin();
opcodetype opcode;
while (script.GetOp(pc, opcode)) {
if (opcode == OP_MASK) {
result.insert(result.end(), pc2, pc);
skip_next = true;
pc2 = pc;
}
else if (skip_next == true) {
result.insert(result.end(), (unsigned char)OP_VERIF);
skip_next = false;
pc2 = pc;
++masked;
}
}
if (skip_next == true) {
script = CScript();
return -1;
}
if (masked > 0) {
result.insert(result.end(), pc2, static_cast<CScript::const_iterator>(script.end()));
script = std::move(result);
}
return masked;
}
BOOST_AUTO_TEST_CASE(script_op_mask)
{
// Exercise the FindAndMask functionality
CScript s;
CScript d;
CScript e;
s = CScript() << OP_1 << OP_2 << OP_3;
e = s;
BOOST_CHECK_EQUAL(FindAndMask(s), 0);
BOOST_CHECK(s == e);
s = ScriptFromHex("5101bd02febd");
e = s;
BOOST_CHECK_EQUAL(FindAndMask(s), 0);
BOOST_CHECK(s == e);
s = ScriptFromHex("5101bd02bd"); // invalid: incomplete push
e = s;
BOOST_CHECK_EQUAL(FindAndMask(s), 0);
BOOST_CHECK(s == e);
e = CScript() << OP_1 << OP_MASK << OP_VERIF;
s = CScript() << OP_1 << OP_MASK << OP_DUP;
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd02feed");
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd02febd");
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed");
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_MASK << OP_VERIF; // invalid: OP_VERIF
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed02bdbd");
e = ScriptFromHex("51bd6502bdbd");
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = ScriptFromHex("51bd4e02000000feed02bd"); // invalid: incomplete push
e = ScriptFromHex("51bd6502bd");
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_IF << OP_MASK << OP_NOP8 << OP_ELSE << OP_MASK << OP_NOP9 << OP_ENDIF;
e = CScript() << OP_1 << OP_IF << OP_MASK << OP_VERIF << OP_ELSE << OP_MASK << OP_VERIF << OP_ENDIF;
BOOST_CHECK_EQUAL(FindAndMask(s), 2);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_MASK << OP_MASK << OP_3;
e = CScript() << OP_1 << OP_MASK << OP_MASK << OP_VERIF;
BOOST_CHECK_EQUAL(FindAndMask(s), 1);
BOOST_CHECK(s == e);
s = CScript() << OP_1 << OP_MASK << OP_MASK << OP_3 << OP_MASK;
BOOST_CHECK_EQUAL(FindAndMask(s), -1);
BOOST_CHECK(s == CScript());
s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK << OP_MASK;
BOOST_CHECK_EQUAL(FindAndMask(s), -1);
BOOST_CHECK(s == CScript());
s = CScript() << OP_1 << OP_2 << OP_3 << OP_MASK;
BOOST_CHECK_EQUAL(FindAndMask(s), -1);
BOOST_CHECK(s == CScript());
s = CScript() << OP_1 << OP_2 << OP_NOTIF << OP_MASK; // invalid: inbalance condition
BOOST_CHECK_EQUAL(FindAndMask(s), -1);
BOOST_CHECK(s == CScript());
s = ScriptFromHex("51bd02fe"); // invalid: incomplete push
BOOST_CHECK_EQUAL(FindAndMask(s), -1);
BOOST_CHECK(s == CScript());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment