Changeset View
Changeset View
Standalone View
Standalone View
src/test/sighash_tests.cpp
Show First 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) | BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) | ||||
BOOST_AUTO_TEST_CASE(sighash_test) { | BOOST_AUTO_TEST_CASE(sighash_test) { | ||||
SeedInsecureRand(false); | SeedInsecureRand(false); | ||||
#if defined(PRINT_SIGHASH_JSON) | #if defined(PRINT_SIGHASH_JSON) | ||||
std::cout << "[\n"; | std::cout << "[\n"; | ||||
std::cout << "\t[\"raw_transaction, script, input_index, hashType, " | std::cout << "\t[\"raw_transaction, script, input_index, hashType, " | ||||
"signature_hash (result)\"],\n"; | "signature_hash (regular), signature_hash(no forkid), " | ||||
"signature_hash(replay protected)\"],\n"; | |||||
#endif | #endif | ||||
int nRandomTests = 50000; | |||||
#if defined(PRINT_SIGHASH_JSON) | int nRandomTests = 1000; | ||||
nRandomTests = 500; | |||||
#endif | |||||
for (int i = 0; i < nRandomTests; i++) { | for (int i = 0; i < nRandomTests; i++) { | ||||
int nHashType = insecure_rand(); | uint32_t nHashType = insecure_rand(); | ||||
SigHashType sigHashType(nHashType); | SigHashType sigHashType(nHashType); | ||||
// Clear forkid | |||||
nHashType &= ~SIGHASH_FORKID; | |||||
sigHashType = sigHashType.withForkId(false); | |||||
CMutableTransaction txTo; | CMutableTransaction txTo; | ||||
RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); | RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); | ||||
CScript scriptCode; | CScript scriptCode; | ||||
RandomScript(scriptCode); | RandomScript(scriptCode); | ||||
int nIn = InsecureRandRange(txTo.vin.size()); | int nIn = InsecureRandRange(txTo.vin.size()); | ||||
uint256 sh, sho; | uint256 shref = | ||||
sho = SignatureHashOld(scriptCode, CTransaction(txTo), nIn, nHashType); | SignatureHashOld(scriptCode, CTransaction(txTo), nIn, nHashType); | ||||
sh = SignatureHash(scriptCode, CTransaction(txTo), nIn, sigHashType, | uint256 shold = SignatureHash(scriptCode, CTransaction(txTo), nIn, | ||||
Amount(0)); | sigHashType, Amount(0), nullptr, 0); | ||||
BOOST_CHECK(shold == shref); | |||||
// Check the impact of the forkid flag. | |||||
uint256 shreg = SignatureHash(scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType, Amount(0)); | |||||
if (sigHashType.hasForkId()) { | |||||
BOOST_CHECK(nHashType & SIGHASH_FORKID); | |||||
BOOST_CHECK(shreg != shref); | |||||
} else { | |||||
BOOST_CHECK((nHashType & SIGHASH_FORKID) == 0); | |||||
BOOST_CHECK(shreg == shref); | |||||
} | |||||
// Make sure replay protection works as expected. | |||||
uint256 shrep = SignatureHash(scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType, Amount(0), nullptr, | |||||
SCRIPT_ENABLE_SIGHASH_FORKID | | |||||
SCRIPT_ENABLE_REPLAY_PROTECTION); | |||||
uint32_t newForValue = 0xff0000 | ((nHashType >> 8) ^ 0xdead); | |||||
uint256 manualshrep = | |||||
SignatureHash(scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType.withForkValue(newForValue), Amount(0)); | |||||
BOOST_CHECK(shrep == manualshrep); | |||||
// Replay protection works even if the hash is of the form 0xffxxxx | |||||
uint256 shrepff = SignatureHash( | |||||
scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType.withForkValue(newForValue), Amount(0), nullptr, | |||||
SCRIPT_ENABLE_SIGHASH_FORKID | SCRIPT_ENABLE_REPLAY_PROTECTION); | |||||
uint256 manualshrepff = SignatureHash( | |||||
scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType.withForkValue(newForValue ^ 0xdead), Amount(0)); | |||||
BOOST_CHECK(shrepff == manualshrepff); | |||||
uint256 shrepabcdef = SignatureHash( | |||||
scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType.withForkValue(0xabcdef), Amount(0), nullptr, | |||||
SCRIPT_ENABLE_SIGHASH_FORKID | SCRIPT_ENABLE_REPLAY_PROTECTION); | |||||
uint256 manualshrepabcdef = | |||||
SignatureHash(scriptCode, CTransaction(txTo), nIn, | |||||
sigHashType.withForkValue(0xff1342), Amount(0)); | |||||
BOOST_CHECK(shrepabcdef == manualshrepabcdef); | |||||
#if defined(PRINT_SIGHASH_JSON) | #if defined(PRINT_SIGHASH_JSON) | ||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | ||||
ss << txTo; | ss << txTo; | ||||
std::cout << "\t[\""; | std::cout << "\t[\""; | ||||
std::cout << HexStr(ss.begin(), ss.end()) << "\", \""; | std::cout << HexStr(ss.begin(), ss.end()) << "\", \""; | ||||
std::cout << HexStr(scriptCode) << "\", "; | std::cout << HexStr(scriptCode) << "\", "; | ||||
std::cout << nIn << ", "; | std::cout << nIn << ", "; | ||||
std::cout << nHashType << ", \""; | std::cout << int(nHashType) << ", "; | ||||
std::cout << sh.GetHex() << "\"]"; | std::cout << "\"" << shreg.GetHex() << "\", "; | ||||
std::cout << "\"" << shold.GetHex() << "\", "; | |||||
std::cout << "\"" << shrep.GetHex() << "\"]"; | |||||
if (i + 1 != nRandomTests) { | if (i + 1 != nRandomTests) { | ||||
std::cout << ","; | std::cout << ","; | ||||
} | } | ||||
std::cout << "\n"; | std::cout << "\n"; | ||||
#endif | #endif | ||||
BOOST_CHECK(sh == sho); | |||||
} | } | ||||
#if defined(PRINT_SIGHASH_JSON) | #if defined(PRINT_SIGHASH_JSON) | ||||
std::cout << "]\n"; | std::cout << "]\n"; | ||||
#endif | #endif | ||||
} | } | ||||
// Goal: check that SignatureHash generates correct hash | // Goal: check that SignatureHash generates correct hash | ||||
BOOST_AUTO_TEST_CASE(sighash_from_data) { | BOOST_AUTO_TEST_CASE(sighash_from_data) { | ||||
Show All 9 Lines | for (size_t idx = 0; idx < tests.size(); idx++) { | ||||
BOOST_ERROR("Bad test: " << strTest); | BOOST_ERROR("Bad test: " << strTest); | ||||
continue; | continue; | ||||
} | } | ||||
if (test.size() == 1) { | if (test.size() == 1) { | ||||
// comment | // comment | ||||
continue; | continue; | ||||
} | } | ||||
std::string raw_tx, raw_script, sigHashHex; | std::string sigHashRegHex, sigHashOldHex, sigHashRepHex; | ||||
int nIn; | int nIn; | ||||
SigHashType sigHashType; | SigHashType sigHashType; | ||||
uint256 sh; | |||||
CTransactionRef tx; | CTransactionRef tx; | ||||
CScript scriptCode = CScript(); | CScript scriptCode = CScript(); | ||||
try { | try { | ||||
// deserialize test data | // deserialize test data | ||||
raw_tx = test[0].get_str(); | std::string raw_tx = test[0].get_str(); | ||||
raw_script = test[1].get_str(); | std::string raw_script = test[1].get_str(); | ||||
nIn = test[2].get_int(); | nIn = test[2].get_int(); | ||||
sigHashType = SigHashType(test[3].get_int()); | sigHashType = SigHashType(test[3].get_int()); | ||||
sigHashHex = test[4].get_str(); | sigHashRegHex = test[4].get_str(); | ||||
sigHashOldHex = test[5].get_str(); | |||||
sigHashRepHex = test[6].get_str(); | |||||
CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); | CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); | ||||
stream >> tx; | stream >> tx; | ||||
CValidationState state; | CValidationState state; | ||||
BOOST_CHECK_MESSAGE(CheckRegularTransaction(*tx, state), strTest); | BOOST_CHECK_MESSAGE(CheckRegularTransaction(*tx, state), strTest); | ||||
BOOST_CHECK(state.IsValid()); | BOOST_CHECK(state.IsValid()); | ||||
std::vector<uint8_t> raw = ParseHex(raw_script); | std::vector<uint8_t> raw = ParseHex(raw_script); | ||||
scriptCode.insert(scriptCode.end(), raw.begin(), raw.end()); | scriptCode.insert(scriptCode.end(), raw.begin(), raw.end()); | ||||
} catch (...) { | } catch (...) { | ||||
BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); | BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); | ||||
continue; | continue; | ||||
} | } | ||||
sh = SignatureHash(scriptCode, *tx, nIn, sigHashType, Amount(0)); | uint256 shreg = | ||||
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); | SignatureHash(scriptCode, *tx, nIn, sigHashType, Amount(0)); | ||||
BOOST_CHECK_MESSAGE(shreg.GetHex() == sigHashRegHex, strTest); | |||||
uint256 shold = SignatureHash(scriptCode, *tx, nIn, sigHashType, | |||||
Amount(0), nullptr, 0); | |||||
BOOST_CHECK_MESSAGE(shold.GetHex() == sigHashOldHex, strTest); | |||||
uint256 shrep = SignatureHash( | |||||
scriptCode, *tx, nIn, sigHashType, Amount(0), nullptr, | |||||
SCRIPT_ENABLE_SIGHASH_FORKID | SCRIPT_ENABLE_REPLAY_PROTECTION); | |||||
BOOST_CHECK_MESSAGE(shrep.GetHex() == sigHashRepHex, strTest); | |||||
} | } | ||||
} | } | ||||
BOOST_AUTO_TEST_SUITE_END() | BOOST_AUTO_TEST_SUITE_END() |