Add consensus branch ID parameter to SignatureHash, remove SigVersion parameter

We do not need to be able to calculate multiple SignatureHash versions for a
single transaction format; instead, we use the transaction format to determine
the SigVersion.

The consensus branch ID *does* need to be passed in from the outside, as only
the caller knows the context in which the SignatureHash is being calculated
(ie. mempool acceptance vs. block validation).

JoinSplit signature verification has been moved into ContextualCheckTransaction,
where the consensus branch ID can be obtained.

The argument to the sign command for zcash-tx has been modified to take a height
in addition to the optional sigtype flags.
This commit is contained in:
Jack Grigg
2018-02-02 01:49:42 +00:00
parent 6514771a44
commit be12669982
26 changed files with 360 additions and 237 deletions

View File

@@ -232,7 +232,7 @@ bool static CheckMinimalPush(const valtype& data, opcodetype opcode) {
return true;
}
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* serror)
bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, uint32_t consensusBranchId, ScriptError* serror)
{
static const CScriptNum bnZero(0);
static const CScriptNum bnOne(1);
@@ -828,7 +828,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
//serror is set
return false;
}
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, sigversion);
bool fSuccess = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId);
popstack(stack);
popstack(stack);
@@ -886,7 +886,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
}
// Check signature
bool fOk = checker.CheckSig(vchSig, vchPubKey, script, sigversion);
bool fOk = checker.CheckSig(vchSig, vchPubKey, script, consensusBranchId);
if (fOk) {
isig++;
@@ -1083,14 +1083,25 @@ PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo)
hashOutputs = GetOutputsHash(txTo);
}
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
SigVersion SignatureHashVersion(const CTransaction& txTo)
{
if (txTo.fOverwintered) {
return SIGVERSION_OVERWINTER;
} else {
return SIGVERSION_SPROUT;
}
}
uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, const CAmount& amount, uint32_t consensusBranchId, const PrecomputedTransactionData* cache)
{
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
// nIn out of range
throw logic_error("input index is out of range");
}
if (sigversion == SIGVERSION_WITNESS_V0) {
auto sigversion = SignatureHashVersion(txTo);
if (sigversion == SIGVERSION_OVERWINTER) {
uint256 hashPrevouts;
uint256 hashSequence;
uint256 hashOutputs;
@@ -1159,7 +1170,7 @@ bool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned cha
return pubkey.Verify(sighash, vchSig);
}
bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const
{
CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
@@ -1174,7 +1185,7 @@ bool TransactionSignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn
uint256 sighash;
try {
sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata);
sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, this->txdata);
} catch (logic_error ex) {
return false;
}
@@ -1222,7 +1233,7 @@ bool TransactionSignatureChecker::CheckLockTime(const CScriptNum& nLockTime) con
}
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, uint32_t consensusBranchId, ScriptError* serror)
{
set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);
@@ -1231,12 +1242,12 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
}
vector<vector<unsigned char> > stack, stackCopy;
if (!EvalScript(stack, scriptSig, flags, checker, SIGVERSION_BASE, serror))
if (!EvalScript(stack, scriptSig, flags, checker, consensusBranchId, serror))
// serror is set
return false;
if (flags & SCRIPT_VERIFY_P2SH)
stackCopy = stack;
if (!EvalScript(stack, scriptPubKey, flags, checker, SIGVERSION_BASE, serror))
if (!EvalScript(stack, scriptPubKey, flags, checker, consensusBranchId, serror))
// serror is set
return false;
if (stack.empty())
@@ -1263,7 +1274,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne
CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
popstack(stack);
if (!EvalScript(stack, pubKey2, flags, checker, SIGVERSION_BASE, serror))
if (!EvalScript(stack, pubKey2, flags, checker, consensusBranchId, serror))
// serror is set
return false;
if (stack.empty())