Changeset View
Changeset View
Standalone View
Standalone View
src/test/script_sighashtype_tests.cpp
// Copyright (c) 2016 The Bitcoin Core developers | // Copyright (c) 2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "script/sighashtype.h" | #include "script/sighashtype.h" | ||||
#include "test/test_bitcoin.h" | #include "test/test_bitcoin.h" | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
#include <set> | #include <set> | ||||
BOOST_FIXTURE_TEST_SUITE(script_sighashtype_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(script_sighashtype_tests, BasicTestingSetup) | ||||
static void CheckSigHashType(SigHashType t, BaseSigHashType baseType, | static void CheckSigHashType(SigHashType t, BaseSigHashType baseType, | ||||
bool hasSupportedBaseType, uint32_t forkValue, | bool isDefined, uint32_t forkValue, bool hasForkId, | ||||
bool hasForkId, bool hasAnyoneCanPay) { | bool hasAnyoneCanPay) { | ||||
BOOST_CHECK(t.getBaseType() == baseType); | BOOST_CHECK(t.getBaseType() == baseType); | ||||
BOOST_CHECK_EQUAL(t.hasSupportedBaseType(), hasSupportedBaseType); | BOOST_CHECK_EQUAL(t.isDefined(), isDefined); | ||||
BOOST_CHECK_EQUAL(t.getForkValue(), forkValue); | BOOST_CHECK_EQUAL(t.getForkValue(), forkValue); | ||||
BOOST_CHECK_EQUAL(t.hasForkId(), hasForkId); | BOOST_CHECK_EQUAL(t.hasForkId(), hasForkId); | ||||
BOOST_CHECK_EQUAL(t.hasAnyoneCanPay(), hasAnyoneCanPay); | BOOST_CHECK_EQUAL(t.hasAnyoneCanPay(), hasAnyoneCanPay); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(sighash_construction_test) { | BOOST_AUTO_TEST_CASE(sighash_construction_test) { | ||||
// Check default values. | // Check default values. | ||||
CheckSigHashType(SigHashType(), BaseSigHashType::ALL, true, 0, false, | CheckSigHashType(SigHashType(), BaseSigHashType::ALL, true, 0, false, | ||||
Show All 12 Lines | for (BaseSigHashType baseType : baseTypes) { | ||||
for (bool hasForkId : forkIdFlagValues) { | for (bool hasForkId : forkIdFlagValues) { | ||||
for (bool hasAnyoneCanPay : anyoneCanPayFlagValues) { | for (bool hasAnyoneCanPay : anyoneCanPayFlagValues) { | ||||
SigHashType t = SigHashType() | SigHashType t = SigHashType() | ||||
.withBaseType(baseType) | .withBaseType(baseType) | ||||
.withForkValue(forkValue) | .withForkValue(forkValue) | ||||
.withForkId(hasForkId) | .withForkId(hasForkId) | ||||
.withAnyoneCanPay(hasAnyoneCanPay); | .withAnyoneCanPay(hasAnyoneCanPay); | ||||
bool hasSupportedBaseType = | bool isDefined = baseType != BaseSigHashType::UNSUPPORTED; | ||||
baseType != BaseSigHashType::UNSUPPORTED; | CheckSigHashType(t, baseType, isDefined, forkValue, | ||||
CheckSigHashType(t, baseType, hasSupportedBaseType, | hasForkId, hasAnyoneCanPay); | ||||
forkValue, hasForkId, hasAnyoneCanPay); | |||||
// Also check all possible alterations. | // Also check all possible alterations. | ||||
CheckSigHashType(t.withForkId(hasForkId), baseType, | CheckSigHashType(t.withForkId(hasForkId), baseType, | ||||
hasSupportedBaseType, forkValue, hasForkId, | isDefined, forkValue, hasForkId, | ||||
hasAnyoneCanPay); | hasAnyoneCanPay); | ||||
CheckSigHashType(t.withForkId(!hasForkId), baseType, | CheckSigHashType(t.withForkId(!hasForkId), baseType, | ||||
hasSupportedBaseType, forkValue, | isDefined, forkValue, !hasForkId, | ||||
!hasForkId, hasAnyoneCanPay); | hasAnyoneCanPay); | ||||
CheckSigHashType(t.withAnyoneCanPay(hasAnyoneCanPay), | CheckSigHashType(t.withAnyoneCanPay(hasAnyoneCanPay), | ||||
baseType, hasSupportedBaseType, forkValue, | baseType, isDefined, forkValue, hasForkId, | ||||
hasForkId, hasAnyoneCanPay); | hasAnyoneCanPay); | ||||
CheckSigHashType(t.withAnyoneCanPay(!hasAnyoneCanPay), | CheckSigHashType(t.withAnyoneCanPay(!hasAnyoneCanPay), | ||||
baseType, hasSupportedBaseType, forkValue, | baseType, isDefined, forkValue, hasForkId, | ||||
hasForkId, !hasAnyoneCanPay); | !hasAnyoneCanPay); | ||||
for (BaseSigHashType newBaseType : baseTypes) { | for (BaseSigHashType newBaseType : baseTypes) { | ||||
bool hasSupportedNewBaseType = | bool isNewDefined = | ||||
newBaseType != BaseSigHashType::UNSUPPORTED; | newBaseType != BaseSigHashType::UNSUPPORTED; | ||||
CheckSigHashType(t.withBaseType(newBaseType), | CheckSigHashType(t.withBaseType(newBaseType), | ||||
newBaseType, hasSupportedNewBaseType, | newBaseType, isNewDefined, forkValue, | ||||
forkValue, hasForkId, hasAnyoneCanPay); | hasForkId, hasAnyoneCanPay); | ||||
} | } | ||||
for (uint32_t newForkValue : forkValues) { | for (uint32_t newForkValue : forkValues) { | ||||
CheckSigHashType(t.withForkValue(newForkValue), | CheckSigHashType(t.withForkValue(newForkValue), | ||||
baseType, hasSupportedBaseType, | baseType, isDefined, newForkValue, | ||||
newForkValue, hasForkId, | hasForkId, hasAnyoneCanPay); | ||||
hasAnyoneCanPay); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(sighash_serialization_test) { | BOOST_AUTO_TEST_CASE(sighash_serialization_test) { | ||||
std::set<uint32_t> forkValues{0, 1, 0xab1fe9, 0xc81eea, 0xffffff}; | std::set<uint32_t> forkValues{0, 1, 0xab1fe9, 0xc81eea, 0xffffff}; | ||||
// Test all possible base sig hash values. | // Test all possible sig hash values embeded in signatures. | ||||
for (uint32_t baseType = 0; baseType <= 0x1f; baseType++) { | for (uint32_t sigHashType = 0x00; sigHashType <= 0xff; sigHashType++) { | ||||
for (uint32_t forkValue : forkValues) { | for (uint32_t forkValue : forkValues) { | ||||
bool hasSupportedBaseType = | uint32_t rawType = sigHashType | (forkValue << 8); | ||||
(baseType != 0) && (baseType <= SIGHASH_SINGLE); | |||||
uint32_t rawType = baseType | (forkValue << 8); | uint32_t baseType = rawType & 0x1f; | ||||
bool hasForkId = (rawType & SIGHASH_FORKID) != 0; | |||||
bool hasAnyoneCanPay = (rawType & SIGHASH_ANYONECANPAY) != 0; | |||||
uint32_t noflag = | |||||
sigHashType & ~(SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | |||||
bool isDefined = (noflag != 0) && (noflag <= SIGHASH_SINGLE); | |||||
SigHashType tbase(rawType); | SigHashType tbase(rawType); | ||||
SigHashType tforkid(rawType | SIGHASH_FORKID); | |||||
SigHashType tanyonecanspend(rawType | SIGHASH_ANYONECANPAY); | |||||
SigHashType tboth(rawType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | |||||
// Check deserialization. | // Check deserialization. | ||||
CheckSigHashType(tbase, BaseSigHashType(baseType), | CheckSigHashType(tbase, BaseSigHashType(baseType), isDefined, | ||||
hasSupportedBaseType, forkValue, false, false); | forkValue, hasForkId, hasAnyoneCanPay); | ||||
CheckSigHashType(tforkid, BaseSigHashType(baseType), | |||||
hasSupportedBaseType, forkValue, true, false); | |||||
CheckSigHashType(tanyonecanspend, BaseSigHashType(baseType), | |||||
hasSupportedBaseType, forkValue, false, true); | |||||
CheckSigHashType(tboth, BaseSigHashType(baseType), | |||||
hasSupportedBaseType, forkValue, true, true); | |||||
// Check raw value. | // Check raw value. | ||||
BOOST_CHECK_EQUAL(tbase.getRawSigHashType(), rawType); | BOOST_CHECK_EQUAL(tbase.getRawSigHashType(), rawType); | ||||
BOOST_CHECK_EQUAL(tforkid.getRawSigHashType(), | |||||
rawType | SIGHASH_FORKID); | |||||
BOOST_CHECK_EQUAL(tanyonecanspend.getRawSigHashType(), | |||||
rawType | SIGHASH_ANYONECANPAY); | |||||
BOOST_CHECK_EQUAL(tboth.getRawSigHashType(), | |||||
rawType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | |||||
// Check serialization/deserialization. | // Check serialization/deserialization. | ||||
uint32_t unserializedOutput; | uint32_t unserializedOutput; | ||||
(CDataStream(SER_DISK, 0) << tbase) >> unserializedOutput; | (CDataStream(SER_DISK, 0) << tbase) >> unserializedOutput; | ||||
BOOST_CHECK_EQUAL(unserializedOutput, rawType); | BOOST_CHECK_EQUAL(unserializedOutput, rawType); | ||||
(CDataStream(SER_DISK, 0) << tforkid) >> unserializedOutput; | |||||
BOOST_CHECK_EQUAL(unserializedOutput, rawType | SIGHASH_FORKID); | |||||
(CDataStream(SER_DISK, 0) << tanyonecanspend) >> unserializedOutput; | |||||
BOOST_CHECK_EQUAL(unserializedOutput, | |||||
rawType | SIGHASH_ANYONECANPAY); | |||||
(CDataStream(SER_DISK, 0) << tboth) >> unserializedOutput; | |||||
BOOST_CHECK_EQUAL(unserializedOutput, | |||||
rawType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |