Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115717
D1104.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
46 KB
Subscribers
None
D1104.diff
View Options
Index: src/test/op_code.cpp
===================================================================
--- src/test/op_code.cpp
+++ src/test/op_code.cpp
@@ -2,9 +2,9 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "script/script.h"
-#include "script/interpreter.h"
#include "policy/policy.h"
+#include "script/interpreter.h"
+#include "script/script.h"
#include <boost/test/unit_test.hpp>
#include <cassert>
@@ -15,457 +15,698 @@
#endif
//--------------------------
-//uncomment the following line to see debug output
+// uncomment the following line to see debug output
//#define VERBOSE
//--------------------------
#ifdef VERBOSE
-#include <iostream>
-#include <iomanip>
#include "core_io.h"
+#include <iomanip>
+#include <iostream>
#endif
namespace {
- typedef vector<uint8_t> item;
- typedef vector<item> stack_t;
-
- #ifdef VERBOSE
- void print(const item& i) {
- if (i.empty()) cout << "empty";
- for (auto& s:i) cout << hex << setw(2) << setfill('0') << (int) s << " ";
- cout << endl;
- }
- void print(const stack_t& i) {
- for (auto& s:i) print(s);
- cout << endl;
- }
- #endif
-
- /// Deepest sole function for testing expected errors
- /// Invokes the interpreter.
- void test(const CScript& script, stack_t stack, uint32_t flags, const ScriptError se) {
- #ifdef VERBOSE
- cout << "--------------" << endl;
- cout << "Checking script \"" << FormatScript(script) << "\" flags " << flags << endl;
- cout << "with input stack: " << endl;
- print(stack);
- cout << "expected error: " << se << endl;
- #endif
- ScriptError err=SCRIPT_ERR_OK;
- BaseSignatureChecker sigchecker;
- bool r=EvalScript(stack, script, flags, sigchecker, &err);
- BOOST_CHECK_EQUAL(r, false);
- #ifdef VERBOSE
- cout << "got error: " << err << " vs " << se << endl;
- #endif
- BOOST_CHECK_EQUAL(err==se, true);
- }
-
- /// Deepest sole function for testing expected returning stacks
- /// Invokes the interpreter.
- void test(const CScript& script, stack_t stack, uint32_t flags, stack_t expected) {
- #ifdef VERBOSE
- cout << "--------------" << endl;
- cout << "Checking script \"" << FormatScript(script) << "\" flags " << flags << endl;
- cout << "with input stack: " << endl;
- print(stack);
- cout << "expected output stack: " << endl;
- print(expected);
- #endif
- ScriptError err;
- BaseSignatureChecker sigchecker;
- bool r=EvalScript(stack, script, flags, sigchecker, &err);
- #ifdef VERBOSE
- cout << "got output stack: " << endl;
- print(stack);
- #endif
- BOOST_CHECK_EQUAL(r, true);
- BOOST_CHECK_EQUAL(err, SCRIPT_ERR_OK);
- BOOST_CHECK_EQUAL(stack==expected, true);
- }
-
- /// OP_AND, OP_OR
-
- void test_bitwiseop(const CScript& script, uint32_t flags) {
- //number of inputs
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{{0x01}},flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
-
- //where len(x1) == 0 == len(x2) the output will be an empty array.
- test(script,stack_t{{},{}},flags,stack_t{{}});
-
- //operation fails when length of operands not equal
- test(script,stack_t{{0x01},{}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{0x01,0x01},{}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{},{0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{},{0x01,0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{0x01},{0x01,0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{0x01,0x01},{0x01,0x01,0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{0x01,0x01},{0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- test(script,stack_t{{0x01,0x01,0x01},{0x01,0x01}},flags,SCRIPT_ERR_INVALID_BITWISE_OPERATION);
- }
+typedef vector<uint8_t> item;
+typedef vector<item> stack_t;
- /// OP_AND
-
- void test_and(uint32_t flags) {
- CScript script;
- script << OP_AND;
- test_bitwiseop(script,flags);
- test(script,stack_t{{0x00},{0x00}},flags,stack_t{{0x00}});
- test(script,stack_t{{0x00},{0x01}},flags,stack_t{{0x00}});
- test(script,stack_t{{0x01},{0x00}},flags,stack_t{{0x00}});
- test(script,stack_t{{0x01},{0x01}},flags,stack_t{{0x01}});
-
- test(script,stack_t{{0x00,0x00},{0x00,0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x00,0x00},{0x01,0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x01,0x00},{0x00,0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x01,0x00},{0x01,0x00}},flags,stack_t{{0x01,0x00}});
-
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x01);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xF0);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x01 & 0xF0);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
-
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x3C);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xDB);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x3C & 0xDB);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
- }
-
- /// OP_OR
-
- void test_or(uint32_t flags) {
- CScript script;
- script << OP_OR;
- test_bitwiseop(script,flags);
-
- test(script,stack_t{{0x00},{0x00}},flags,stack_t{{0x00}});
- test(script,stack_t{{0x00},{0x01}},flags,stack_t{{0x01}});
- test(script,stack_t{{0x01},{0x00}},flags,stack_t{{0x01}});
- test(script,stack_t{{0x01},{0x01}},flags,stack_t{{0x01}});
+#ifdef VERBOSE
+void print(const item &i) {
+ if (i.empty()) cout << "empty";
+ for (auto &s : i)
+ cout << hex << setw(2) << setfill('0') << (int)s << " ";
+ cout << endl;
+}
+void print(const stack_t &i) {
+ for (auto &s : i)
+ print(s);
+ cout << endl;
+}
+#endif
- test(script,stack_t{{0x00,0x00},{0x00,0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x00,0x00},{0x01,0x00}},flags,stack_t{{0x01,0x00}});
- test(script,stack_t{{0x01,0x00},{0x00,0x00}},flags,stack_t{{0x01,0x00}});
- test(script,stack_t{{0x01,0x00},{0x01,0x00}},flags,stack_t{{0x01,0x00}});
+/// Deepest sole function for testing expected errors
+/// Invokes the interpreter.
+void test(const CScript &script, stack_t stack, uint32_t flags,
+ const ScriptError se) {
+#ifdef VERBOSE
+ cout << "--------------" << endl;
+ cout << "Checking script \"" << FormatScript(script) << "\" flags " << flags
+ << endl;
+ cout << "with input stack: " << endl;
+ print(stack);
+ cout << "expected error: " << se << endl;
+#endif
+ ScriptError err = SCRIPT_ERR_OK;
+ BaseSignatureChecker sigchecker;
+ bool r = EvalScript(stack, script, flags, sigchecker, &err);
+ BOOST_CHECK_EQUAL(r, false);
+#ifdef VERBOSE
+ cout << "got error: " << err << " vs " << se << endl;
+#endif
+ BOOST_CHECK_EQUAL(err == se, true);
+}
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x01);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xF0);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x01 | 0xF0);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
+/// Deepest sole function for testing expected returning stacks
+/// Invokes the interpreter.
+void test(const CScript &script, stack_t stack, uint32_t flags,
+ stack_t expected) {
+#ifdef VERBOSE
+ cout << "--------------" << endl;
+ cout << "Checking script \"" << FormatScript(script) << "\" flags " << flags
+ << endl;
+ cout << "with input stack: " << endl;
+ print(stack);
+ cout << "expected output stack: " << endl;
+ print(expected);
+#endif
+ ScriptError err;
+ BaseSignatureChecker sigchecker;
+ bool r = EvalScript(stack, script, flags, sigchecker, &err);
+#ifdef VERBOSE
+ cout << "got output stack: " << endl;
+ print(stack);
+#endif
+ BOOST_CHECK_EQUAL(r, true);
+ BOOST_CHECK_EQUAL(err, SCRIPT_ERR_OK);
+ BOOST_CHECK_EQUAL(stack == expected, true);
+}
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x3C);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xDB);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x3C | 0xDB);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
+/// OP_AND, OP_OR
+
+void test_bitwiseop(const CScript &script, uint32_t flags) {
+ // number of inputs
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{0x01}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // where len(x1) == 0 == len(x2) the output will be an empty array.
+ test(script, stack_t{{}, {}}, flags, stack_t{{}});
+
+ // operation fails when length of operands not equal
+ test(script, stack_t{{0x01}, {}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{0x01, 0x01}, {}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{}, {0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{}, {0x01, 0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{0x01}, {0x01, 0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{0x01, 0x01}, {0x01, 0x01, 0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{0x01, 0x01}, {0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+ test(script, stack_t{{0x01, 0x01, 0x01}, {0x01, 0x01}}, flags,
+ SCRIPT_ERR_INVALID_BITWISE_OPERATION);
+}
+/// OP_AND
+
+void test_and(uint32_t flags) {
+ CScript script;
+ script << OP_AND;
+ test_bitwiseop(script, flags);
+ test(script, stack_t{{0x00}, {0x00}}, flags, stack_t{{0x00}});
+ test(script, stack_t{{0x00}, {0x01}}, flags, stack_t{{0x00}});
+ test(script, stack_t{{0x01}, {0x00}}, flags, stack_t{{0x00}});
+ test(script, stack_t{{0x01}, {0x01}}, flags, stack_t{{0x01}});
+
+ test(script, stack_t{{0x00, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x00, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x01);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xF0);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x01 & 0xF0);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
}
- /// OP_XOR tests
-
- void test_xor(uint32_t flags) {
- CScript script;
- script << OP_XOR;
- test_bitwiseop(script,flags);
-
- test(script,stack_t{{0x00},{0x00}},flags,stack_t{{0x00}});
- test(script,stack_t{{0x00},{0x01}},flags,stack_t{{0x01}});
- test(script,stack_t{{0x01},{0x00}},flags,stack_t{{0x01}});
- test(script,stack_t{{0x01},{0x01}},flags,stack_t{{0x00}});
-
- test(script,stack_t{{0x00,0x00},{0x00,0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x00,0x00},{0x01,0x00}},flags,stack_t{{0x01,0x00}});
- test(script,stack_t{{0x01,0x00},{0x00,0x00}},flags,stack_t{{0x01,0x00}});
- test(script,stack_t{{0x01,0x00},{0x01,0x00}},flags,stack_t{{0x00,0x00}});
-
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x01);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xF0);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x01 ^ 0xF0);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
-
- {
- item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE,0x3C);
- item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE,0xDB);
- item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE,0x3C ^ 0xDB);
- test(script,stack_t{maxlenbin1,maxlenbin2},flags,stack_t{maxlenbin3});
- }
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x3C);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xDB);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x3C & 0xDB);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
}
+}
- /// OP_DIV tests
-
- void test_div(uint32_t flags) {
- CScript script;
- script << OP_DIV;
-
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{{}},flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
-
- //test not valid numbers
- test(script,stack_t{{0x01,0x02,0x03,0x04,0x05},{0x01,0x02,0x03,0x04,0x05}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- test(script,stack_t{{0x01,0x02,0x03,0x04,0x05},{0x01}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- test(script,stack_t{{0x01,0x05},{0x01,0x02,0x03,0x04,0x05}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- //b == 0 ; b is equal to any type of zero
- test(script,stack_t{{0x01,0x05},{}},flags,SCRIPT_ERR_DIV_BY_ZERO);
- test(script,stack_t{{},{}},flags,SCRIPT_ERR_DIV_BY_ZERO);
- if (flags&SCRIPT_VERIFY_MINIMALDATA) {
- test(script,stack_t{{},{0x00}},flags,SCRIPT_ERR_UNKNOWN_ERROR); //not minimal encoding
- test(script,stack_t{{},{0x00,0x00}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- }
- else {
- test(script,stack_t{{},{0x00}},flags,SCRIPT_ERR_DIV_BY_ZERO);
- test(script,stack_t{{},{0x00,0x00}},flags,SCRIPT_ERR_DIV_BY_ZERO);
- }
- //185377af/85f41b01 =-4
- //185377af/00001b01 =E69D
- test(script,stack_t{{0xaf,0x77,0x53,0x18},{0x01,0x1b,0xf4,0x85}},flags,stack_t{{0x84}});
- test(script,stack_t{{0xaf,0x77,0x53,0x18},{0x01,0x1b}},flags,stack_t{{0x9D,0xE6,0x00}});
- //15/4 =3
- //15/-4 =-3
- //-15/4 =-3
- //-15/-4 =3
- test(script,stack_t{{0x0f},{0x04}},flags,stack_t{{0x03}});
- test(script,stack_t{{0x0f},{0x84}},flags,stack_t{{0x83}});
- test(script,stack_t{{0x8f},{0x04}},flags,stack_t{{0x83}});
- test(script,stack_t{{0x8f},{0x84}},flags,stack_t{{0x03}});
- //15000/4 =3750
- //15000/-4 =-3750
- //-15000/4 =-3750
- //-15000/-4 =3750
- test(script,stack_t{{0x98,0x3a},{0x04}},flags,stack_t{{0xa6,0x0e}});
- test(script,stack_t{{0x98,0x3a},{0x84}},flags,stack_t{{0xa6,0x8e}});
- test(script,stack_t{{0x98,0xba},{0x04}},flags,stack_t{{0xa6,0x8e}});
- test(script,stack_t{{0x98,0xba},{0x84}},flags,stack_t{{0xa6,0x0e}});
- //15000/4000 =3
- //15000/-4000 =-3
- //-15000/4000 =-3
- //-15000/-4000 =3
- test(script,stack_t{{0x98,0x3a},{0xa0,0x0f}},flags,stack_t{{0x03}});
- test(script,stack_t{{0x98,0x3a},{0xa0,0x8f}},flags,stack_t{{0x83}});
- test(script,stack_t{{0x98,0xba},{0xa0,0x0f}},flags,stack_t{{0x83}});
- test(script,stack_t{{0x98,0xba},{0xa0,0x8f}},flags,stack_t{{0x03}});
- //15000000/4000 =3750
- //15000000/-4000 =-3750
- //-15000000/4000 =-3750
- //-15000000/-4000 =3750
- test(script,stack_t{{0xc0,0xe1,0xe4,0x00},{0xa0,0x0f}},flags,stack_t{{0xa6,0x0e}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x00},{0xa0,0x8f}},flags,stack_t{{0xa6,0x8e}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x80},{0xa0,0x0f}},flags,stack_t{{0xa6,0x8e}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x80},{0xa0,0x8f}},flags,stack_t{{0xa6,0x0e}});
- //15000000/4 =3750000
- //15000000/-4 =-3750000
- //-15000000/4 =-3750000
- //-15000000/-4 =3750000
- test(script,stack_t{{0xc0,0xe1,0xe4,0x00},{0x04}},flags,stack_t{{0x70,0x38,0x39}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x00},{0x84}},flags,stack_t{{0x70,0x38,0xb9}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x80},{0x04}},flags,stack_t{{0x70,0x38,0xb9}});
- test(script,stack_t{{0xc0,0xe1,0xe4,0x80},{0x84}},flags,stack_t{{0x70,0x38,0x39}});
+/// OP_OR
+
+void test_or(uint32_t flags) {
+ CScript script;
+ script << OP_OR;
+ test_bitwiseop(script, flags);
+
+ test(script, stack_t{{0x00}, {0x00}}, flags, stack_t{{0x00}});
+ test(script, stack_t{{0x00}, {0x01}}, flags, stack_t{{0x01}});
+ test(script, stack_t{{0x01}, {0x00}}, flags, stack_t{{0x01}});
+ test(script, stack_t{{0x01}, {0x01}}, flags, stack_t{{0x01}});
+
+ test(script, stack_t{{0x00, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x00, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x01);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xF0);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x01 | 0xF0);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
}
- /// OP_MOD tests
-
- void test_mod(uint32_t flags) {
- CScript script;
- script << OP_MOD;
-
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{{}},flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
-
- //test not valid numbers
- test(script,stack_t{{0x01,0x02,0x03,0x04,0x05},{0x01,0x02,0x03,0x04,0x05}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- test(script,stack_t{{0x01,0x02,0x03,0x04,0x05},{0x01}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- test(script,stack_t{{0x01,0x05},{0x01,0x02,0x03,0x04,0x05}},flags,SCRIPT_ERR_UNKNOWN_ERROR);
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x3C);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xDB);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x3C | 0xDB);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
+ }
+}
- //mod by 0
- test(script,stack_t{{0x01,0x05},{}},flags,SCRIPT_ERR_MOD_BY_ZERO);
+/// OP_XOR tests
+
+void test_xor(uint32_t flags) {
+ CScript script;
+ script << OP_XOR;
+ test_bitwiseop(script, flags);
+
+ test(script, stack_t{{0x00}, {0x00}}, flags, stack_t{{0x00}});
+ test(script, stack_t{{0x00}, {0x01}}, flags, stack_t{{0x01}});
+ test(script, stack_t{{0x01}, {0x00}}, flags, stack_t{{0x01}});
+ test(script, stack_t{{0x01}, {0x01}}, flags, stack_t{{0x00}});
+
+ test(script, stack_t{{0x00, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x00, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x00, 0x00}}, flags,
+ stack_t{{0x01, 0x00}});
+ test(script, stack_t{{0x01, 0x00}, {0x01, 0x00}}, flags,
+ stack_t{{0x00, 0x00}});
+
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x01);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xF0);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x01 ^ 0xF0);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
+ }
- //56488123%321 =148
- //56488123%3 =1
- //56488123%564881230 =56488123
- test(script,stack_t{{0xbb,0xf0,0x5d,0x03},{0x41,0x01}},flags,stack_t{{0x94,0x00}});
- test(script,stack_t{{0xbb,0xf0,0x5d,0x03},{0x03}},flags,stack_t{{0x01}});
- test(script,stack_t{{0xbb,0xf0,0x5d,0x03},{0x4e,0x67,0xab,0x21}},flags,stack_t{{0xbb,0xf0,0x5d,0x03}});
+ {
+ item maxlenbin1(MAX_SCRIPT_ELEMENT_SIZE, 0x3C);
+ item maxlenbin2(MAX_SCRIPT_ELEMENT_SIZE, 0xDB);
+ item maxlenbin3(MAX_SCRIPT_ELEMENT_SIZE, 0x3C ^ 0xDB);
+ test(script, stack_t{maxlenbin1, maxlenbin2}, flags,
+ stack_t{maxlenbin3});
+ }
+}
- //-56488123%321 = -148
- //-56488123%3 = -1
- //-56488123%564881230 = -56488123
- test(script,stack_t{{0xbb,0xf0,0x5d,0x83},{0x41,0x01}},flags,stack_t{{0x94,0x80}});
- test(script,stack_t{{0xbb,0xf0,0x5d,0x83},{0x03}},flags,stack_t{{0x81}});
- test(script,stack_t{{0xbb,0xf0,0x5d,0x83},{0x4e,0x67,0xab,0x21}},flags,stack_t{{0xbb,0xf0,0x5d,0x83}});
+/// OP_DIV tests
+
+void test_div(uint32_t flags) {
+ CScript script;
+ script << OP_DIV;
+
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // test not valid numbers
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04, 0x05},
+ {0x01, 0x02, 0x03, 0x04, 0x05}},
+ flags, SCRIPT_ERR_UNKNOWN_ERROR);
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04, 0x05}, {0x01}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+ test(script, stack_t{{0x01, 0x05}, {0x01, 0x02, 0x03, 0x04, 0x05}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+ // b == 0 ; b is equal to any type of zero
+ test(script, stack_t{{0x01, 0x05}, {}}, flags, SCRIPT_ERR_DIV_BY_ZERO);
+ test(script, stack_t{{}, {}}, flags, SCRIPT_ERR_DIV_BY_ZERO);
+ if (flags & SCRIPT_VERIFY_MINIMALDATA) {
+ test(script, stack_t{{}, {0x00}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR); // not minimal encoding
+ test(script, stack_t{{}, {0x00, 0x00}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+ } else {
+ test(script, stack_t{{}, {0x00}}, flags, SCRIPT_ERR_DIV_BY_ZERO);
+ test(script, stack_t{{}, {0x00, 0x00}}, flags, SCRIPT_ERR_DIV_BY_ZERO);
}
+ // 185377af/85f41b01 =-4
+ // 185377af/00001b01 =E69D
+ test(script, stack_t{{0xaf, 0x77, 0x53, 0x18}, {0x01, 0x1b, 0xf4, 0x85}},
+ flags, stack_t{{0x84}});
+ test(script, stack_t{{0xaf, 0x77, 0x53, 0x18}, {0x01, 0x1b}}, flags,
+ stack_t{{0x9D, 0xE6, 0x00}});
+ // 15/4 =3
+ // 15/-4 =-3
+ //-15/4 =-3
+ //-15/-4 =3
+ test(script, stack_t{{0x0f}, {0x04}}, flags, stack_t{{0x03}});
+ test(script, stack_t{{0x0f}, {0x84}}, flags, stack_t{{0x83}});
+ test(script, stack_t{{0x8f}, {0x04}}, flags, stack_t{{0x83}});
+ test(script, stack_t{{0x8f}, {0x84}}, flags, stack_t{{0x03}});
+ // 15000/4 =3750
+ // 15000/-4 =-3750
+ //-15000/4 =-3750
+ //-15000/-4 =3750
+ test(script, stack_t{{0x98, 0x3a}, {0x04}}, flags, stack_t{{0xa6, 0x0e}});
+ test(script, stack_t{{0x98, 0x3a}, {0x84}}, flags, stack_t{{0xa6, 0x8e}});
+ test(script, stack_t{{0x98, 0xba}, {0x04}}, flags, stack_t{{0xa6, 0x8e}});
+ test(script, stack_t{{0x98, 0xba}, {0x84}}, flags, stack_t{{0xa6, 0x0e}});
+ // 15000/4000 =3
+ // 15000/-4000 =-3
+ //-15000/4000 =-3
+ //-15000/-4000 =3
+ test(script, stack_t{{0x98, 0x3a}, {0xa0, 0x0f}}, flags, stack_t{{0x03}});
+ test(script, stack_t{{0x98, 0x3a}, {0xa0, 0x8f}}, flags, stack_t{{0x83}});
+ test(script, stack_t{{0x98, 0xba}, {0xa0, 0x0f}}, flags, stack_t{{0x83}});
+ test(script, stack_t{{0x98, 0xba}, {0xa0, 0x8f}}, flags, stack_t{{0x03}});
+ // 15000000/4000 =3750
+ // 15000000/-4000 =-3750
+ //-15000000/4000 =-3750
+ //-15000000/-4000 =3750
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x00}, {0xa0, 0x0f}}, flags,
+ stack_t{{0xa6, 0x0e}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x00}, {0xa0, 0x8f}}, flags,
+ stack_t{{0xa6, 0x8e}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x80}, {0xa0, 0x0f}}, flags,
+ stack_t{{0xa6, 0x8e}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x80}, {0xa0, 0x8f}}, flags,
+ stack_t{{0xa6, 0x0e}});
+ // 15000000/4 =3750000
+ // 15000000/-4 =-3750000
+ //-15000000/4 =-3750000
+ //-15000000/-4 =3750000
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x00}, {0x04}}, flags,
+ stack_t{{0x70, 0x38, 0x39}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x00}, {0x84}}, flags,
+ stack_t{{0x70, 0x38, 0xb9}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x80}, {0x04}}, flags,
+ stack_t{{0x70, 0x38, 0xb9}});
+ test(script, stack_t{{0xc0, 0xe1, 0xe4, 0x80}, {0x84}}, flags,
+ stack_t{{0x70, 0x38, 0x39}});
+}
- /// OP_CAT
+/// OP_MOD tests
+
+void test_mod(uint32_t flags) {
+ CScript script;
+ script << OP_MOD;
+
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+ // test not valid numbers
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04, 0x05},
+ {0x01, 0x02, 0x03, 0x04, 0x05}},
+ flags, SCRIPT_ERR_UNKNOWN_ERROR);
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04, 0x05}, {0x01}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+ test(script, stack_t{{0x01, 0x05}, {0x01, 0x02, 0x03, 0x04, 0x05}}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+
+ // mod by 0
+ test(script, stack_t{{0x01, 0x05}, {}}, flags, SCRIPT_ERR_MOD_BY_ZERO);
+
+ // 56488123%321 =148
+ // 56488123%3 =1
+ // 56488123%564881230 =56488123
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x03}, {0x41, 0x01}}, flags,
+ stack_t{{0x94, 0x00}});
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x03}, {0x03}}, flags,
+ stack_t{{0x01}});
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x03}, {0x4e, 0x67, 0xab, 0x21}},
+ flags, stack_t{{0xbb, 0xf0, 0x5d, 0x03}});
+
+ //-56488123%321 = -148
+ //-56488123%3 = -1
+ //-56488123%564881230 = -56488123
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x83}, {0x41, 0x01}}, flags,
+ stack_t{{0x94, 0x80}});
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x83}, {0x03}}, flags,
+ stack_t{{0x81}});
+ test(script, stack_t{{0xbb, 0xf0, 0x5d, 0x83}, {0x4e, 0x67, 0xab, 0x21}},
+ flags, stack_t{{0xbb, 0xf0, 0x5d, 0x83}});
+}
- void test_cat(uint32_t flags) {
- CScript script;
- script << OP_CAT;
+/// OP_CAT
- //two inputs required
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{{0x00}},flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
+void test_cat(uint32_t flags) {
+ CScript script;
+ script << OP_CAT;
- //stack item with maximum length
- item maxlength_item(MAX_SCRIPT_ELEMENT_SIZE, 0x00);
+ // two inputs required
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{0x00}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
- //Concatenation producing illegal sized output
- {
+ // stack item with maximum length
+ item maxlength_item(MAX_SCRIPT_ELEMENT_SIZE, 0x00);
+
+ // Concatenation producing illegal sized output
+ {
stack_t input_stack;
input_stack.push_back(maxlength_item);
item i;
i.push_back(0x00);
input_stack.push_back(i);
- test(script,input_stack,flags,SCRIPT_ERR_PUSH_SIZE);
- }
-
- //Concatenation of a max-sized item with empty is legal
- {
+ test(script, input_stack, flags, SCRIPT_ERR_PUSH_SIZE);
+ }
+
+ // Concatenation of a max-sized item with empty is legal
+ {
stack_t input_stack;
input_stack.push_back(maxlength_item);
- input_stack.push_back(item()); //empty item
- test(script,input_stack,flags,stack_t{maxlength_item});
- }
- {
+ input_stack.push_back(item()); // empty item
+ test(script, input_stack, flags, stack_t{maxlength_item});
+ }
+ {
stack_t input_stack;
- input_stack.push_back(item()); //empty item
+ input_stack.push_back(item()); // empty item
input_stack.push_back(maxlength_item);
- test(script,input_stack,flags,stack_t{maxlength_item});
- }
-
- //Concatenation of a zero length operand
- test(script,stack_t{{0x01},{}},flags,stack_t{{0x01}});
- test(script,stack_t{{},{0x01}},flags,stack_t{{0x01}});
-
- //Concatenation of two empty operands results in empty item
- test(script,stack_t{{},{}},flags,stack_t{{}});
-
- // concatenating two operands generates the correct result
- test(script,stack_t{{0x00},{0x00}},flags,stack_t{{0x00,0x00}});
- test(script,stack_t{{0x01},{0x02}},flags,stack_t{{0x01,0x02}});
- test(script,stack_t{{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a},{0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14}},flags,stack_t{{0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14}});
+ test(script, input_stack, flags, stack_t{maxlength_item});
}
- /// OP_SPLIT
+ // Concatenation of a zero length operand
+ test(script, stack_t{{0x01}, {}}, flags, stack_t{{0x01}});
+ test(script, stack_t{{}, {0x01}}, flags, stack_t{{0x01}});
+
+ // Concatenation of two empty operands results in empty item
+ test(script, stack_t{{}, {}}, flags, stack_t{{}});
+
+ // concatenating two operands generates the correct result
+ test(script, stack_t{{0x00}, {0x00}}, flags, stack_t{{0x00, 0x00}});
+ test(script, stack_t{{0x01}, {0x02}}, flags, stack_t{{0x01, 0x02}});
+ test(script,
+ stack_t{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a},
+ {0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}},
+ flags,
+ stack_t{{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14}});
+}
- void test_split(uint32_t flags) {
- CScript script;
- script << OP_SPLIT; //inputs: x n; outputs: x1 x2
+/// OP_SPLIT
- //two inputs required
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{{0x01}},flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
+void test_split(uint32_t flags) {
+ CScript script;
+ script << OP_SPLIT; // inputs: x n; outputs: x1 x2
- //length of 2nd input greater than CScriptNum::nDefaultMaxNumSize
- {
- item maxlength_num_item(CScriptNum::nDefaultMaxNumSize,0x01);
- item illegal_item=maxlength_num_item;
- illegal_item.push_back(0x00);
- test(script,stack_t{{0x01},illegal_item},flags,SCRIPT_ERR_UNKNOWN_ERROR);
- }
+ // two inputs required
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{0x01}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
- //if n == 0, then x1 is the empty array and x2 == x;
- //execution of OP_SPLIT on empty array results in two empty arrays.
- test(script,stack_t{{},{}},flags,stack_t{{},{}});
- test(script,stack_t{{0x01},{}},flags,stack_t{{},{0x01}}); //x 0 OP_SPLIT -> OP_0 x
- test(script,stack_t{{0x01,0x02,0x03,0x04},{}},flags,stack_t{{},{0x01,0x02,0x03,0x04}});
-
- //if n == len(x) then x1 == x and x2 is the empty array
- test(script,stack_t{{0x01},{0x01}},flags,stack_t{{0x01},{}});
- test(script,stack_t{{0x01,0x02,0x03},{0x03}},flags,stack_t{{0x01,0x02,0x03},{}}); //x len(x) OP_SPLIT -> x OP_0
+ // length of 2nd input greater than CScriptNum::nDefaultMaxNumSize
+ {
+ item maxlength_num_item(CScriptNum::nDefaultMaxNumSize, 0x01);
+ item illegal_item = maxlength_num_item;
+ illegal_item.push_back(0x00);
+ test(script, stack_t{{0x01}, illegal_item}, flags,
+ SCRIPT_ERR_UNKNOWN_ERROR);
+ }
- //if n > len(x), then the operator must fail; x (len(x) + 1) OP_SPLIT -> FAIL
- test(script,stack_t{{},{0x01}},flags,SCRIPT_ERR_INVALID_SPLIT_RANGE);
- test(script,stack_t{{0x01},{0x02}},flags,SCRIPT_ERR_INVALID_SPLIT_RANGE);
- test(script,stack_t{{0x01,0x02,0x03},{0x04}},flags,SCRIPT_ERR_INVALID_SPLIT_RANGE);
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x05}},flags,SCRIPT_ERR_INVALID_SPLIT_RANGE);
+ // if n == 0, then x1 is the empty array and x2 == x;
+ // execution of OP_SPLIT on empty array results in two empty arrays.
+ test(script, stack_t{{}, {}}, flags, stack_t{{}, {}});
+ test(script, stack_t{{0x01}, {}}, flags,
+ stack_t{{}, {0x01}}); // x 0 OP_SPLIT -> OP_0 x
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {}}, flags,
+ stack_t{{}, {0x01, 0x02, 0x03, 0x04}});
+
+ // if n == len(x) then x1 == x and x2 is the empty array
+ test(script, stack_t{{0x01}, {0x01}}, flags, stack_t{{0x01}, {}});
+ test(script, stack_t{{0x01, 0x02, 0x03}, {0x03}}, flags,
+ stack_t{{0x01, 0x02, 0x03}, {}}); // x len(x) OP_SPLIT -> x OP_0
+
+ // if n > len(x), then the operator must fail; x (len(x) + 1) OP_SPLIT ->
+ // FAIL
+ test(script, stack_t{{}, {0x01}}, flags, SCRIPT_ERR_INVALID_SPLIT_RANGE);
+ test(script, stack_t{{0x01}, {0x02}}, flags,
+ SCRIPT_ERR_INVALID_SPLIT_RANGE);
+ test(script, stack_t{{0x01, 0x02, 0x03}, {0x04}}, flags,
+ SCRIPT_ERR_INVALID_SPLIT_RANGE);
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x05}}, flags,
+ SCRIPT_ERR_INVALID_SPLIT_RANGE);
+
+ // if n < 0 the operator must fail.
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x81}}, flags,
+ SCRIPT_ERR_INVALID_SPLIT_RANGE);
+
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x01}}, flags,
+ stack_t{{0x01}, {0x02, 0x03, 0x04}});
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x02}}, flags,
+ stack_t{{0x01, 0x02}, {0x03, 0x04}});
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x03}}, flags,
+ stack_t{{0x01, 0x02, 0x03}, {0x04}});
+ test(script, stack_t{{0x01, 0x02, 0x03, 0x04}, {0x04}}, flags,
+ stack_t{{0x01, 0x02, 0x03, 0x04}, {}});
+
+ // split of a max-len item
+ {
+ item maxlength_item(MAX_SCRIPT_ELEMENT_SIZE, 0x00);
+ test(script, stack_t{maxlength_item, {}}, flags,
+ stack_t{{}, maxlength_item});
+ }
+}
- //if n < 0 the operator must fail.
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x81}},flags,SCRIPT_ERR_INVALID_SPLIT_RANGE);
+/// OP_CAT + OP_SPLIT
+void test_cat_split(const item &x, uint32_t flags) {
+ CScript script;
+ script << OP_SPLIT << OP_CAT;
+ // x n OP_SPLIT OP_CAT -> x - for all x and for all 0 <= n <= len(x)
+ test(script, stack_t{x, {}}, flags, stack_t{x});
+ for (uint8_t i = 1; i <= x.size(); ++i) {
+ test(script, stack_t{x, {i}}, flags, stack_t{x});
+ }
+}
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x01}},flags,stack_t{{0x01},{0x02,0x03,0x04}});
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x02}},flags,stack_t{{0x01,0x02},{0x03,0x04}});
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x03}},flags,stack_t{{0x01,0x02,0x03},{0x04}});
- test(script,stack_t{{0x01,0x02,0x03,0x04},{0x04}},flags,stack_t{{0x01,0x02,0x03,0x04},{}});
+void test_cat_split(uint32_t flags) {
+ test_cat_split({}, flags);
+ test_cat_split({0x01}, flags);
+ test_cat_split({0x01, 0x02}, flags);
+ test_cat_split({0x01, 0x02, 0x03}, flags);
+}
- //split of a max-len item
- {
- item maxlength_item(MAX_SCRIPT_ELEMENT_SIZE, 0x00);
- test(script,stack_t{maxlength_item,{}},flags,stack_t{{},maxlength_item});
+/// OP_BIN2NUM tests
+
+/// make bin - helper function
+/// input: a number
+/// output: BIN representation Big Endian (BE)
+/// removes the sign, constructs a BE array of bytes with the positive
+/// number,
+/// the adds the sign.
+item mk_bin(int64_t v0) {
+ if (v0 == 0) return item{0x00};
+ bool neg = v0 < 0;
+ uint64_t v = htobe64(neg ? -v0 : v0);
+ item ans;
+ ans.reserve(sizeof(uint64_t));
+ uint8_t *p = reinterpret_cast<uint8_t *>(&v);
+ for (size_t i = 0; i < sizeof(uint64_t); ++i, ++p) {
+ if (ans.empty()) {
+ if (!*p) continue;
+ if (*p & 0x80)
+ ans.push_back(0x00); // first bit looks like a sign but it is
+ // not, add a leading 0
}
+ ans.push_back(*p);
}
+ if (neg) *ans.begin() |= 0x80; // add the sign
+ return move(ans);
+}
- /// OP_CAT + OP_SPLIT
+void test_bin2num(uint32_t flags) {
+ CScript script;
+ script << OP_BIN2NUM;
+ {
+ item i{0x00, 0x80, 0x00, 0x05};
+ BOOST_CHECK_EQUAL(mk_bin(0x800005) == i, true);
+ }
+ {
+ item i{0x05};
+ BOOST_CHECK_EQUAL(mk_bin(0x000005) == i, true);
+ }
+ {
+ item i{0x01, 0x05};
+ BOOST_CHECK_EQUAL(mk_bin(0x000105) == i, true);
+ }
+ {
+ item i{0x81, 0x05};
+ BOOST_CHECK_EQUAL(mk_bin(-0x000105) == i, true);
+ }
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{mk_bin(0)}, flags, stack_t{{}});
+ test(script, stack_t{mk_bin((int64_t)INT_MAX >> 1)}, flags,
+ stack_t{CScriptNum(INT_MAX >> 1).getvch()});
+ test(script, stack_t{mk_bin((int64_t)INT_MIN >> 1)}, flags,
+ stack_t{CScriptNum(INT_MIN >> 1).getvch()});
+ test(script, stack_t{mk_bin((int64_t)(INT_MAX >> 1) + 1)}, flags,
+ SCRIPT_ERR_INVALID_BIN2NUM_OPERATION);
+ test(script, stack_t{mk_bin((int64_t)(INT_MIN >> 1) - 1)}, flags,
+ SCRIPT_ERR_INVALID_BIN2NUM_OPERATION);
+ test(script, stack_t{mk_bin(106894)}, flags,
+ stack_t{CScriptNum(106894).getvch()});
+ test(script, stack_t{mk_bin(-106894)}, flags,
+ stack_t{CScriptNum(-106894).getvch()});
+ test(script, stack_t{mk_bin(0)}, flags, stack_t{CScriptNum(0).getvch()});
+}
- void test_cat_split(const item& x, uint32_t flags) {
- CScript script;
- script << OP_SPLIT << OP_CAT;
- // x n OP_SPLIT OP_CAT -> x - for all x and for all 0 <= n <= len(x)
- test(script,stack_t{x,{}},flags,stack_t{x});
- for (uint8_t i=1; i<=x.size(); ++i) {
- test(script,stack_t{x,{i}},flags,stack_t{x});
- }
+/// OP_NUM2BIN tests
+
+/// make expected value - helper function
+/// input: number in LE byte order, desired output byte length
+/// output: BIN representation as expected to be generated by the
+/// interpreter.
+/// removes the sign, constructs a BE array of bytes with the positive
+/// number,
+/// the adds the sign.
+///
+vector<uint8_t> make_ev(vector<uint8_t> v, size_t sz) { // v contains a num in
+ // LE
+ if (v.empty()) return vector<uint8_t>(sz, 0);
+ vector<uint8_t> ans;
+ assert(sz >= v.size());
+ ans.reserve(sz);
+ bool neg = *v.rbegin() & 0x80;
+ *v.rbegin() &= ~0x80;
+ size_t pad = sz - v.size();
+ for (uint8_t i = 0; i < pad; ++i) {
+ ans.push_back(0);
+ }
+ for (auto i = v.rbegin(); i != v.rend(); ++i) {
+ ans.push_back(*i);
}
+ if (neg) *ans.begin() |= 0x80;
+ return ans;
+}
- void test_cat_split(uint32_t flags) {
- test_cat_split({},flags);
- test_cat_split({0x01},flags);
- test_cat_split({0x01,0x02},flags);
- test_cat_split({0x01,0x02,0x03},flags);
+void test_num2bin(const CScript &script, vector<uint8_t> v, uint32_t flags) {
+ if (v.empty()) return;
+ for (uint8_t i = 0; i < v.size(); ++i) {
+ if (i == 0)
+ test(script, stack_t{v, {}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ else
+ test(script, stack_t{v, {i}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ }
+ for (uint8_t i = v.size(); i <= CScriptNum::nDefaultMaxNumSize; ++i) {
+ if (i == 0)
+ test(script, stack_t{v, {}}, flags, stack_t{make_ev(v, i)});
+ else
+ test(script, stack_t{v, {i}}, flags, stack_t{make_ev(v, i)});
}
+}
+
+void test_num2bin(uint32_t flags) {
+ CScript script;
+ script << OP_NUM2BIN;
+ test(script, stack_t(), flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{4}}, flags, SCRIPT_ERR_INVALID_STACK_OPERATION);
+ test(script, stack_t{{0x02}, {CScriptNum::nDefaultMaxNumSize + 1}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ test(script, stack_t{{0x85}, {CScriptNum::nDefaultMaxNumSize + 1}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ test(script, stack_t{{0x02}, {}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ test(script, stack_t{{0x85}, {0x85}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ test(script, stack_t{{0x85}, {}}, flags,
+ SCRIPT_ERR_INVALID_NUM2BIN_OPERATION);
+ test_num2bin(script, {}, flags);
+ test_num2bin(script, {0x7f}, flags);
+ test_num2bin(script, {0xff, 0x7f}, flags); // LE for 0x7FFF
+ test_num2bin(script, {0x02, 0x71}, flags);
+ test_num2bin(script, {0xff, 0xff, 0x7f}, flags);
+ test_num2bin(script, {0x03, 0x02, 0x71}, flags);
+ test_num2bin(script, {0xff, 0xff, 0xff, 0x7f}, flags);
+ test_num2bin(script, {0x04, 0x03, 0x02, 0x71}, flags);
+ test_num2bin(script, {0x81}, flags);
+ test_num2bin(script, {0xff, 0x80}, flags);
+ test_num2bin(script, {0xaf, 0x81}, flags);
+ test_num2bin(script, {0xed, 0x60, 0x83}, flags);
+ test_num2bin(script, {0xb6, 0xe3, 0x81}, flags);
+ test_num2bin(script, {0x81, 0x9a, 0x6e, 0x84}, flags);
+ test_num2bin(script, {0xe4, 0xc3, 0x92, 0x91}, flags);
+}
+
+/// OP_BIN2NUM + OP_NUM2BIN tests
+
+void test_bin2num_num2bin(const CScript &script, int sz, int64_t v,
+ uint32_t flags) {
+ auto x = mk_bin(v);
+ test(script, stack_t{x}, flags,
+ stack_t{make_ev(CScriptNum(v).getvch(), sz)});
+}
+
+void test_num2bin_bin2num(const CScript &script, int64_t v, uint32_t flags) {
+ test(script, stack_t{CScriptNum(v).getvch()}, flags,
+ stack_t{CScriptNum(v).getvch()});
+}
- /// OP_BIN2NUM tests
-
- /// make bin - helper function
- /// input: a number
- /// output: BIN representation Big Endian (BE)
- /// removes the sign, constructs a BE array of bytes with the positive number,
- /// the adds the sign.
- item mk_bin(int64_t v0) {
- if (v0==0) return item{0x00};
- bool neg=v0<0;
- uint64_t v=htobe64(neg?-v0:v0);
- item ans;
- ans.reserve(sizeof(uint64_t));
- uint8_t* p=reinterpret_cast<uint8_t*>(&v);
- for (size_t i=0; i<sizeof(uint64_t); ++i, ++p) {
- if (ans.empty()) {
- if (!*p) continue;
- if (*p&0x80) ans.push_back(0x00); //first bit looks like a sign but it is not, add a leading 0
+void test_bin2num_num2bin(int sz, uint32_t flags) {
+ CScript script;
+ script << OP_BIN2NUM << sz << OP_NUM2BIN;
+ test_bin2num_num2bin(script, sz, 0, flags);
+ test_bin2num_num2bin(script, sz, 1, flags);
+ test_bin2num_num2bin(script, sz, -1, flags);
+ if (sz >= 2) {
+ test_bin2num_num2bin(script, sz, 321, flags);
+ test_bin2num_num2bin(script, sz, -321, flags);
+ if (sz >= 3) {
+ test_bin2num_num2bin(script, sz, 106894, flags);
+ test_bin2num_num2bin(script, sz, -106894, flags);
+ if (sz >= 4) {
+ test_bin2num_num2bin(script, sz, INT_MAX >> 1, flags);
+ test_bin2num_num2bin(script, sz, INT_MIN >> 1, flags);
}
- ans.push_back(*p);
}
- if (neg) *ans.begin()|=0x80; //add the sign
- return move(ans);
}
+}
- void test_bin2num(uint32_t flags) {
- CScript script;
- script << OP_BIN2NUM;
- { item i{0x00, 0x80, 0x00, 0x05}; BOOST_CHECK_EQUAL(mk_bin(0x800005)==i, true); }
- { item i{0x05}; BOOST_CHECK_EQUAL(mk_bin(0x000005)==i, true); }
- { item i{0x01,0x05}; BOOST_CHECK_EQUAL(mk_bin(0x000105)==i, true); }
- { item i{0x81,0x05}; BOOST_CHECK_EQUAL(mk_bin(-0x000105)==i, true); }
- test(script,stack_t(),flags,SCRIPT_ERR_INVALID_STACK_OPERATION);
- test(script,stack_t{mk_bin(0)},flags,stack_t{{}});
- test(script,stack_t{mk_bin((int64_t)INT_MAX>>1)},flags,stack_t{CScriptNum(INT_MAX>>1).getvch()});
- test(script,stack_t{mk_bin((int64_t)INT_MIN>>1)},flags,stack_t{CScriptNum(INT_MIN>>1).getvch()});
- test(script,stack_t{mk_bin((int64_t)(INT_MAX>>1)+1)},flags,SCRIPT_ERR_INVALID_BIN2NUM_OPERATION);
- test(script,stack_t{mk_bin((int64_t)(INT_MIN>>1)-1)},flags,SCRIPT_ERR_INVALID_BIN2NUM_OPERATION);
- test(script,stack_t{mk_bin(106894)},flags,stack_t{CScriptNum(106894).getvch()});
- test(script,stack_t{mk_bin(-106894)},flags,stack_t{CScriptNum(-106894).getvch()});
- test(script,stack_t{mk_bin(0)},flags,stack_t{CScriptNum(0).getvch()});
+void test_num2bin_bin2num(int sz, uint32_t flags) {
+ CScript script;
+ script << sz << OP_NUM2BIN << OP_BIN2NUM;
+ test_num2bin_bin2num(script, 0, flags);
+ test_num2bin_bin2num(script, 1, flags);
+ test_num2bin_bin2num(script, -1, flags);
+ if (sz >= 2) {
+ test_num2bin_bin2num(script, 321, flags);
+ test_num2bin_bin2num(script, -321, flags);
+ if (sz >= 3) {
+ test_num2bin_bin2num(script, 106894, flags);
+ test_num2bin_bin2num(script, -106894, flags);
+ if (sz >= 4) {
+ test_num2bin_bin2num(script, INT_MAX >> 1, flags);
+ test_num2bin_bin2num(script, INT_MIN >> 1, flags);
+ }
+ }
}
+}
+void test_bin2num_num2bin(uint32_t flags) {
+ test_bin2num_num2bin(4, flags); // expect 4 byte output
+ test_bin2num_num2bin(3, flags); // expect 3 byte output
+ test_bin2num_num2bin(2, flags); // expect 2 byte output
+ test_bin2num_num2bin(1, flags); // expect 1 byte output
+}
+
+void test_num2bin_bin2num(uint32_t flags) {
+ test_num2bin_bin2num(4, flags); // 4 byte num2bin output
+ test_num2bin_bin2num(3, flags); // 3 byte num2bin output
+ test_num2bin_bin2num(2, flags); // 2 byte num2bin output
+ test_num2bin_bin2num(1, flags); // 1 byte num2bin output
+}
}
/// Entry points
@@ -535,5 +776,25 @@
test_bin2num(STANDARD_LOCKTIME_VERIFY_FLAGS);
}
-BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_CASE(op_num2bin) {
+ test_num2bin(0);
+ test_num2bin(STANDARD_SCRIPT_VERIFY_FLAGS);
+ test_num2bin(STANDARD_NOT_MANDATORY_VERIFY_FLAGS);
+ test_num2bin(STANDARD_LOCKTIME_VERIFY_FLAGS);
+}
+
+BOOST_AUTO_TEST_CASE(bin2num_num2bin) {
+ test_bin2num_num2bin(0);
+ test_bin2num_num2bin(STANDARD_SCRIPT_VERIFY_FLAGS);
+ test_bin2num_num2bin(STANDARD_NOT_MANDATORY_VERIFY_FLAGS);
+ test_bin2num_num2bin(STANDARD_LOCKTIME_VERIFY_FLAGS);
+}
+BOOST_AUTO_TEST_CASE(num2bin_bin2num) {
+ test_num2bin_bin2num(0);
+ test_num2bin_bin2num(STANDARD_SCRIPT_VERIFY_FLAGS);
+ test_num2bin_bin2num(STANDARD_NOT_MANDATORY_VERIFY_FLAGS);
+ test_num2bin_bin2num(STANDARD_LOCKTIME_VERIFY_FLAGS);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 1, 11:52 (6 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5187706
Default Alt Text
D1104.diff (46 KB)
Attached To
D1104: unit tests for OP_NUM2BIN
Event Timeline
Log In to Comment