diff options
Diffstat (limited to 'src/test/sighash_tests.cpp')
-rw-r--r-- | src/test/sighash_tests.cpp | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index f098d46186..353fd60f7b 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -1,7 +1,22 @@ +// Copyright (c) 2013 The Bitcoin Core developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + #include <boost/test/unit_test.hpp> +#include <iostream> #include "main.h" #include "util.h" +#include "serialize.h" +#include "version.h" +#include "data/sighash.json.h" + +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_utils.h" +#include "json/json_spirit_writer_template.h" + +using namespace json_spirit; +extern Array read_json(const std::string& jsondata); extern uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); @@ -103,18 +118,97 @@ BOOST_AUTO_TEST_SUITE(sighash_tests) BOOST_AUTO_TEST_CASE(sighash_test) { seed_insecure_rand(false); - - for (int i=0; i<50000; i++) { + + #if defined(PRINT_SIGHASH_JSON) + std::cout << "[\n"; + std::cout << "\t[\"raw_transaction, script, input_index, hashType, signature_hash (result)\"],\n"; + #endif + int nRandomTests = 50000; + + #if defined(PRINT_SIGHASH_JSON) + nRandomTests = 500; + #endif + for (int i=0; i<nRandomTests; i++) { int nHashType = insecure_rand(); CTransaction txTo; RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); CScript scriptCode; RandomScript(scriptCode); int nIn = insecure_rand() % txTo.vin.size(); - BOOST_CHECK(SignatureHash(scriptCode, txTo, nIn, nHashType) == - SignatureHashOld(scriptCode, txTo, nIn, nHashType)); + + uint256 sh, sho; + sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType); + sh = SignatureHash(scriptCode, txTo, nIn, nHashType); + #if defined(PRINT_SIGHASH_JSON) + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + ss << txTo; + + std::cout << "\t[\"" ; + std::cout << HexStr(ss.begin(), ss.end()) << "\", \""; + std::cout << HexStr(scriptCode) << "\", "; + std::cout << nIn << ", "; + std::cout << nHashType << ", \""; + std::cout << sho.GetHex() << "\"]"; + if (i+1 != nRandomTests) { + std::cout << ","; + } + std::cout << "\n"; + #endif + BOOST_CHECK(sh == sho); } + #if defined(PRINT_SIGHASH_JSON) + std::cout << "]\n"; + #endif } +// Goal: check that SignatureHash generates correct hash +BOOST_AUTO_TEST_CASE(sighash_from_data) +{ + Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); + + BOOST_FOREACH(Value& tv, tests) + { + Array test = tv.get_array(); + std::string strTest = write_string(tv, false); + if (test.size() < 1) // Allow for extra stuff (useful for comments) + { + BOOST_ERROR("Bad test: " << strTest); + continue; + } + if (test.size() == 1) continue; // comment + + std::string raw_tx, raw_script, sigHashHex; + int nIn, nHashType; + uint256 sh; + CTransaction tx; + CScript scriptCode = CScript(); + + try { + // deserialize test data + raw_tx = test[0].get_str(); + raw_script = test[1].get_str(); + nIn = test[2].get_int(); + nHashType = test[3].get_int(); + sigHashHex = test[4].get_str(); + + uint256 sh; + CDataStream stream(ParseHex(raw_tx), SER_NETWORK, PROTOCOL_VERSION); + stream >> tx; + + CValidationState state; + BOOST_CHECK_MESSAGE(CheckTransaction(tx, state), strTest); + BOOST_CHECK(state.IsValid()); + + std::vector<unsigned char> raw = ParseHex(raw_script); + scriptCode.insert(scriptCode.end(), raw.begin(), raw.end()); + } catch (...) { + BOOST_ERROR("Bad test, couldn't deserialize data: " << strTest); + continue; + } + + sh = SignatureHash(scriptCode, tx, nIn, nHashType); + BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest); + } +} BOOST_AUTO_TEST_SUITE_END() |