Merge pull request #62 from jc23424/zt-test-fixes
ZT Test Fixes - rebased and squashed
This commit is contained in:
commit
cf7a1643a4
|
@ -113,3 +113,5 @@ libzcashconsensus.pc
|
|||
|
||||
contrib/debian/files
|
||||
contrib/debian/substvars
|
||||
|
||||
*.gen
|
||||
|
|
|
@ -1025,7 +1025,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
|
|||
CScript scriptCode;
|
||||
uint256 dataToBeSigned;
|
||||
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) {
|
||||
return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
|
||||
REJECT_INVALID, "error-computing-signature-hash");
|
||||
|
@ -1039,6 +1039,7 @@ bool CheckTransactionWithoutProofVerification(const CTransaction& tx, CValidatio
|
|||
dataToBeSigned.begin(), 32,
|
||||
tx.joinSplitPubKey.begin()
|
||||
) != 0) {
|
||||
|
||||
return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
|
||||
REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
|
||||
}
|
||||
|
|
|
@ -810,22 +810,25 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
|||
boost::assign::map_list_of
|
||||
(string("ALL"), int(SIGHASH_ALL))
|
||||
(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("NONE"), int(SIGHASH_NONE))
|
||||
(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("SINGLE"), int(SIGHASH_SINGLE))
|
||||
(string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY))
|
||||
(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();
|
||||
if (mapSigHashValues.count(strHashType))
|
||||
nHashType = mapSigHashValues[strHashType];
|
||||
else
|
||||
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);
|
||||
|
|
|
@ -160,6 +160,13 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
|
|||
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) {
|
||||
if (!IsValidSignatureEncoding(vchSig)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||
|
@ -185,6 +192,18 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
|
|||
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) {
|
||||
// Empty signature. Not strictly DER encoded, but allowed to provide a
|
||||
// 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)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_DER);
|
||||
} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
|
||||
// serror is set
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -202,21 +220,12 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc
|
|||
if(!IsDefinedHashtypeSignature(vchSig)) {
|
||||
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
|
||||
}
|
||||
unsigned char nHashType = vchSig[vchSig.size() - 1];
|
||||
bool btcpForkHash = nHashType & SIGHASH_FORKID;
|
||||
bool btcpforkEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID;
|
||||
|
||||
if(!btcpForkHash && btcpforkEnabled) {
|
||||
bool requiresForkId = !AllowsNonForkId(flags);
|
||||
bool usesForkId = UsesForkId(vchSig);
|
||||
if (requiresForkId && !usesForkId)
|
||||
return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID);
|
||||
}
|
||||
|
||||
if(btcpForkHash && !btcpforkEnabled) {
|
||||
return set_error(serror, SCRIPT_ERR_ILLEGAL_FORKID);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) {
|
||||
//serror is set
|
||||
// serror is set
|
||||
return false;
|
||||
}
|
||||
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script);
|
||||
|
@ -962,7 +971,6 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
|
|||
default:
|
||||
return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
|
||||
}
|
||||
|
||||
// Size limits
|
||||
if (stack.size() + altstack.size() > 1000)
|
||||
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())
|
||||
return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);
|
||||
|
||||
return set_success(serror);
|
||||
}
|
||||
|
||||
|
@ -993,13 +1000,15 @@ private:
|
|||
const bool fAnyoneCanPay; //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set
|
||||
const bool fHashSingle; //! whether the hashtype is SIGHASH_SINGLE
|
||||
const bool fHashNone; //! whether the hashtype is SIGHASH_NONE
|
||||
const bool fSighashForkid; //! whether SIGHASH_FORKID is set
|
||||
|
||||
public:
|
||||
CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) :
|
||||
txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),
|
||||
fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),
|
||||
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 */
|
||||
template<typename S>
|
||||
|
@ -1080,19 +1089,20 @@ public:
|
|||
};
|
||||
|
||||
} // 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)
|
||||
{
|
||||
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
|
||||
// nIn out of range
|
||||
throw logic_error("input index is out of range");
|
||||
}
|
||||
|
||||
// Check for invalid use of SIGHASH_SINGLE
|
||||
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
|
||||
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
|
||||
CHashWriter ss(SER_GETHASH, 0);
|
||||
ss << txTmp << nHashType;
|
||||
ss << txTmp << (nHashType & ~SIGHASH_FORKID);
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1137,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
|
|||
vector<unsigned char> vchSig(vchSigIn);
|
||||
if (vchSig.empty())
|
||||
return false;
|
||||
int nHashType = vchSig.back();
|
||||
int nHashType = GetHashType(vchSig);
|
||||
vchSig.pop_back();
|
||||
|
||||
uint256 sighash;
|
||||
|
@ -1199,13 +1212,14 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
|
|||
|
||||
vector<vector<unsigned char> > stack, stackCopy;
|
||||
if (!EvalScript(stack, scriptSig, flags, checker, serror))
|
||||
// serror is set
|
||||
return false;
|
||||
return false;
|
||||
if (flags & SCRIPT_VERIFY_P2SH)
|
||||
stackCopy = stack;
|
||||
if (!EvalScript(stack, scriptPubKey, flags, checker, serror))
|
||||
// serror is set
|
||||
return false;
|
||||
// serror is set
|
||||
return false;
|
||||
|
||||
|
||||
if (stack.empty())
|
||||
return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
|
||||
if (CastToBool(stack.back()) == false)
|
||||
|
|
|
@ -32,6 +32,15 @@ enum
|
|||
SIGHASH_ANYONECANPAY = 0x80,
|
||||
};
|
||||
|
||||
/** Fork IDs **/
|
||||
enum
|
||||
{
|
||||
FORKID_BCC = 0,
|
||||
FORKID_BTCP = 42,
|
||||
};
|
||||
|
||||
static const int FORKID_IN_USE = FORKID_BTCP;
|
||||
|
||||
/** Script verification flags */
|
||||
enum
|
||||
{
|
||||
|
@ -89,9 +98,13 @@ enum
|
|||
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
|
||||
|
||||
// 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);
|
||||
|
||||
class BaseSignatureChecker
|
||||
|
|
|
@ -98,7 +98,6 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
|
|||
return true;
|
||||
case TX_SCRIPTHASH:
|
||||
return creator.KeyStore().GetCScript(uint160(vSolutions[0]), scriptSigRet);
|
||||
|
||||
case TX_MULTISIG:
|
||||
scriptSigRet << OP_0; // workaround CHECKMULTISIG bug
|
||||
return (SignN(vSolutions, creator, scriptPubKey, scriptSigRet));
|
||||
|
@ -275,9 +274,9 @@ CScript CombineSignatures(const CScript& scriptPubKey, const BaseSignatureChecke
|
|||
Solver(scriptPubKey, txType, vSolutions);
|
||||
|
||||
vector<valtype> stack1;
|
||||
EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
|
||||
EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC|SCRIPT_ENABLE_SIGHASH_FORKID, BaseSignatureChecker());
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class TransactionSignatureCreator : public BaseSignatureCreator {
|
|||
const TransactionSignatureChecker checker;
|
||||
|
||||
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; }
|
||||
bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode) const;
|
||||
};
|
||||
|
|
|
@ -36,6 +36,10 @@ extern unsigned nMaxDatacarrierBytes;
|
|||
* Failing one of these tests may trigger a DoS ban - see CheckInputs() for
|
||||
* 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;
|
||||
|
||||
/**
|
||||
|
|
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
|
@ -28,7 +28,7 @@ BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
|
|||
CScript
|
||||
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;
|
||||
result << OP_0; // CHECKMULTISIG bug workaround
|
||||
|
@ -36,7 +36,7 @@ sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction,
|
|||
{
|
||||
vector<unsigned char> 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;
|
||||
}
|
||||
return result;
|
||||
|
@ -312,7 +312,7 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
|
|||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,8 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
|||
BOOST_CHECK_THROW(CallRPC("signrawtransaction null"), 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+" null null NONE|ANYONECANPAY"));
|
||||
BOOST_CHECK_NO_THROW(CallRPC(string("signrawtransaction ")+rawtx+" [] [] 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|SIGHASH_FORKID"));
|
||||
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...
|
||||
|
|
|
@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(sign)
|
|||
}
|
||||
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
|
||||
// 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;
|
||||
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)
|
||||
BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
|
||||
else
|
||||
|
@ -238,7 +238,7 @@ BOOST_AUTO_TEST_CASE(set)
|
|||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +346,8 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||
txFrom.vout[3].nValue = 4000;
|
||||
|
||||
// vout[4] is max sigops:
|
||||
CScript fifteenSigops; fifteenSigops << OP_1;
|
||||
CScript fifteenSigops;
|
||||
fifteenSigops << OP_1;
|
||||
for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
|
||||
fifteenSigops << ToByteVector(key[i%3].GetPubKey());
|
||||
fifteenSigops << OP_15 << OP_CHECKMULTISIG;
|
||||
|
@ -376,9 +377,11 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||
txTo.vin[i].prevout.n = i;
|
||||
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, 2));
|
||||
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0,SIGHASH_ALL| SIGHASH_FORKID));
|
||||
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
|
||||
// not testing validating signatures, so just create
|
||||
// dummy signatures that DO include the correct P2SH scripts:
|
||||
|
|
|
@ -34,7 +34,7 @@ using namespace std;
|
|||
// Uncomment if you want to output updated 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);
|
||||
string FormatScriptFlags(unsigned int flags);
|
||||
|
@ -234,9 +234,10 @@ public:
|
|||
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);
|
||||
|
||||
std::vector<unsigned char> vchSig, r, s;
|
||||
uint32_t iter = 0;
|
||||
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]]);
|
||||
} while (lenR != r.size() || lenS != s.size());
|
||||
vchSig.push_back(static_cast<unsigned char>(nHashType));
|
||||
|
||||
DoPush(vchSig);
|
||||
return *this;
|
||||
}
|
||||
|
@ -270,6 +272,7 @@ public:
|
|||
std::vector<unsigned char> datain = ParseHex(hexin);
|
||||
std::vector<unsigned char> dataout = ParseHex(hexout);
|
||||
assert(pos + datain.size() <= push.size());
|
||||
|
||||
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.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,
|
||||
"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,
|
||||
"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,
|
||||
"P2SH(P2PK)", SCRIPT_VERIFY_P2SH, true
|
||||
"P2SH(P2PK)", SCRIPT_VERIFY_P2SH|SCRIPT_ENABLE_SIGHASH_FORKID, true
|
||||
).PushSig(keys.key0).PushRedeem());
|
||||
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));
|
||||
|
||||
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
|
||||
).PushSig(keys.key0).DamagePush(10).PushRedeem());
|
||||
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());
|
||||
|
||||
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));
|
||||
|
||||
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());
|
||||
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());
|
||||
|
||||
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1C) << OP_CHECKSIG,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"BIP66 example 3", 0
|
||||
).Num(0));
|
||||
|
@ -408,73 +411,73 @@ BOOST_AUTO_TEST_CASE(script_build)
|
|||
).Num(1));
|
||||
bad.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"P2PK with high S", SCRIPT_VERIFY_LOW_S
|
||||
).PushSig(keys.key2, SIGHASH_ALL, 32, 33));
|
||||
"P2PK with high S", SCRIPT_VERIFY_LOW_S | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).PushSig(keys.key2, SIGHASH_ALL | SIGHASH_FORKID, 32, 33));
|
||||
|
||||
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG,
|
||||
"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,
|
||||
"P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
|
||||
).PushSig(keys.key0, SIGHASH_ALL));
|
||||
"P2PK with hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
|
||||
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
|
||||
"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,
|
||||
"P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC
|
||||
).PushSig(keys.key0, SIGHASH_ALL));
|
||||
"P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).PushSig(keys.key0, SIGHASH_ALL | SIGHASH_FORKID));
|
||||
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT,
|
||||
"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,
|
||||
"P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC
|
||||
).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10));
|
||||
"P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).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,
|
||||
"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,
|
||||
"1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
|
||||
).Num(0).PushSig(keys.key1, SIGHASH_ALL));
|
||||
"1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).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,
|
||||
"1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC
|
||||
).Num(0).PushSig(keys.key1, SIGHASH_ALL));
|
||||
"1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC | SCRIPT_ENABLE_SIGHASH_FORKID
|
||||
).Num(0).PushSig(keys.key1, SIGHASH_ALL | SIGHASH_FORKID));
|
||||
|
||||
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG,
|
||||
"P2PK with undefined hashtype but no STRICTENC", 0
|
||||
).PushSig(keys.key1, 5));
|
||||
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));
|
||||
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG << OP_NOT,
|
||||
"P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
|
||||
).PushSig(keys.key1, 5).DamagePush(10));
|
||||
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));
|
||||
|
||||
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
|
||||
).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,
|
||||
"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));
|
||||
bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
|
||||
"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
|
||||
).PushSig(keys.key2).PushRedeem());
|
||||
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));
|
||||
|
||||
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));
|
||||
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));
|
||||
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());
|
||||
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());
|
||||
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());
|
||||
|
||||
|
||||
|
@ -586,6 +589,7 @@ BOOST_AUTO_TEST_CASE(script_valid)
|
|||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
string strTest = test.write();
|
||||
|
||||
if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
|
||||
{
|
||||
if (test.size() != 1) {
|
||||
|
@ -661,7 +665,7 @@ BOOST_AUTO_TEST_CASE(script_PushData)
|
|||
CScript
|
||||
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;
|
||||
//
|
||||
|
@ -677,7 +681,7 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac
|
|||
{
|
||||
vector<unsigned char> 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;
|
||||
}
|
||||
return result;
|
||||
|
@ -856,17 +860,17 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||
|
||||
// A couple of partially-signed versions:
|
||||
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));
|
||||
sig1.push_back(SIGHASH_ALL);
|
||||
sig1.push_back(SIGHASH_ALL| SIGHASH_FORKID);
|
||||
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));
|
||||
sig2.push_back(SIGHASH_NONE);
|
||||
sig2.push_back(SIGHASH_NONE| SIGHASH_FORKID);
|
||||
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));
|
||||
sig3.push_back(SIGHASH_SINGLE);
|
||||
sig3.push_back(SIGHASH_SINGLE | SIGHASH_FORKID);
|
||||
|
||||
// Not fussy about order (or even existence) of placeholders or signatures:
|
||||
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;
|
||||
|
||||
combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial1b);
|
||||
|
||||
BOOST_CHECK(combined == partial1a);
|
||||
combined = CombineSignatures(scriptPubKey, txTo, 0, partial1a, partial2a);
|
||||
BOOST_CHECK(combined == complete12);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <univalue.h>
|
||||
|
||||
|
||||
extern UniValue read_json(const std::string& jsondata);
|
||||
|
||||
// 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
|
||||
if (nHashType & SIGHASH_ANYONECANPAY)
|
||||
if ((nHashType & 0x1f) == SIGHASH_ANYONECANPAY)
|
||||
{
|
||||
txTmp.vin[0] = txTmp.vin[nIn];
|
||||
txTmp.vin.resize(1);
|
||||
|
@ -98,8 +99,9 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
|
|||
tx.vout.clear();
|
||||
tx.nLockTime = (insecure_rand() % 2) ? insecure_rand() : 0;
|
||||
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);
|
||||
|
||||
for (int in = 0; in < ins; in++) {
|
||||
tx.vin.push_back(CTxIn());
|
||||
CTxIn &txin = tx.vin.back();
|
||||
|
@ -153,6 +155,16 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -168,16 +180,18 @@ BOOST_AUTO_TEST_CASE(sighash_test)
|
|||
nRandomTests = 500;
|
||||
#endif
|
||||
for (int i=0; i<nRandomTests; i++) {
|
||||
int nHashType = insecure_rand();
|
||||
int nHashType = (insecure_rand() % 3) + 1;
|
||||
CMutableTransaction txTo;
|
||||
RandomTransaction(txTo, (nHashType & 0x1f) == SIGHASH_SINGLE);
|
||||
RandomTransaction(txTo, (nHashType == SIGHASH_SINGLE));
|
||||
CScript scriptCode;
|
||||
RandomScript(scriptCode);
|
||||
int nIn = insecure_rand() % txTo.vin.size();
|
||||
|
||||
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;
|
||||
|
|
|
@ -424,7 +424,10 @@ BOOST_AUTO_TEST_CASE(test_simple_joinsplit_invalidity)
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
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,
|
||||
dataToBeSigned.begin(), 32,
|
||||
|
|
|
@ -2829,7 +2829,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
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
|
||||
assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
|
||||
|
|
Loading…
Reference in New Issue