Changeset View
Changeset View
Standalone View
Standalone View
src/test/op_bswap_tests.cpp
- This file was added.
// Copyright (c) 2020 The Bitcoin developers | |||||
// Distributed under the MIT software license, see the accompanying | |||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
#include <script/interpreter.h> | |||||
#include <script/script.h> | |||||
#include <test/lcg.h> | |||||
#include <test/test_bitcoin.h> | |||||
#include <boost/test/unit_test.hpp> | |||||
typedef std::vector<uint8_t> valtype; | |||||
typedef std::vector<valtype> stacktype; | |||||
BOOST_FIXTURE_TEST_SUITE(op_bswap_tests, BasicTestingSetup) | |||||
static void CheckErrorWithFlags(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const ScriptError expected) { | |||||
BaseSignatureChecker sigchecker; | |||||
ScriptError err = ScriptError::OK; | |||||
stacktype stack{original_stack}; | |||||
bool r = EvalScript(stack, script, flags, sigchecker, &err); | |||||
BOOST_CHECK(!r); | |||||
BOOST_CHECK(err == expected); | |||||
} | |||||
static void CheckPassWithFlags(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const stacktype &expected) { | |||||
BaseSignatureChecker sigchecker; | |||||
ScriptError err = ScriptError::OK; | |||||
stacktype stack{original_stack}; | |||||
bool r = EvalScript(stack, script, flags, sigchecker, &err); | |||||
BOOST_CHECK(r); | |||||
BOOST_CHECK(err == ScriptError::OK); | |||||
BOOST_CHECK(stack == expected); | |||||
} | |||||
/** | |||||
* Verifies that the given error occurs with OP_BSWAP enabled | |||||
* and that BAD_OPCODE occurs if disabled. | |||||
*/ | |||||
static void CheckErrorIfEnabled(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const ScriptError expected) { | |||||
CheckErrorWithFlags(flags | SCRIPT_ENABLE_OP_BSWAP, original_stack, script, | |||||
expected); | |||||
CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_BSWAP, original_stack, script, | |||||
ScriptError::BAD_OPCODE); | |||||
} | |||||
/** | |||||
* Verifies that the given stack results with OP_BSWAP enabled | |||||
* and that BAD_OPCODE occurs if disabled. | |||||
*/ | |||||
static void CheckPassIfEnabled(const uint32_t flags, | |||||
const stacktype &original_stack, | |||||
const CScript &script, | |||||
const stacktype &expected) { | |||||
CheckPassWithFlags(flags | SCRIPT_ENABLE_OP_BSWAP, original_stack, script, | |||||
expected); | |||||
CheckErrorWithFlags(flags & ~SCRIPT_ENABLE_OP_BSWAP, original_stack, script, | |||||
ScriptError::BAD_OPCODE); | |||||
} | |||||
BOOST_AUTO_TEST_CASE(op_bswap_tests) { | |||||
MMIXLinearCongruentialGenerator lcg; | |||||
for (int i = 0; i < 4096; i++) { | |||||
uint32_t flags = lcg.next(); | |||||
// Empty stack. | |||||
CheckErrorIfEnabled(flags, {}, CScript() << OP_BSWAP, | |||||
ScriptError::INVALID_STACK_OPERATION); | |||||
// Manual tests. | |||||
CheckPassIfEnabled(flags, {{}}, CScript() << OP_BSWAP, {{}}); | |||||
CheckPassIfEnabled(flags, {{99}}, CScript() << OP_BSWAP, {{99}}); | |||||
CheckPassIfEnabled(flags, {{0xde, 0xad}}, CScript() << OP_BSWAP, | |||||
{{0xad, 0xde}}); | |||||
CheckPassIfEnabled(flags, {{0xde, 0xad, 0xa1}}, CScript() << OP_BSWAP, | |||||
{{0xa1, 0xad, 0xde}}); | |||||
CheckPassIfEnabled(flags, {{0xde, 0xad, 0xbe, 0xef}}, | |||||
CScript() << OP_BSWAP, {{0xef, 0xbe, 0xad, 0xde}}); | |||||
// Generated tests, sizes 0 to 520 shoud succeed | |||||
for (int32_t datasize = 0; datasize <= (int32_t)MAX_SCRIPT_ELEMENT_SIZE; | |||||
++datasize) { | |||||
valtype data; | |||||
int32_t item; | |||||
data.reserve(datasize); | |||||
for (item = 0; item < datasize; ++item) { | |||||
data.push_back(uint8_t(item % 256)); | |||||
} | |||||
valtype reversed_data; | |||||
reversed_data.reserve(datasize); | |||||
for (item = datasize - 1; item >= 0; --item) { | |||||
reversed_data.push_back(uint8_t(item % 256)); | |||||
} | |||||
CheckPassIfEnabled(flags, {data}, CScript() << OP_BSWAP, | |||||
{reversed_data}); | |||||
} | |||||
// More tests. | |||||
CheckPassIfEnabled(flags, {{0x12, 0x34, 0x56}, {0x56, 0x34, 0x12}}, | |||||
CScript() << OP_BSWAP << OP_EQUALVERIFY, {}); | |||||
CheckPassIfEnabled( | |||||
flags, {{0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C}}, | |||||
CScript() << OP_DUP << OP_BSWAP << OP_BSWAP << OP_EQUALVERIFY, {}); | |||||
// Verify palindrome. | |||||
CheckPassIfEnabled(flags, {{0x01, 0x02, 0x03, 0x02, 0x01}}, | |||||
CScript() << OP_DUP << OP_BSWAP << OP_EQUALVERIFY, | |||||
{}); | |||||
// Verify non-palindrome fails. | |||||
CheckErrorIfEnabled(flags, {{0x01, 0x02, 0x03, 0x02, 0x02}}, | |||||
CScript() << OP_DUP << OP_BSWAP << OP_EQUALVERIFY, | |||||
ScriptError::EQUALVERIFY); | |||||
} | |||||
} | |||||
BOOST_AUTO_TEST_SUITE_END() |