Merge pull request #62 from jc23424/zt-test-fixes

ZT Test Fixes - rebased and squashed
This commit is contained in:
BlueSilver22 2018-02-07 18:27:20 -06:00 committed by GitHub
commit cf7a1643a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 2257 additions and 2225 deletions

2
.gitignore vendored
View File

@ -113,3 +113,5 @@ libzcashconsensus.pc
contrib/debian/files contrib/debian/files
contrib/debian/substvars contrib/debian/substvars
*.gen

View File

@ -1025,7 +1025,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
CScript scriptCode; CScript scriptCode;
uint256 dataToBeSigned; uint256 dataToBeSigned;
try { try {
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL); dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL|SIGHASH_FORKID);
} catch (std::logic_error ex) { } catch (std::logic_error ex) {
return state.DoS(100, error("CheckTransaction(): error computing signature hash"), return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
REJECT_INVALID, "error-computing-signature-hash"); REJECT_INVALID, "error-computing-signature-hash");
@ -1039,6 +1039,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
dataToBeSigned.begin(), 32, dataToBeSigned.begin(), 32,
tx.joinSplitPubKey.begin() tx.joinSplitPubKey.begin()
) != 0) { ) != 0) {
return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"), return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
REJECT_INVALID, "bad-txns-invalid-joinsplit-signature"); REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
} }

View File

@ -810,22 +810,25 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
boost::assign::map_list_of boost::assign::map_list_of
(string("ALL"), int(SIGHASH_ALL)) (string("ALL"), int(SIGHASH_ALL))
(string("ALL|SIGHASH_FORKID"), int(SIGHASH_ALL|SIGHASH_FORKID)) (string("ALL|SIGHASH_FORKID"), int(SIGHASH_ALL|SIGHASH_FORKID))
(string("ALL|SIGHASH_FORKID|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_FORKID)) (string("ALL|ANYONECANPAY|SIGHASH_FORKID"), int(SIGHASH_ALL|SIGHASH_FORKID))
(string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)) (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY))
(string("NONE"), int(SIGHASH_NONE)) (string("NONE"), int(SIGHASH_NONE))
(string("NONE|SIGHASH_FORKID"), int(SIGHASH_NONE|SIGHASH_FORKID)) (string("NONE|SIGHASH_FORKID"), int(SIGHASH_NONE|SIGHASH_FORKID))
(string("NONE|SIGHASH_FORKID|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_FORKID|SIGHASH_ANYONECANPAY)) (string("NONE|ANYONECANPAY|SIGHASH_FORKID"), int(SIGHASH_NONE|SIGHASH_FORKID|SIGHASH_ANYONECANPAY))
(string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)) (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY))
(string("SINGLE"), int(SIGHASH_SINGLE)) (string("SINGLE"), int(SIGHASH_SINGLE))
(string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
(string("SINGLE|SIGHASH_FORKID"), int(SIGHASH_SINGLE|SIGHASH_FORKID)) (string("SINGLE|SIGHASH_FORKID"), int(SIGHASH_SINGLE|SIGHASH_FORKID))
(string("SINGLE|SIGHASH_FORKID|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_FORKID|SIGHASH_ANYONECANPAY)) (string("SINGLE|ANYONECANPAY|SIGHASH_FORKID"), int(SIGHASH_SINGLE|SIGHASH_FORKID|SIGHASH_ANYONECANPAY))
; ;
string strHashType = params[3].get_str(); string strHashType = params[3].get_str();
if (mapSigHashValues.count(strHashType)) if (mapSigHashValues.count(strHashType))
nHashType = mapSigHashValues[strHashType]; nHashType = mapSigHashValues[strHashType];
else else
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
if (!(nHashType & SIGHASH_FORKID))
throw JSONRPCError(RPC_INVALID_PARAMETER, "Signature must use SIGHASH_FORKID");
} }
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);

View File

@ -160,6 +160,13 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
return true; return true;
} }
uint32_t static GetHashType(const valtype &vchSig) {
if (vchSig.size() == 0)
return 0;
// check IsValidSignatureEncoding()'s comment for vchSig format
return vchSig.back();
}
bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) { bool static IsLowDERSignature(const valtype &vchSig, ScriptError* serror) {
if (!IsValidSignatureEncoding(vchSig)) { if (!IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER); return set_error(serror, SCRIPT_ERR_SIG_DER);
@ -185,6 +192,18 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
return true; return true;
} }
bool static UsesForkId(uint32_t nHashType) {
return nHashType & SIGHASH_FORKID;
}
bool static UsesForkId(const valtype &vchSig) {
uint32_t nHashType = GetHashType(vchSig);
return UsesForkId(nHashType);
}
bool static AllowsNonForkId(unsigned int flags) {
return flags & SCRIPT_ALLOW_NON_FORKID;
}
bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
// Empty signature. Not strictly DER encoded, but allowed to provide a // Empty signature. Not strictly DER encoded, but allowed to provide a
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
@ -194,7 +213,6 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc
if (!IsValidSignatureEncoding(vchSig)) { if (!IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER); return set_error(serror, SCRIPT_ERR_SIG_DER);
} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) { } else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
// serror is set
return false; return false;
} }
@ -202,21 +220,12 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc
if(!IsDefinedHashtypeSignature(vchSig)) { if(!IsDefinedHashtypeSignature(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE); return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
} }
unsigned char nHashType = vchSig[vchSig.size() - 1]; bool requiresForkId = !AllowsNonForkId(flags);
bool btcpForkHash = nHashType & SIGHASH_FORKID; bool usesForkId = UsesForkId(vchSig);
bool btcpforkEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID; if (requiresForkId && !usesForkId)
if(!btcpForkHash && btcpforkEnabled) {
return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID); return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID);
} }
return true;
if(btcpForkHash && !btcpforkEnabled) {
return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID);
}
}
return true;
} }
bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
@ -854,7 +863,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
valtype& vchPubKey = stacktop(-1); valtype& vchPubKey = stacktop(-1);
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
//serror is set // serror is set
return false; return false;
} }
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script); bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script);
@ -962,7 +971,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
default: default:
return set_error(serror, SCRIPT_ERR_BAD_OPCODE); return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
} }
// Size limits // Size limits
if (stack.size() + altstack.size() > 1000) if (stack.size() + altstack.size() > 1000)
return set_error(serror, SCRIPT_ERR_STACK_SIZE); return set_error(serror, SCRIPT_ERR_STACK_SIZE);
@ -975,7 +983,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
if (!vfExec.empty()) if (!vfExec.empty())
return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL); return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
return set_success(serror); return set_success(serror);
} }
@ -993,13 +1000,15 @@ private:
const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set
const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE
const bool fHashNone; //! whether the hashtype is SIGHASH_NONE const bool fHashNone; //! whether the hashtype is SIGHASH_NONE
const bool fSighashForkid; //! whether SIGHASH_FORKID is set
public: public:
CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn), txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)), fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE), fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),
fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {} fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE),
fSighashForkid((nHashTypeIn & SIGHASH_FORKID) == SIGHASH_FORKID){}
/** Serialize the passed scriptCode */ /** Serialize the passed scriptCode */
template<typename S> template<typename S>
@ -1080,19 +1089,20 @@ public:
}; };
} // anon namespace } // anon namespace
//
// https://github.com/BTCGPU/BTCGPU/blob/bd007ae79c934f8c99d2247115637f8684ed861a/src/script/interpreter.cpp#L1204
// forkid
//
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{ {
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) { if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
// nIn out of range
throw logic_error("input index is out of range"); throw logic_error("input index is out of range");
} }
// Check for invalid use of SIGHASH_SINGLE // Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) { if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) { if (nIn >= txTo.vout.size()) {
// nOut out of range throw logic_error(" no matching output for SIGHASH_SINGLE");
throw logic_error("no matching output for SIGHASH_SINGLE");
} }
} }
@ -1101,11 +1111,14 @@ uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsig
// Serialize and hash // Serialize and hash
CHashWriter ss(SER_GETHASH, 0); CHashWriter ss(SER_GETHASH, 0);
ss << txTmp << nHashType; ss << txTmp << (nHashType & ~SIGHASH_FORKID);
// This ensures Two Way Replay Protection // This ensures Two Way Replay Protection
if (nHashType & SIGHASH_FORKID) { //
ss << std::string("btcp"); // see instead: https://github.com/BTCGPU/BTCGPU/blob/bd007ae79c934f8c99d2247115637f8684ed861a/src/script/interpreter.cpp#L1276
} //
// if (nHashType & SIGHASH_FORKID) {
// ss << std::string("btcp");
// }
return ss.GetHash(); return ss.GetHash();
} }
@ -1124,7 +1137,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
vector<unsigned char> vchSig(vchSigIn); vector<unsigned char> vchSig(vchSigIn);
if (vchSig.empty()) if (vchSig.empty())
return false; return false;
int nHashType = vchSig.back(); int nHashType = GetHashType(vchSig);
vchSig.pop_back(); vchSig.pop_back();
uint256 sighash; uint256 sighash;
@ -1199,13 +1212,14 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
vector<vector<unsigned char> > stack, stackCopy; vector<vector<unsigned char> > stack, stackCopy;
if (!EvalScript(stack, scriptSig, flags, checker, serror)) if (!EvalScript(stack, scriptSig, flags, checker, serror))
// serror is set return false;
return false;
if (flags & SCRIPT_VERIFY_P2SH) if (flags & SCRIPT_VERIFY_P2SH)
stackCopy = stack; stackCopy = stack;
if (!EvalScript(stack, scriptPubKey, flags, checker, serror)) if (!EvalScript(stack, scriptPubKey, flags, checker, serror))
// serror is set // serror is set
return false; return false;
if (stack.empty()) if (stack.empty())
return set_error(serror, SCRIPT_ERR_EVAL_FALSE); return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
if (CastToBool(stack.back()) == false) if (CastToBool(stack.back()) == false)

View File

@ -32,6 +32,15 @@ enum
SIGHASH_ANYONECANPAY = 0x80, SIGHASH_ANYONECANPAY = 0x80,
}; };
/** Fork IDs **/
enum
{
FORKID_BCC = 0,
FORKID_BTCP = 42,
};
static const int FORKID_IN_USE = FORKID_BTCP;
/** Script verification flags */ /** Script verification flags */
enum enum
{ {
@ -89,9 +98,13 @@ enum
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
// Do we accept signature using SIGHASH_FORKID // Do we accept signature using SIGHASH_FORKID
SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 10), SCRIPT_ENABLE_SIGHASH_FORKID = (1U << 16),
// Allow NON_FORKID in legacy tests and blocks under BTG hard fork height
SCRIPT_ALLOW_NON_FORKID = (1U << 17),
}; };
//
// TODO: add forkId
//
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
class BaseSignatureChecker class BaseSignatureChecker

View File

@ -98,7 +98,6 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
return true; return true;
case TX_SCRIPTHASH: case TX_SCRIPTHASH:
return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet); return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
case TX_MULTISIG: case TX_MULTISIG:
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet)); return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
@ -275,9 +274,9 @@ CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecke
Solver(scriptPubKey, txType, vSolutions); Solver(scriptPubKey, txType, vSolutions);
vector<valtype> stack1; vector<valtype> stack1;
EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC|SCRIPT_ENABLE_SIGHASH_FORKID, BaseSignatureChecker());
vector<valtype> stack2; vector<valtype> stack2;
EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker()); EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC|SCRIPT_ENABLE_SIGHASH_FORKID, BaseSignatureChecker());
return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2); return CombineSignatures(scriptPubKey, checker, txType, vSolutions, stack1, stack2);
} }

View File

@ -38,7 +38,7 @@ class TransactionSignatureCreator : public BaseSignatureCreator {
const TransactionSignatureChecker checker; const TransactionSignatureChecker checker;
public: public:
TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL); TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, int nHashTypeIn=SIGHASH_ALL|SIGHASH_FORKID);
const BaseSignatureChecker& Checker() const { return checker; } const BaseSignatureChecker& Checker() const { return checker; }
bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const; bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const;
}; };

View File

@ -36,6 +36,10 @@ extern unsigned nMaxDatacarrierBytes;
* Failing one of these tests may trigger a DoS ban - see CheckInputs() for * Failing one of these tests may trigger a DoS ban - see CheckInputs() for
* details. * details.
*/ */
//
// TODO https://github.com/BTCGPU/BTCGPU/blob/bd007ae79c934f8c99d2247115637f8684ed861a/src/script/standard.h#L43
//
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID; static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID;
/** /**
@ -76,7 +80,7 @@ public:
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
}; };
/** /**
* A txout script template with a specific destination. It is either: * A txout script template with a specific destination. It is either:
* * CNoDestination: no destination set * * CNoDestination: no destination set
* * CKeyID: TX_PUBKEYHASH destination * * CKeyID: TX_PUBKEYHASH destination

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -28,7 +28,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
CScript CScript
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn) sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
{ {
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL); uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL|SIGHASH_FORKID);
CScript result; CScript result;
result << OP_0; // CHECKMULTISIG bug workaround result << OP_0; // CHECKMULTISIG bug workaround
@ -36,7 +36,7 @@ sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction,
{ {
vector<unsigned char> vchSig; vector<unsigned char> vchSig;
BOOST_CHECK(key.Sign(hash, vchSig)); BOOST_CHECK(key.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL | SIGHASH_FORKID);
result << vchSig; result << vchSig;
} }
return result; return result;
@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL | SIGHASH_FORKID), strprintf("SignSignature %d", i));
} }
} }

View File

@ -86,8 +86,8 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), runtime_error); BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), runtime_error);
BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), runtime_error); BOOST_CHECK_THROW(CallRPC("signrawtransaction ff00"), runtime_error);
BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx)); BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx));
BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY")); BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null NONE|ANYONECANPAY|SIGHASH_FORKID"));
BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY")); BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" [] [] NONE|ANYONECANPAY|SIGHASH_FORKID"));
BOOST_CHECK_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null badenum"), runtime_error); BOOST_CHECK_THROW(CallRPC(string("signrawtransaction ")+rawtx+" null null badenum"), runtime_error);
// Only check failure cases for sendrawtransaction, there's no network to send to... // Only check failure cases for sendrawtransaction, there's no network to send to...
@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(json_parse_errors)
BOOST_AUTO_TEST_CASE(rpc_ban) BOOST_AUTO_TEST_CASE(rpc_ban)
{ {
BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned"))); BOOST_CHECK_NO_THROW(CallRPC(string("clearbanned")));
UniValue r; UniValue r;
BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add"))); BOOST_CHECK_NO_THROW(r = CallRPC(string("setban 127.0.0.0 add")));
BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed BOOST_CHECK_THROW(r = CallRPC(string("setban 127.0.0.0:8334")), runtime_error); //portnumber for setban not allowed
@ -247,7 +247,7 @@ BOOST_AUTO_TEST_CASE(rpc_ban)
adr = find_value(o1, "address"); adr = find_value(o1, "address");
banned_until = find_value(o1, "banned_until"); banned_until = find_value(o1, "banned_until");
BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0"); BOOST_CHECK_EQUAL(adr.get_str(), "127.0.0.0/255.255.255.0");
int64_t now = GetTime(); int64_t now = GetTime();
BOOST_CHECK(banned_until.get_int64() > now); BOOST_CHECK(banned_until.get_int64() > now);
BOOST_CHECK(banned_until.get_int64()-now <= 200); BOOST_CHECK(banned_until.get_int64()-now <= 200);

View File

@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(sign)
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL| SIGHASH_FORKID), strprintf("SignSignature %d", i));
} }
// All of the above should be OK, and the txTos have valid signatures // All of the above should be OK, and the txTos have valid signatures
// Check to make sure signature verification fails if we use the wrong ScriptSig: // Check to make sure signature verification fails if we use the wrong ScriptSig:
@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(sign)
{ {
CScript sigSave = txTo[i].vin[0].scriptSig; CScript sigSave = txTo[i].vin[0].scriptSig;
txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig; txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)(); bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID, false)();
if (i == j) if (i == j)
BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j)); BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
else else
@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(set)
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i)); BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL | SIGHASH_FORKID), strprintf("SignSignature %d", i));
BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i)); BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason), strprintf("txTo[%d].IsStandard", i));
} }
} }
@ -346,7 +346,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txFrom.vout[3].nValue = 4000; txFrom.vout[3].nValue = 4000;
// vout[4] is max sigops: // vout[4] is max sigops:
CScript fifteenSigops; fifteenSigops << OP_1; CScript fifteenSigops;
fifteenSigops << OP_1;
for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++) for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
fifteenSigops << ToByteVector(key[i%3].GetPubKey()); fifteenSigops << ToByteVector(key[i%3].GetPubKey());
fifteenSigops << OP_15 << OP_CHECKMULTISIG; fifteenSigops << OP_15 << OP_CHECKMULTISIG;
@ -376,9 +377,11 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
txTo.vin[i].prevout.n = i; txTo.vin[i].prevout.n = i;
txTo.vin[i].prevout.hash = txFrom.GetHash(); txTo.vin[i].prevout.hash = txFrom.GetHash();
} }
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0));
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1)); BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0,SIGHASH_ALL| SIGHASH_FORKID));
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2)); BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1,SIGHASH_ALL| SIGHASH_FORKID));
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2,SIGHASH_ALL| SIGHASH_FORKID));
// SignSignature doesn't know how to sign these. We're // SignSignature doesn't know how to sign these. We're
// not testing validating signatures, so just create // not testing validating signatures, so just create
// dummy signatures that DO include the correct P2SH scripts: // dummy signatures that DO include the correct P2SH scripts:

View File

@ -34,7 +34,7 @@ using namespace std;
// Uncomment if you want to output updated JSON tests. // Uncomment if you want to output updated JSON tests.
// #define UPDATE_JSON_TESTS // #define UPDATE_JSON_TESTS
static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID;
unsigned int ParseScriptFlags(string strFlags); unsigned int ParseScriptFlags(string strFlags);
string FormatScriptFlags(unsigned int flags); string FormatScriptFlags(unsigned int flags);
@ -234,9 +234,10 @@ public:
return *this; return *this;
} }
TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32) TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL| SIGHASH_FORKID, unsigned int lenR = 32, unsigned int lenS = 32)
{ {
uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType); uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType);
std::vector<unsigned char> vchSig, r, s; std::vector<unsigned char> vchSig, r, s;
uint32_t iter = 0; uint32_t iter = 0;
do { do {
@ -248,6 +249,7 @@ public:
s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]); s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
} while (lenR != r.size() || lenS != s.size()); } while (lenR != r.size() || lenS != s.size());
vchSig.push_back(static_cast<unsigned char>(nHashType)); vchSig.push_back(static_cast<unsigned char>(nHashType));
DoPush(vchSig); DoPush(vchSig);
return *this; return *this;
} }
@ -270,6 +272,7 @@ public:
std::vector<unsigned char> datain = ParseHex(hexin); std::vector<unsigned char> datain = ParseHex(hexin);
std::vector<unsigned char> dataout = ParseHex(hexout); std::vector<unsigned char> dataout = ParseHex(hexout);
assert(pos + datain.size() <= push.size()); assert(pos + datain.size() <= push.size());
BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment); BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
push.erase(push.begin() + pos, push.begin() + pos + datain.size()); push.erase(push.begin() + pos, push.begin() + pos + datain.size());
push.insert(push.begin() + pos, dataout.begin(), dataout.end()); push.insert(push.begin() + pos, dataout.begin(), dataout.end());
@ -339,23 +342,23 @@ BOOST_AUTO_TEST_CASE(script_build)
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK anyonecanpay", 0 "P2PK anyonecanpay", 0
).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY)); ).PushSig(keys.key1, SIGHASH_ALL|SIGHASH_ANYONECANPAY | SIGHASH_FORKID));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK anyonecanpay marked with normal hashtype", 0 "P2PK anyonecanpay marked with normal hashtype", 0
).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_ANYONECANPAY).EditPush(70, "81", "01")); ).PushSig(keys.key1, SIGHASH_ALL|SIGHASH_ANYONECANPAY| SIGHASH_FORKID).EditPush(70, "C1", "03"));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true "P2SH(P2PK)", SCRIPT_VERIFY_P2SH|SCRIPT_ENABLE_SIGHASH_FORKID, true
).PushSig(keys.key0).PushRedeem()); ).PushSig(keys.key0).PushRedeem());
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0C) << OP_CHECKSIG,
"P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH, true "P2SH(P2PK), bad redeemscript", SCRIPT_VERIFY_P2SH |SCRIPT_ENABLE_SIGHASH_FORKID, true
).PushSig(keys.key0).PushRedeem().DamagePush(10)); ).PushSig(keys.key0).PushRedeem().DamagePush(10));
good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0, true
).PushSig(keys.key0).DamagePush(10).PushRedeem()); ).PushSig(keys.key0).DamagePush(10).PushRedeem());
bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << OP_DUP << OP_HASH160 << ToByteVector(keys.pubkey1.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG,
"P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH, true "P2SH(P2PKH), bad sig", SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).PushSig(keys.key0).DamagePush(10).PushRedeem()); ).PushSig(keys.key0).DamagePush(10).PushRedeem());
good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
@ -366,34 +369,34 @@ BOOST_AUTO_TEST_CASE(script_build)
).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0)); ).Num(0).PushSig(keys.key0).PushSig(keys.key1).Num(0));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"P2SH(2-of-3)", SCRIPT_VERIFY_P2SH, true "P2SH(2-of-3)", SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem()); ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
"P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH, true "P2SH(2-of-3), 1 sig", SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).Num(0).PushSig(keys.key1).Num(0).PushRedeem()); ).Num(0).PushSig(keys.key1).Num(0).PushRedeem());
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much R padding", 0 "P2PK with too much R padding", 0
).PushSig(keys.key1, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 31, 32).EditPush(1, "43021F", "44022000"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too much S padding", 0 "P2PK with too much S padding", 0
).PushSig(keys.key1, SIGHASH_ALL).EditPush(1, "44", "45").EditPush(37, "20", "2100")); ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID).EditPush(1, "44", "45").EditPush(37, "20", "2100"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"P2PK with too little R padding", 0 "P2PK with too little R padding", 0
).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with bad sig with too much R padding", 0 "P2PK NOT with bad sig with too much R padding", 0
).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10)); ).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 31, 32).EditPush(1, "43021F", "44022000").DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with too much R padding", 0 "P2PK NOT with too much R padding", 0
).PushSig(keys.key2, SIGHASH_ALL, 31, 32).EditPush(1, "43021F", "44022000")); ).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 31, 32).EditPush(1, "43021F", "44022000"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 1", 0 "BIP66 example 1", 0
).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG << OP_NOT,
"BIP66 example 2", 0 "BIP66 example 2", 0
).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); ).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
"BIP66 example 3", 0 "BIP66 example 3", 0
).Num(0)); ).Num(0));
@ -408,73 +411,73 @@ BOOST_AUTO_TEST_CASE(script_build)
).Num(1)); ).Num(1));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 7", 0 "BIP66 example 7", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 8", 0 "BIP66 example 8", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL| SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220").PushSig(keys.key2));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 9", 0 "BIP66 example 9", 0
).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 10", 0 "BIP66 example 10", 0
).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220")); ).Num(0).Num(0).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220"));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
"BIP66 example 11", 0 "BIP66 example 11", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL| SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220").Num(0));
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT, good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 12", 0 "BIP66 example 12", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID, 33, 32).EditPush(1, "45022100", "440220").Num(0));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with multi-byte hashtype", 0 "P2PK with multi-byte hashtype", 0
).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101")); ).PushSig(keys.key2, SIGHASH_ALL| SIGHASH_FORKID).EditPush(70, "41", "101"));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0 "P2PK with high S but no LOW_S", 0
).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); ).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 32, 33));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S", SCRIPT_VERIFY_LOW_S "P2PK with high S", SCRIPT_VERIFY_LOW_S | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key2, SIGHASH_ALL, 32, 33)); ).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 32, 33));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
"P2PK with hybrid pubkey but no STRICTENC", 0 "P2PK with hybrid pubkey but no STRICTENC", 0
).PushSig(keys.key0, SIGHASH_ALL)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
"P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC "P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key0, SIGHASH_ALL)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with hybrid pubkey but no STRICTENC", 0 "P2PK NOT with hybrid pubkey but no STRICTENC", 0
).PushSig(keys.key0, SIGHASH_ALL)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key0, SIGHASH_ALL)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID).DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); ).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID).DamagePush(10));
good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
).Num(0).PushSig(keys.key1, SIGHASH_ALL)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID));
good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(0).PushSig(keys.key1, SIGHASH_ALL)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID));
bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG,
"1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(0).PushSig(keys.key1, SIGHASH_ALL)); ).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK with undefined hashtype but no STRICTENC", 0 "P2PK with undefined hashtype but no STRICTENC", 0
).PushSig(keys.key1, 5)); ).PushSig(keys.key1, 5));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
"P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC "P2PK with undefined hashtype", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key1, 5)); ).PushSig(keys.key1, 5));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0 "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
).PushSig(keys.key1, 5).DamagePush(10)); ).PushSig(keys.key1, 5).DamagePush(10));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
"P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC "P2PK NOT with invalid sig and undefined hashtype", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
).PushSig(keys.key1, 5).DamagePush(10)); ).PushSig(keys.key1, 5).DamagePush(10));
good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_3 << ToByteVector(keys.pubkey0C) << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_3 << OP_CHECKMULTISIG,
@ -494,7 +497,7 @@ BOOST_AUTO_TEST_CASE(script_build)
"2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0 "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY "2-of-2 with two identical keys and sigs pushed using OP_DUP", SCRIPT_VERIFY_SIGPUSHONLY | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP)); ).Num(0).PushSig(keys.key1).Add(CScript() << OP_DUP));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0 "P2SH(P2PK) with non-push scriptSig but no SIGPUSHONLY", 0
@ -503,23 +506,23 @@ BOOST_AUTO_TEST_CASE(script_build)
"P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY "P2SH(P2PK) with non-push scriptSig", SCRIPT_VERIFY_SIGPUSHONLY
).PushSig(keys.key2).PushRedeem()); ).PushSig(keys.key2).PushRedeem());
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG,
"2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY "2-of-2 with two identical keys and sigs pushed", SCRIPT_VERIFY_SIGPUSHONLY | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(0).PushSig(keys.key1).PushSig(keys.key1)); ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH "P2PK with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(11).PushSig(keys.key0)); ).Num(11).PushSig(keys.key0));
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH "P2PK with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID
).Num(11).PushSig(keys.key0)); ).Num(11).PushSig(keys.key0));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH, true "P2SH with unnecessary input but no CLEANSTACK", SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).Num(11).PushSig(keys.key0).PushRedeem()); ).Num(11).PushSig(keys.key0).PushRedeem());
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true "P2SH with unnecessary input", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).Num(11).PushSig(keys.key0).PushRedeem()); ).Num(11).PushSig(keys.key0).PushRedeem());
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG, good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0) << OP_CHECKSIG,
"P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH, true "P2SH with CLEANSTACK", SCRIPT_VERIFY_CLEANSTACK | SCRIPT_VERIFY_P2SH | SCRIPT_ENABLE_SIGHASH_FORKID, true
).PushSig(keys.key0).PushRedeem()); ).PushSig(keys.key0).PushRedeem());
@ -586,6 +589,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
for (size_t idx = 0; idx < tests.size(); idx++) { for (size_t idx = 0; idx < tests.size(); idx++) {
UniValue test = tests[idx]; UniValue test = tests[idx];
string strTest = test.write(); string strTest = test.write();
if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
{ {
if (test.size() != 1) { if (test.size() != 1) {
@ -661,7 +665,7 @@ BOOST_AUTO_TEST_CASE(script_PushData)
CScript CScript
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction) sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction)
{ {
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL); uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL | SIGHASH_FORKID);
CScript result; CScript result;
// //
@ -677,7 +681,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac
{ {
vector<unsigned char> vchSig; vector<unsigned char> vchSig;
BOOST_CHECK(key.Sign(hash, vchSig)); BOOST_CHECK(key.Sign(hash, vchSig));
vchSig.push_back((unsigned char)SIGHASH_ALL); vchSig.push_back((unsigned char)SIGHASH_ALL | SIGHASH_FORKID);
result << vchSig; result << vchSig;
} }
return result; return result;
@ -787,7 +791,7 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
} }
BOOST_AUTO_TEST_CASE(script_combineSigs) BOOST_AUTO_TEST_CASE(script_combineSigs)
{ {
@ -856,17 +860,17 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
// A couple of partially-signed versions: // A couple of partially-signed versions:
vector<unsigned char> sig1; vector<unsigned char> sig1;
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL); uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL | SIGHASH_FORKID);
BOOST_CHECK(keys[0].Sign(hash1, sig1)); BOOST_CHECK(keys[0].Sign(hash1, sig1));
sig1.push_back(SIGHASH_ALL); sig1.push_back(SIGHASH_ALL| SIGHASH_FORKID);
vector<unsigned char> sig2; vector<unsigned char> sig2;
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE); uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE | SIGHASH_FORKID);
BOOST_CHECK(keys[1].Sign(hash2, sig2)); BOOST_CHECK(keys[1].Sign(hash2, sig2));
sig2.push_back(SIGHASH_NONE); sig2.push_back(SIGHASH_NONE| SIGHASH_FORKID);
vector<unsigned char> sig3; vector<unsigned char> sig3;
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE); uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE | SIGHASH_FORKID);
BOOST_CHECK(keys[2].Sign(hash3, sig3)); BOOST_CHECK(keys[2].Sign(hash3, sig3));
sig3.push_back(SIGHASH_SINGLE); sig3.push_back(SIGHASH_SINGLE | SIGHASH_FORKID);
// Not fussy about order (or even existence) of placeholders or signatures: // Not fussy about order (or even existence) of placeholders or signatures:
CScript partial1a = CScript() << OP_0 << sig1 << OP_0; CScript partial1a = CScript() << OP_0 << sig1 << OP_0;
@ -881,6 +885,7 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
CScript complete23 = CScript() << OP_0 << sig2 << sig3; CScript complete23 = CScript() << OP_0 << sig2 << sig3;
combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b); combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b);
BOOST_CHECK(combined == partial1a); BOOST_CHECK(combined == partial1a);
combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a); combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a);
BOOST_CHECK(combined == complete12); BOOST_CHECK(combined == complete12);

View File

@ -20,6 +20,7 @@
#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
@ -69,7 +70,7 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
} }
// 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 & 0x1f) == SIGHASH_ANYONECANPAY)
{ {
txTmp.vin[0] = txTmp.vin[nIn]; txTmp.vin[0] = txTmp.vin[nIn];
txTmp.vin.resize(1); txTmp.vin.resize(1);
@ -98,8 +99,9 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
tx.vout.clear(); tx.vout.clear();
tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0; tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
int ins = (insecure_rand() % 4) + 1; int ins = (insecure_rand() % 4) + 1;
int outs = fSingle ? ins : (insecure_rand() % 4) + 1; int outs = fSingle ? ins + 1 : (insecure_rand() % 4) + 1;
int joinsplits = (insecure_rand() % 4); int joinsplits = (insecure_rand() % 4);
for (int in = 0; in < ins; in++) { for (int in = 0; in < ins; in++) {
tx.vin.push_back(CTxIn()); tx.vin.push_back(CTxIn());
CTxIn &txin = tx.vin.back(); CTxIn &txin = tx.vin.back();
@ -153,6 +155,16 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
} }
BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup) BOOST_FIXTURE_TEST_SUITE(sighash_tests, BasicTestingSetup)
//
// NB Any change in the data created below will require that you define this,
// and
// $ ./test_bitcoin -t sighash_tests > data/sighash.json
// $ make -C .. bitcoin_test
//
// the first step rebuilds the json, the second step result in
// data/sighash.json.h being recreated and used in a recompile
//
// #define PRINT_SIGHASH_JSON
BOOST_AUTO_TEST_CASE(sighash_test) BOOST_AUTO_TEST_CASE(sighash_test)
{ {
@ -168,16 +180,18 @@ BOOST_AUTO_TEST_CASE(sighash_test)
nRandomTests = 500; nRandomTests = 500;
#endif #endif
for (int i=0; i<nRandomTests; i++) { for (int i=0; i<nRandomTests; i++) {
int nHashType = insecure_rand(); int nHashType = (insecure_rand() % 3) + 1;
CMutableTransaction txTo; CMutableTransaction txTo;
RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE); RandomTransaction(txTo, (nHashType == SIGHASH_SINGLE));
CScript scriptCode; CScript scriptCode;
RandomScript(scriptCode); RandomScript(scriptCode);
int nIn = insecure_rand() % txTo.vin.size(); int nIn = insecure_rand() % txTo.vin.size();
uint256 sh, sho; uint256 sh, sho;
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType); sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
sh = SignatureHash(scriptCode, txTo, nIn, nHashType); sh = SignatureHash(scriptCode, txTo, nIn, nHashType);
#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;

View File

@ -424,7 +424,10 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity)
// Empty output script. // Empty output script.
CScript scriptCode; CScript scriptCode;
CTransaction signTx(newTx); CTransaction signTx(newTx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL | SIGHASH_FORKID); //
// NB SIGHASH_ALL | SIGHASH_FORKID
//
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, 0x41);
assert(crypto_sign_detached(&newTx.joinSplitSig[0], NULL, assert(crypto_sign_detached(&newTx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32, dataToBeSigned.begin(), 32,
@ -439,7 +442,7 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity)
CValidationState state; CValidationState state;
newTx.vjoinsplit.push_back(JSDescription()); newTx.vjoinsplit.push_back(JSDescription());
JSDescription *jsdesc = &newTx.vjoinsplit[0]; JSDescription *jsdesc = &newTx.vjoinsplit[0];
jsdesc->vpub_old = -1; jsdesc->vpub_old = -1;

View File

@ -2829,7 +2829,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
// Empty output script. // Empty output script.
CScript scriptCode; CScript scriptCode;
CTransaction signTx(mtx); CTransaction signTx(mtx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL); uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL | SIGHASH_FORKID);
// Add the signature // Add the signature
assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,