Changeset View
Changeset View
Standalone View
Standalone View
src/test/sighash_tests.cpp
Show All 19 Lines | |||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
#include <univalue.h> | #include <univalue.h> | ||||
extern UniValue read_json(const std::string &jsondata); | extern UniValue read_json(const std::string &jsondata); | ||||
// Old script.cpp SignatureHash function | // Old script.cpp SignatureHash function | ||||
static uint256 SignatureHashOld(CScript scriptCode, const CTransaction &txTo, | static uint256 SignatureHashOld(CScript scriptCode, const CTransaction &txTo, | ||||
unsigned int nIn, int nHashType) { | unsigned int nIn, uint32_t nHashType) { | ||||
static const uint256 one(uint256S( | static const uint256 one(uint256S( | ||||
"0000000000000000000000000000000000000000000000000000000000000001")); | "0000000000000000000000000000000000000000000000000000000000000001")); | ||||
if (nIn >= txTo.vin.size()) { | if (nIn >= txTo.vin.size()) { | ||||
printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn); | printf("ERROR: SignatureHash(): nIn=%d out of range\n", nIn); | ||||
return one; | return one; | ||||
} | } | ||||
CMutableTransaction txTmp(txTo); | CMutableTransaction txTmp(txTo); | ||||
// In case concatenating two scripts ends up with two codeseparators, or an | // In case concatenating two scripts ends up with two codeseparators, or an | ||||
// extra one at the end, this prevents all those possible incompatibilities. | // extra one at the end, this prevents all those possible incompatibilities. | ||||
scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); | scriptCode.FindAndDelete(CScript(OP_CODESEPARATOR)); | ||||
// Blank out other inputs' signatures | // Blank out other inputs' signatures | ||||
for (unsigned int i = 0; i < txTmp.vin.size(); i++) | for (auto &in : txTmp.vin) { | ||||
txTmp.vin[i].scriptSig = CScript(); | in.scriptSig = CScript(); | ||||
} | |||||
txTmp.vin[nIn].scriptSig = scriptCode; | txTmp.vin[nIn].scriptSig = scriptCode; | ||||
// Blank out some of the outputs | // Blank out some of the outputs | ||||
if ((nHashType & 0x1f) == SIGHASH_NONE) { | if ((nHashType & 0x1f) == SIGHASH_NONE) { | ||||
// Wildcard payee | // Wildcard payee | ||||
txTmp.vout.clear(); | txTmp.vout.clear(); | ||||
// Let the others update at will | // Let the others update at will | ||||
for (unsigned int i = 0; i < txTmp.vin.size(); i++) | for (size_t i = 0; i < txTmp.vin.size(); i++) { | ||||
if (i != nIn) txTmp.vin[i].nSequence = 0; | if (i != nIn) { | ||||
txTmp.vin[i].nSequence = 0; | |||||
} | |||||
} | |||||
} else if ((nHashType & 0x1f) == SIGHASH_SINGLE) { | } else if ((nHashType & 0x1f) == SIGHASH_SINGLE) { | ||||
// Only lock-in the txout payee at same index as txin | // Only lock-in the txout payee at same index as txin | ||||
unsigned int nOut = nIn; | unsigned int nOut = nIn; | ||||
if (nOut >= txTmp.vout.size()) { | if (nOut >= txTmp.vout.size()) { | ||||
printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut); | printf("ERROR: SignatureHash(): nOut=%d out of range\n", nOut); | ||||
return one; | return one; | ||||
} | } | ||||
txTmp.vout.resize(nOut + 1); | txTmp.vout.resize(nOut + 1); | ||||
for (unsigned int i = 0; i < nOut; i++) | for (size_t i = 0; i < nOut; i++) { | ||||
txTmp.vout[i].SetNull(); | txTmp.vout[i].SetNull(); | ||||
} | |||||
// Let the others update at will | // Let the others update at will | ||||
for (unsigned int i = 0; i < txTmp.vin.size(); i++) | for (size_t i = 0; i < txTmp.vin.size(); i++) { | ||||
if (i != nIn) txTmp.vin[i].nSequence = 0; | if (i != nIn) { | ||||
txTmp.vin[i].nSequence = 0; | |||||
} | |||||
} | |||||
} | } | ||||
// Blank out other inputs completely, not recommended for open transactions | // Blank out other inputs completely, not recommended for open transactions | ||||
if (nHashType & SIGHASH_ANYONECANPAY) { | if (nHashType & SIGHASH_ANYONECANPAY) { | ||||
txTmp.vin[0] = txTmp.vin[nIn]; | txTmp.vin[0] = txTmp.vin[nIn]; | ||||
txTmp.vin.resize(1); | txTmp.vin.resize(1); | ||||
} | } | ||||
// Serialize and hash | // Serialize and hash | ||||
CHashWriter ss(SER_GETHASH, 0); | CHashWriter ss(SER_GETHASH, 0); | ||||
ss << txTmp << nHashType; | ss << txTmp << nHashType; | ||||
return ss.GetHash(); | return ss.GetHash(); | ||||
} | } | ||||
static void RandomScript(CScript &script) { | static void RandomScript(CScript &script) { | ||||
static const opcodetype oplist[] = { | static const opcodetype oplist[] = { | ||||
OP_FALSE, OP_1, OP_2, | OP_FALSE, OP_1, OP_2, | ||||
OP_3, OP_CHECKSIG, OP_IF, | OP_3, OP_CHECKSIG, OP_IF, | ||||
OP_VERIF, OP_RETURN, OP_CODESEPARATOR}; | OP_VERIF, OP_RETURN, OP_CODESEPARATOR}; | ||||
script = CScript(); | script = CScript(); | ||||
int ops = (InsecureRandRange(10)); | int ops = (InsecureRandRange(10)); | ||||
for (int i = 0; i < ops; i++) | for (int i = 0; i < ops; i++) { | ||||
script << oplist[InsecureRandRange(sizeof(oplist) / sizeof(oplist[0]))]; | script << oplist[InsecureRandRange(sizeof(oplist) / sizeof(oplist[0]))]; | ||||
} | } | ||||
} | |||||
static void RandomTransaction(CMutableTransaction &tx, bool fSingle) { | static void RandomTransaction(CMutableTransaction &tx, bool fSingle) { | ||||
tx.nVersion = insecure_rand(); | tx.nVersion = insecure_rand(); | ||||
tx.vin.clear(); | tx.vin.clear(); | ||||
tx.vout.clear(); | tx.vout.clear(); | ||||
tx.nLockTime = (InsecureRandBool()) ? insecure_rand() : 0; | tx.nLockTime = (InsecureRandBool()) ? insecure_rand() : 0; | ||||
int ins = (InsecureRandBits(2)) + 1; | int ins = (InsecureRandBits(2)) + 1; | ||||
int outs = fSingle ? ins : (InsecureRandBits(2)) + 1; | int outs = fSingle ? ins : (InsecureRandBits(2)) + 1; | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
// 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) { | ||||
UniValue tests = read_json( | UniValue tests = read_json( | ||||
std::string(json_tests::sighash, | std::string(json_tests::sighash, | ||||
json_tests::sighash + sizeof(json_tests::sighash))); | json_tests::sighash + sizeof(json_tests::sighash))); | ||||
for (unsigned int idx = 0; idx < tests.size(); idx++) { | for (size_t idx = 0; idx < tests.size(); idx++) { | ||||
UniValue test = tests[idx]; | UniValue test = tests[idx]; | ||||
std::string strTest = test.write(); | std::string strTest = test.write(); | ||||
// Allow for extra stuff (useful for comments) | // Allow for extra stuff (useful for comments) | ||||
if (test.size() < 1) { | if (test.size() < 1) { | ||||
BOOST_ERROR("Bad test: " << strTest); | BOOST_ERROR("Bad test: " << strTest); | ||||
continue; | continue; | ||||
} | } | ||||
if (test.size() == 1) continue; // comment | if (test.size() == 1) { | ||||
// comment | |||||
continue; | |||||
} | |||||
std::string raw_tx, raw_script, sigHashHex; | std::string raw_tx, raw_script, sigHashHex; | ||||
int nIn; | int nIn; | ||||
SigHashType sigHashType; | SigHashType sigHashType; | ||||
uint256 sh; | uint256 sh; | ||||
CTransactionRef tx; | CTransactionRef tx; | ||||
CScript scriptCode = CScript(); | CScript scriptCode = CScript(); | ||||
Show All 28 Lines |