Changeset View
Changeset View
Standalone View
Standalone View
src/test/blockstatus_tests.cpp
// Copyright (c) 2018 The Bitcoin developers | // Copyright (c) 2018 The Bitcoin 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 "chain.h" | #include "chain.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(blockstatus_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(blockstatus_tests, BasicTestingSetup) | ||||
static void CheckBlockStatus(const BlockStatus s, BlockValidity validity, | static void CheckBlockStatus(const BlockStatus s, BlockValidity validity, | ||||
bool hasData, bool hasUndo, bool hasFailed, | bool hasData, bool hasUndo, bool hasFailed, | ||||
bool hasFailedParent) { | bool hasFailedParent, bool isParked, | ||||
bool hasParkedParent) { | |||||
BOOST_CHECK(s.getValidity() == validity); | BOOST_CHECK(s.getValidity() == validity); | ||||
BOOST_CHECK_EQUAL(s.hasData(), hasData); | BOOST_CHECK_EQUAL(s.hasData(), hasData); | ||||
BOOST_CHECK_EQUAL(s.hasUndo(), hasUndo); | BOOST_CHECK_EQUAL(s.hasUndo(), hasUndo); | ||||
BOOST_CHECK_EQUAL(s.hasFailed(), hasFailed); | BOOST_CHECK_EQUAL(s.hasFailed(), hasFailed); | ||||
BOOST_CHECK_EQUAL(s.hasFailedParent(), hasFailedParent); | BOOST_CHECK_EQUAL(s.hasFailedParent(), hasFailedParent); | ||||
BOOST_CHECK_EQUAL(s.isInvalid(), hasFailed || hasFailedParent); | BOOST_CHECK_EQUAL(s.isInvalid(), hasFailed || hasFailedParent); | ||||
BOOST_CHECK_EQUAL(s.isParked(), isParked); | |||||
BOOST_CHECK_EQUAL(s.hasParkedParent(), hasParkedParent); | |||||
BOOST_CHECK_EQUAL(s.isOnParkedChain(), isParked || hasParkedParent); | |||||
} | } | ||||
static void CheckAllPermutations(const BlockStatus base, bool hasData, | static void CheckAllPermutations(const BlockStatus base, bool hasData, | ||||
bool hasUndo, bool hasFailed, | bool hasUndo, bool hasFailed, | ||||
bool hasFailedParent) { | bool hasFailedParent, bool isParked, | ||||
bool hasParkedParent) { | |||||
// Check all possible permutations. | // Check all possible permutations. | ||||
std::set<BlockValidity> baseValidities{ | std::set<BlockValidity> baseValidities{ | ||||
BlockValidity::UNKNOWN, BlockValidity::HEADER, | BlockValidity::UNKNOWN, BlockValidity::HEADER, | ||||
BlockValidity::TREE, BlockValidity::TRANSACTIONS, | BlockValidity::TREE, BlockValidity::TRANSACTIONS, | ||||
BlockValidity::CHAIN, BlockValidity::SCRIPTS}; | BlockValidity::CHAIN, BlockValidity::SCRIPTS}; | ||||
for (BlockValidity validity : baseValidities) { | for (BlockValidity validity : baseValidities) { | ||||
const BlockStatus s = base.withValidity(validity); | const BlockStatus s = base.withValidity(validity); | ||||
CheckBlockStatus(s, validity, hasData, hasUndo, hasFailed, | CheckBlockStatus(s, validity, hasData, hasUndo, hasFailed, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
// Clears failure flags. | // Clears failure flags. | ||||
CheckBlockStatus(s.withClearedFailureFlags(), validity, hasData, | CheckBlockStatus(s.withClearedFailureFlags(), validity, hasData, | ||||
hasUndo, false, false); | hasUndo, false, false, isParked, hasParkedParent); | ||||
// Also check all possible alterations. | // Also check all possible alterations. | ||||
CheckBlockStatus(s.withData(true), validity, true, hasUndo, hasFailed, | CheckBlockStatus(s.withData(true), validity, true, hasUndo, hasFailed, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withData(false), validity, false, hasUndo, hasFailed, | CheckBlockStatus(s.withData(false), validity, false, hasUndo, hasFailed, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withUndo(true), validity, hasData, true, hasFailed, | CheckBlockStatus(s.withUndo(true), validity, hasData, true, hasFailed, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withUndo(false), validity, hasData, false, hasFailed, | CheckBlockStatus(s.withUndo(false), validity, hasData, false, hasFailed, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withFailed(true), validity, hasData, hasUndo, true, | CheckBlockStatus(s.withFailed(true), validity, hasData, hasUndo, true, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withFailed(false), validity, hasData, hasUndo, false, | CheckBlockStatus(s.withFailed(false), validity, hasData, hasUndo, false, | ||||
hasFailedParent); | hasFailedParent, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withFailedParent(true), validity, hasData, hasUndo, | CheckBlockStatus(s.withFailedParent(true), validity, hasData, hasUndo, | ||||
hasFailed, true); | hasFailed, true, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withFailedParent(false), validity, hasData, hasUndo, | CheckBlockStatus(s.withFailedParent(false), validity, hasData, hasUndo, | ||||
hasFailed, false); | hasFailed, false, isParked, hasParkedParent); | ||||
CheckBlockStatus(s.withParked(true), validity, hasData, hasUndo, | |||||
hasFailed, hasFailedParent, true, hasParkedParent); | |||||
CheckBlockStatus(s.withParked(false), validity, hasData, hasUndo, | |||||
hasFailed, hasFailedParent, false, hasParkedParent); | |||||
CheckBlockStatus(s.withParkedParent(true), validity, hasData, hasUndo, | |||||
hasFailed, hasFailedParent, isParked, true); | |||||
CheckBlockStatus(s.withParkedParent(false), validity, hasData, hasUndo, | |||||
hasFailed, hasFailedParent, isParked, false); | |||||
for (BlockValidity newValidity : baseValidities) { | for (BlockValidity newValidity : baseValidities) { | ||||
CheckBlockStatus(s.withValidity(newValidity), newValidity, hasData, | CheckBlockStatus(s.withValidity(newValidity), newValidity, hasData, | ||||
hasUndo, hasFailed, hasFailedParent); | hasUndo, hasFailed, hasFailedParent, isParked, | ||||
hasParkedParent); | |||||
} | |||||
} | |||||
} | |||||
static void CheckParked(const BlockStatus s, bool hasData, bool hasUndo, | |||||
bool hasFailed, bool hasFailedParent) { | |||||
std::set<bool> isParkedValues{false, true}; | |||||
std::set<bool> hasParkedParentValues{false, true}; | |||||
for (bool isParked : isParkedValues) { | |||||
for (bool hasParkedParent : hasParkedParentValues) { | |||||
CheckAllPermutations( | |||||
s.withParked(isParked).withParkedParent(hasParkedParent), | |||||
hasData, hasUndo, hasFailed, hasFailedParent, isParked, | |||||
hasParkedParent); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
static void CheckFailures(const BlockStatus s, bool hasData, bool hasUndo) { | static void CheckFailures(const BlockStatus s, bool hasData, bool hasUndo) { | ||||
std::set<bool> hasFailedValues{false, true}; | std::set<bool> hasFailedValues{false, true}; | ||||
std::set<bool> hasFailedParentValues{false, true}; | std::set<bool> hasFailedParentValues{false, true}; | ||||
for (bool hasFailed : hasFailedValues) { | for (bool hasFailed : hasFailedValues) { | ||||
for (bool hasFailedParent : hasFailedParentValues) { | for (bool hasFailedParent : hasFailedParentValues) { | ||||
CheckAllPermutations( | CheckParked( | ||||
s.withFailed(hasFailed).withFailedParent(hasFailedParent), | s.withFailed(hasFailed).withFailedParent(hasFailedParent), | ||||
hasData, hasUndo, hasFailed, hasFailedParent); | hasData, hasUndo, hasFailed, hasFailedParent); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void CheckHaveDataAndUndo(const BlockStatus s) { | static void CheckHaveDataAndUndo(const BlockStatus s) { | ||||
std::set<bool> hasDataValues{false, true}; | std::set<bool> hasDataValues{false, true}; | ||||
std::set<bool> hasUndoValues{false, true}; | std::set<bool> hasUndoValues{false, true}; | ||||
for (bool hasData : hasDataValues) { | for (bool hasData : hasDataValues) { | ||||
for (bool hasUndo : hasUndoValues) { | for (bool hasUndo : hasUndoValues) { | ||||
CheckFailures(s.withData(hasData).withUndo(hasUndo), hasData, | CheckFailures(s.withData(hasData).withUndo(hasUndo), hasData, | ||||
hasUndo); | hasUndo); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(sighash_construction_test) { | BOOST_AUTO_TEST_CASE(sighash_construction_test) { | ||||
// Check default values. | // Check default values. | ||||
CheckBlockStatus(BlockStatus(), BlockValidity::UNKNOWN, false, false, false, | CheckBlockStatus(BlockStatus(), BlockValidity::UNKNOWN, false, false, false, | ||||
false); | false, false, false); | ||||
CheckHaveDataAndUndo(BlockStatus()); | CheckHaveDataAndUndo(BlockStatus()); | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |