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> | ||||
BOOST_FIXTURE_TEST_SUITE(script_sighashtype_tests, BasicTestingSetup) | #include <set> | ||||
BOOST_AUTO_TEST_CASE(SigHashTypeTests) { | BOOST_FIXTURE_TEST_SUITE(script_sighashtype_tests, BasicTestingSetup) | ||||
BOOST_CHECK(SigHashType().getBaseSigHashType() == BaseSigHashType::ALL); | |||||
BOOST_CHECK(SigHashType(SIGHASH_ALL).getBaseSigHashType() == | static void CheckSigHashType(SigHashType t, BaseSigHashType baseType, | ||||
BaseSigHashType::ALL); | bool hasSupportedBaseType, bool hasForkId, | ||||
bool hasAnyoneCanPay) { | |||||
BOOST_CHECK(t.getBaseType() == baseType); | |||||
BOOST_CHECK_EQUAL(t.hasSupportedBaseType(), hasSupportedBaseType); | |||||
BOOST_CHECK_EQUAL(t.hasForkId(), hasForkId); | |||||
BOOST_CHECK_EQUAL(t.hasAnyoneCanPay(), hasAnyoneCanPay); | |||||
} | |||||
BOOST_CHECK(SigHashType(SIGHASH_NONE).getBaseSigHashType() == | BOOST_AUTO_TEST_CASE(sighash_construction_test) { | ||||
BaseSigHashType::NONE); | // Check default values. | ||||
CheckSigHashType(SigHashType(), BaseSigHashType::ALL, true, false, false); | |||||
// Check all possible permutations. | |||||
std::set<BaseSigHashType> baseTypes{ | |||||
BaseSigHashType::UNSUPPORTED, BaseSigHashType::ALL, | |||||
BaseSigHashType::NONE, BaseSigHashType::SINGLE}; | |||||
std::set<bool> forkIdFlagValues{false, true}; | |||||
std::set<bool> anyoneCanPayFlagValues{false, true}; | |||||
for (BaseSigHashType baseType : baseTypes) { | |||||
for (bool hasForkId : forkIdFlagValues) { | |||||
for (bool hasAnyoneCanPay : anyoneCanPayFlagValues) { | |||||
SigHashType t = SigHashType() | |||||
.withBaseType(baseType) | |||||
.withForkId(hasForkId) | |||||
.withAnyoneCanPay(hasAnyoneCanPay); | |||||
bool hasSupportedBaseType = | |||||
baseType != BaseSigHashType::UNSUPPORTED; | |||||
CheckSigHashType(t, baseType, hasSupportedBaseType, hasForkId, | |||||
hasAnyoneCanPay); | |||||
// Also check all possible alterations. | |||||
CheckSigHashType(t.withForkId(hasForkId), baseType, | |||||
hasSupportedBaseType, hasForkId, | |||||
hasAnyoneCanPay); | |||||
CheckSigHashType(t.withForkId(!hasForkId), baseType, | |||||
hasSupportedBaseType, !hasForkId, | |||||
hasAnyoneCanPay); | |||||
CheckSigHashType(t.withAnyoneCanPay(hasAnyoneCanPay), baseType, | |||||
hasSupportedBaseType, hasForkId, | |||||
hasAnyoneCanPay); | |||||
CheckSigHashType(t.withAnyoneCanPay(!hasAnyoneCanPay), baseType, | |||||
hasSupportedBaseType, hasForkId, | |||||
!hasAnyoneCanPay); | |||||
for (BaseSigHashType newBaseType : baseTypes) { | |||||
bool hasSupportedNewBaseType = | |||||
newBaseType != BaseSigHashType::UNSUPPORTED; | |||||
CheckSigHashType(t.withBaseType(newBaseType), newBaseType, | |||||
hasSupportedNewBaseType, hasForkId, | |||||
hasAnyoneCanPay); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
BOOST_CHECK(SigHashType(SIGHASH_SINGLE).getBaseSigHashType() == | BOOST_AUTO_TEST_CASE(sighash_serialization_test) { | ||||
BaseSigHashType::SINGLE); | // Test all possible base sig hash values | ||||
for (uint32_t baseType = 0; baseType <= 0x1f; baseType++) { | |||||
BOOST_CHECK_EQUAL(SigHashType().hasSupportedBaseSigHashType(), true); | bool hasSupportedBaseType = | ||||
BOOST_CHECK_EQUAL(SigHashType(0).hasSupportedBaseSigHashType(), false); | (baseType != 0) && (baseType <= SIGHASH_SINGLE); | ||||
BOOST_CHECK_EQUAL(SigHashType(SIGHASH_ALL).hasSupportedBaseSigHashType(), | |||||
true); | SigHashType tbase(baseType); | ||||
BOOST_CHECK_EQUAL(SigHashType(SIGHASH_NONE).hasSupportedBaseSigHashType(), | SigHashType tforkid(baseType | SIGHASH_FORKID); | ||||
true); | SigHashType tanyonecanspend(baseType | SIGHASH_ANYONECANPAY); | ||||
BOOST_CHECK_EQUAL(SigHashType(SIGHASH_SINGLE).hasSupportedBaseSigHashType(), | SigHashType tboth(baseType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | ||||
true); | |||||
BOOST_CHECK_EQUAL(SigHashType(4).hasSupportedBaseSigHashType(), false); | // Check deserialization. | ||||
CheckSigHashType(tbase, BaseSigHashType(baseType), hasSupportedBaseType, | |||||
BOOST_CHECK_EQUAL(SigHashType(SIGHASH_ALL | SIGHASH_FORKID).hasForkId(), | false, false); | ||||
true); | CheckSigHashType(tforkid, BaseSigHashType(baseType), | ||||
BOOST_CHECK_EQUAL( | hasSupportedBaseType, true, false); | ||||
SigHashType(SIGHASH_ALL | SIGHASH_FORKID).hasAnyoneCanPay(), false); | CheckSigHashType(tanyonecanspend, BaseSigHashType(baseType), | ||||
hasSupportedBaseType, false, true); | |||||
BOOST_CHECK_EQUAL( | CheckSigHashType(tboth, BaseSigHashType(baseType), hasSupportedBaseType, | ||||
SigHashType(SIGHASH_ALL | SIGHASH_ANYONECANPAY).hasForkId(), false); | true, true); | ||||
BOOST_CHECK_EQUAL( | |||||
SigHashType(SIGHASH_ALL | SIGHASH_ANYONECANPAY).hasAnyoneCanPay(), | // Check raw value. | ||||
true); | BOOST_CHECK_EQUAL(tbase.getRawSigHashType(), baseType); | ||||
BOOST_CHECK_EQUAL(tforkid.getRawSigHashType(), | |||||
BOOST_CHECK(SigHashType() | baseType | SIGHASH_FORKID); | ||||
.withBaseSigHash(BaseSigHashType::ALL) | BOOST_CHECK_EQUAL(tanyonecanspend.getRawSigHashType(), | ||||
.getBaseSigHashType() == BaseSigHashType::ALL); | baseType | SIGHASH_ANYONECANPAY); | ||||
BOOST_CHECK(SigHashType() | BOOST_CHECK_EQUAL(tboth.getRawSigHashType(), | ||||
.withBaseSigHash(BaseSigHashType::NONE) | baseType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | ||||
.getBaseSigHashType() == BaseSigHashType::NONE); | |||||
BOOST_CHECK(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::SINGLE) | |||||
.getBaseSigHashType() == BaseSigHashType::SINGLE); | |||||
BOOST_CHECK_EQUAL(SigHashType().withForkId(true).hasForkId(), true); | |||||
BOOST_CHECK_EQUAL(SigHashType().withAnyoneCanPay(true).hasAnyoneCanPay(), | |||||
true); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withForkId(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_ALL | SIGHASH_FORKID); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::NONE) | |||||
.withForkId(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_NONE | SIGHASH_FORKID); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::SINGLE) | |||||
.withForkId(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_SINGLE | SIGHASH_FORKID); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withAnyoneCanPay(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_ALL | SIGHASH_ANYONECANPAY); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::NONE) | |||||
.withAnyoneCanPay(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_NONE | SIGHASH_ANYONECANPAY); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::SINGLE) | |||||
.withAnyoneCanPay(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_SINGLE | SIGHASH_ANYONECANPAY); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withAnyoneCanPay(true) | |||||
.withForkId(true) | |||||
.getRawSigHashType(), | |||||
SIGHASH_ALL | SIGHASH_ANYONECANPAY | SIGHASH_FORKID); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withForkId(true) | |||||
.withForkId(false) | |||||
.hasForkId(), | |||||
false); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withForkId(false) | |||||
.withForkId(true) | |||||
.hasForkId(), | |||||
true); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withAnyoneCanPay(true) | |||||
.withAnyoneCanPay(false) | |||||
.hasAnyoneCanPay(), | |||||
false); | |||||
BOOST_CHECK_EQUAL(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withAnyoneCanPay(false) | |||||
.withAnyoneCanPay(true) | |||||
.hasAnyoneCanPay(), | |||||
true); | |||||
BOOST_CHECK(SigHashType() | |||||
.withBaseSigHash(BaseSigHashType::ALL) | |||||
.withAnyoneCanPay(true) | |||||
.withForkId(true) | |||||
.withBaseSigHash(BaseSigHashType::NONE) | |||||
.getBaseSigHashType() == BaseSigHashType::NONE); | |||||
// Check serialization/deserialization. | |||||
uint32_t unserializedOutput; | uint32_t unserializedOutput; | ||||
for (int baseSigHash = 0; baseSigHash <= 0x1f; | (CDataStream(SER_DISK, 0) << tbase) >> unserializedOutput; | ||||
baseSigHash++) { // Test all possible base sig hash values | BOOST_CHECK_EQUAL(unserializedOutput, baseType); | ||||
(CDataStream(SER_DISK, 0) << SigHashType(baseSigHash)) >> | (CDataStream(SER_DISK, 0) << tforkid) >> unserializedOutput; | ||||
unserializedOutput; | BOOST_CHECK_EQUAL(unserializedOutput, baseType | SIGHASH_FORKID); | ||||
BOOST_CHECK_EQUAL(unserializedOutput, baseSigHash); | (CDataStream(SER_DISK, 0) << tanyonecanspend) >> unserializedOutput; | ||||
(CDataStream(SER_DISK, 0) | BOOST_CHECK_EQUAL(unserializedOutput, baseType | SIGHASH_ANYONECANPAY); | ||||
<< SigHashType(baseSigHash).withForkId(true)) >> | (CDataStream(SER_DISK, 0) << tboth) >> unserializedOutput; | ||||
unserializedOutput; | |||||
BOOST_CHECK_EQUAL(unserializedOutput, baseSigHash | SIGHASH_FORKID); | |||||
(CDataStream(SER_DISK, 0) | |||||
<< SigHashType(baseSigHash).withAnyoneCanPay(true)) >> | |||||
unserializedOutput; | |||||
BOOST_CHECK_EQUAL(unserializedOutput, | BOOST_CHECK_EQUAL(unserializedOutput, | ||||
baseSigHash | SIGHASH_ANYONECANPAY); | baseType | SIGHASH_FORKID | SIGHASH_ANYONECANPAY); | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |