Make `PrecomputedTransactionData` a required argument of `SignatureHash`
The ZIP 244 changes mean that we're going to need to alter every callsite to pass through all of the transparent `CTxOut`s being spent. Given that we need to pass it over to Rust, it makes more sense to just have `PrecomputedTransactionData` be the vehicle for conveying this data across.
This commit is contained in:
parent
3acf7941d6
commit
80f478e67e
|
@ -48,9 +48,11 @@ static void ECDSA(benchmark::State& state)
|
|||
mtx.vout[i].scriptPubKey = CScript() << OP_1;
|
||||
}
|
||||
|
||||
const PrecomputedTransactionData txdata(mtx);
|
||||
|
||||
// sign all inputs
|
||||
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
||||
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, SIGHASH_ALL, consensusBranchId);
|
||||
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, txdata, i, 1000, SIGHASH_ALL, consensusBranchId);
|
||||
assert(hashSigned);
|
||||
}
|
||||
|
||||
|
@ -66,7 +68,7 @@ static void ECDSA(benchmark::State& state)
|
|||
tx.vin[0].scriptSig,
|
||||
scriptPubKey,
|
||||
SCRIPT_VERIFY_P2SH,
|
||||
TransactionSignatureChecker(&tx, 0, 1000),
|
||||
TransactionSignatureChecker(&tx, txdata, 0, 1000),
|
||||
consensusBranchId,
|
||||
&error);
|
||||
}
|
||||
|
|
|
@ -468,6 +468,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput)
|
|||
}
|
||||
|
||||
const CKeyStore& keystore = tempKeystore;
|
||||
const PrecomputedTransactionData txdata(mergedTx);
|
||||
|
||||
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
|
||||
|
||||
|
@ -488,14 +489,14 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& strInput)
|
|||
SignatureData sigdata;
|
||||
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
||||
if (!fHashSingle || (i < mergedTx.vout.size()))
|
||||
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
|
||||
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, txdata, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
|
||||
|
||||
// ... and merge in other signatures:
|
||||
for (const CTransaction& txv : txVariants)
|
||||
sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
|
||||
sigdata = CombineSignatures(prevPubKey, MutableTransactionSignatureChecker(&mergedTx, txdata, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
|
||||
UpdateTransaction(mergedTx, i, sigdata);
|
||||
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, i, amount), consensusBranchId))
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker(&mergedTx, txdata, i, amount), consensusBranchId))
|
||||
fComplete = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,8 @@ void CreateJoinSplitSignature(CMutableTransaction& mtx, uint32_t consensusBranch
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
if (dataToBeSigned == one) {
|
||||
throw std::runtime_error("SignatureHash failed");
|
||||
}
|
||||
|
@ -534,20 +535,21 @@ TEST(ContextualCheckShieldedInputsTest, BadTxnsInvalidJoinsplitSignature) {
|
|||
CMutableTransaction mtx = GetValidTransaction();
|
||||
mtx.joinSplitSig.bytes[0] += 1;
|
||||
CTransaction tx(mtx);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
|
||||
MockCValidationState state;
|
||||
// during initial block download, for transactions being accepted into the
|
||||
// mempool (and thus not mined), DoS ban score should be zero, else 10
|
||||
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return true; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return true; });
|
||||
EXPECT_CALL(state, DoS(10, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return false; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, 0, false, false, [](const Consensus::Params&) { return false; });
|
||||
// for transactions that have been mined in a block, DoS ban score should
|
||||
// always be 100.
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return true; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return true; });
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return false; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, 0, false, true, [](const Consensus::Params&) { return false; });
|
||||
}
|
||||
|
||||
TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) {
|
||||
|
@ -562,11 +564,12 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) {
|
|||
// Create a valid transaction for the Sapling epoch.
|
||||
CMutableTransaction mtx = GetValidTransaction(saplingBranchId);
|
||||
CTransaction tx(mtx);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
|
||||
MockCValidationState state;
|
||||
// Ensure that the transaction validates against Sapling.
|
||||
EXPECT_TRUE(ContextualCheckShieldedInputs(
|
||||
tx, state, orchardAuth, consensus, saplingBranchId, false, false,
|
||||
tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, false,
|
||||
[](const Consensus::Params&) { return false; }));
|
||||
|
||||
// Attempt to validate the inputs against Blossom. We should be notified
|
||||
|
@ -578,7 +581,7 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) {
|
|||
HexInt(saplingBranchId)),
|
||||
false, "")).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckShieldedInputs(
|
||||
tx, state, orchardAuth, consensus, blossomBranchId, false, false,
|
||||
tx, txdata, state, orchardAuth, consensus, blossomBranchId, false, false,
|
||||
[](const Consensus::Params&) { return false; }));
|
||||
|
||||
// Attempt to validate the inputs against Heartwood. All we should learn is
|
||||
|
@ -588,7 +591,7 @@ TEST(ContextualCheckShieldedInputsTest, JoinsplitSignatureDetectsOldBranchId) {
|
|||
10, false, REJECT_INVALID,
|
||||
"bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
EXPECT_FALSE(ContextualCheckShieldedInputs(
|
||||
tx, state, orchardAuth, consensus, heartwoodBranchId, false, false,
|
||||
tx, txdata, state, orchardAuth, consensus, heartwoodBranchId, false, false,
|
||||
[](const Consensus::Params&) { return false; }));
|
||||
}
|
||||
|
||||
|
@ -603,8 +606,9 @@ TEST(ContextualCheckShieldedInputsTest, NonCanonicalEd25519Signature) {
|
|||
// Check that the signature is valid before we add L
|
||||
{
|
||||
CTransaction tx(mtx);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
MockCValidationState state;
|
||||
EXPECT_TRUE(ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, saplingBranchId, false, true));
|
||||
EXPECT_TRUE(ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, true));
|
||||
}
|
||||
|
||||
// Copied from libsodium/crypto_sign/ed25519/ref10/open.c
|
||||
|
@ -622,20 +626,21 @@ TEST(ContextualCheckShieldedInputsTest, NonCanonicalEd25519Signature) {
|
|||
}
|
||||
|
||||
CTransaction tx(mtx);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
|
||||
MockCValidationState state;
|
||||
// during initial block download, for transactions being accepted into the
|
||||
// mempool (and thus not mined), DoS ban score should be zero, else 10
|
||||
EXPECT_CALL(state, DoS(0, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return true; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return true; });
|
||||
EXPECT_CALL(state, DoS(10, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return false; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, false, [](const Consensus::Params&) { return false; });
|
||||
// for transactions that have been mined in a block, DoS ban score should
|
||||
// always be 100.
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return true; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return true; });
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-invalid-joinsplit-signature", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(tx, state, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return false; });
|
||||
ContextualCheckShieldedInputs(tx, txdata, state, orchardAuth, consensus, saplingBranchId, false, true, [](const Consensus::Params&) { return false; });
|
||||
}
|
||||
|
||||
TEST(ChecktransactionTests, OverwinterConstructors) {
|
||||
|
@ -1294,9 +1299,10 @@ TEST(ChecktransactionTests, HeartwoodEnforcesSaplingRulesOnShieldedCoinbase) {
|
|||
|
||||
// Coinbase transaction does not pass shielded input checks, as bindingSig
|
||||
// consensus rule is enforced.
|
||||
PrecomputedTransactionData txdata(tx);
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "bad-txns-sapling-binding-signature-invalid", false, "")).Times(1);
|
||||
ContextualCheckShieldedInputs(
|
||||
tx, state, orchardAuth, chainparams.GetConsensus(), heartwoodBranchId, false, true);
|
||||
tx, txdata, state, orchardAuth, chainparams.GetConsensus(), heartwoodBranchId, false, true);
|
||||
|
||||
RegtestDeactivateHeartwood();
|
||||
}
|
||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -1229,6 +1229,7 @@ bool ContextualCheckTransaction(
|
|||
|
||||
bool ContextualCheckShieldedInputs(
|
||||
const CTransaction& tx,
|
||||
const PrecomputedTransactionData& txdata,
|
||||
CValidationState &state,
|
||||
orchard::AuthValidator& orchardAuth,
|
||||
const Consensus::Params& consensus,
|
||||
|
@ -1259,8 +1260,8 @@ bool ContextualCheckShieldedInputs(
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
try {
|
||||
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
prevDataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, prevConsensusBranchId);
|
||||
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
prevDataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT, SIGHASH_ALL, 0, prevConsensusBranchId, txdata);
|
||||
} catch (std::logic_error ex) {
|
||||
// A logic error should never occur because we pass NOT_AN_INPUT and
|
||||
// SIGHASH_ALL to SignatureHash().
|
||||
|
@ -2001,6 +2002,7 @@ bool AcceptToMemoryPool(
|
|||
// Check shielded input signatures.
|
||||
if (!ContextualCheckShieldedInputs(
|
||||
tx,
|
||||
txdata,
|
||||
state,
|
||||
orchardAuth,
|
||||
chainparams.GetConsensus(),
|
||||
|
@ -2535,7 +2537,7 @@ void UpdateCoins(const CTransaction& tx, CCoinsViewCache& inputs, int nHeight)
|
|||
|
||||
bool CScriptCheck::operator()() {
|
||||
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
|
||||
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, nIn, amount, cacheStore, *txdata), consensusBranchId, &error)) {
|
||||
if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingTransactionSignatureChecker(ptxTo, *txdata, nIn, amount, cacheStore), consensusBranchId, &error)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -3256,7 +3258,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
|
||||
std::vector<CScriptCheck> vChecks;
|
||||
bool fCacheResults = fJustCheck; /* Don't cache results if we're actually connecting blocks (still consult the cache, though) */
|
||||
if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, fCacheResults, txdata[i], chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
|
||||
if (!ContextualCheckInputs(tx, state, view, fExpensiveChecks, flags, fCacheResults, txdata.back(), chainparams.GetConsensus(), consensusBranchId, nScriptCheckThreads ? &vChecks : NULL))
|
||||
return error("ConnectBlock(): CheckInputs on %s failed with %s",
|
||||
tx.GetHash().ToString(), FormatStateMessage(state));
|
||||
control.Add(vChecks);
|
||||
|
@ -3265,6 +3267,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
// Check shielded inputs.
|
||||
if (!ContextualCheckShieldedInputs(
|
||||
tx,
|
||||
txdata.back(),
|
||||
state,
|
||||
orchardAuth,
|
||||
chainparams.GetConsensus(),
|
||||
|
|
|
@ -373,6 +373,7 @@ bool ContextualCheckInputs(const CTransaction& tx, CValidationState &state, cons
|
|||
*/
|
||||
bool ContextualCheckShieldedInputs(
|
||||
const CTransaction& tx,
|
||||
const PrecomputedTransactionData& txdata,
|
||||
CValidationState &state,
|
||||
orchard::AuthValidator& orchardAuth,
|
||||
const Consensus::Params& consensus,
|
||||
|
@ -449,6 +450,8 @@ private:
|
|||
bool cacheStore;
|
||||
uint32_t consensusBranchId;
|
||||
ScriptError error;
|
||||
// We store a pointer instead of a reference here, to allow it to be null for
|
||||
// performance reasons (enabling fast swaps in CCheckQueue::Loop).
|
||||
PrecomputedTransactionData *txdata;
|
||||
|
||||
public:
|
||||
|
|
|
@ -219,9 +219,11 @@ public:
|
|||
uint256 dataToBeSigned;
|
||||
CScript scriptCode;
|
||||
try {
|
||||
PrecomputedTransactionData txdata(mtx);
|
||||
dataToBeSigned = SignatureHash(
|
||||
scriptCode, mtx, NOT_AN_INPUT, SIGHASH_ALL, 0,
|
||||
CurrentEpochBranchId(nHeight, chainparams.GetConsensus()));
|
||||
CurrentEpochBranchId(nHeight, chainparams.GetConsensus()),
|
||||
txdata);
|
||||
} catch (std::logic_error ex) {
|
||||
librustzcash_sapling_proving_ctx_free(ctx);
|
||||
throw ex;
|
||||
|
|
|
@ -1043,6 +1043,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
|||
// Use CTransaction for the constant parts of the
|
||||
// transaction to avoid rehashing.
|
||||
const CTransaction txConst(mergedTx);
|
||||
const PrecomputedTransactionData txdata(txConst);
|
||||
// Sign what we can:
|
||||
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
|
||||
CTxIn& txin = mergedTx.vin[i];
|
||||
|
@ -1057,17 +1058,17 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
|||
SignatureData sigdata;
|
||||
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
||||
if (!fHashSingle || (i < mergedTx.vout.size()))
|
||||
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
|
||||
ProduceSignature(MutableTransactionSignatureCreator(&keystore, &mergedTx, txdata, i, amount, nHashType), prevPubKey, sigdata, consensusBranchId);
|
||||
|
||||
// ... and merge in other signatures:
|
||||
for (const CMutableTransaction& txv : txVariants) {
|
||||
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
|
||||
sigdata = CombineSignatures(prevPubKey, TransactionSignatureChecker(&txConst, txdata, i, amount), sigdata, DataFromTransaction(txv, i), consensusBranchId);
|
||||
}
|
||||
|
||||
UpdateTransaction(mergedTx, i, sigdata);
|
||||
|
||||
ScriptError serror = SCRIPT_ERR_OK;
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, i, amount), consensusBranchId, &serror)) {
|
||||
if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, TransactionSignatureChecker(&txConst, txdata, i, amount), consensusBranchId, &serror)) {
|
||||
TxInErrorToJSON(txin, vErrors, ScriptErrorString(serror));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1179,7 +1179,7 @@ uint256 SignatureHash(
|
|||
int nHashType,
|
||||
const CAmount& amount,
|
||||
uint32_t consensusBranchId,
|
||||
const PrecomputedTransactionData* cache)
|
||||
const PrecomputedTransactionData& txdata)
|
||||
{
|
||||
if (nIn >= txTo.vin.size() && nIn != NOT_AN_INPUT) {
|
||||
// nIn out of range
|
||||
|
@ -1198,30 +1198,16 @@ uint256 SignatureHash(
|
|||
CDataStream sScriptCode(SER_NETWORK, PROTOCOL_VERSION);
|
||||
sScriptCode << *(CScriptBase*)(&scriptCode);
|
||||
|
||||
if (cache) {
|
||||
uint256 hash;
|
||||
zcash_transaction_transparent_signature_digest(
|
||||
cache->preTx.get(),
|
||||
nHashType,
|
||||
nIn,
|
||||
reinterpret_cast<const unsigned char*>(sScriptCode.data()),
|
||||
sScriptCode.size(),
|
||||
amount,
|
||||
hash.begin());
|
||||
return hash;
|
||||
} else {
|
||||
PrecomputedTransactionData local(txTo);
|
||||
uint256 hash;
|
||||
zcash_transaction_transparent_signature_digest(
|
||||
local.preTx.get(),
|
||||
nHashType,
|
||||
nIn,
|
||||
reinterpret_cast<const unsigned char*>(sScriptCode.data()),
|
||||
sScriptCode.size(),
|
||||
amount,
|
||||
hash.begin());
|
||||
return hash;
|
||||
}
|
||||
uint256 hash;
|
||||
zcash_transaction_transparent_signature_digest(
|
||||
txdata.preTx.get(),
|
||||
nHashType,
|
||||
nIn,
|
||||
reinterpret_cast<const unsigned char*>(sScriptCode.data()),
|
||||
sScriptCode.size(),
|
||||
amount,
|
||||
hash.begin());
|
||||
return hash;
|
||||
}
|
||||
} else if (sigversion == SIGVERSION_OVERWINTER || sigversion == SIGVERSION_SAPLING) {
|
||||
uint256 hashPrevouts;
|
||||
|
@ -1232,15 +1218,15 @@ uint256 SignatureHash(
|
|||
uint256 hashShieldedOutputs;
|
||||
|
||||
if (!(nHashType & SIGHASH_ANYONECANPAY)) {
|
||||
hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo);
|
||||
hashPrevouts = txdata.hashPrevouts;
|
||||
}
|
||||
|
||||
if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
|
||||
hashSequence = cache ? cache->hashSequence : GetSequenceHash(txTo);
|
||||
hashSequence = txdata.hashSequence;
|
||||
}
|
||||
|
||||
if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
|
||||
hashOutputs = cache ? cache->hashOutputs : GetOutputsHash(txTo);
|
||||
hashOutputs = txdata.hashOutputs;
|
||||
} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
|
||||
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_OUTPUTS_HASH_PERSONALIZATION);
|
||||
ss << txTo.vout[nIn];
|
||||
|
@ -1248,15 +1234,15 @@ uint256 SignatureHash(
|
|||
}
|
||||
|
||||
if (!txTo.vJoinSplit.empty()) {
|
||||
hashJoinSplits = cache ? cache->hashJoinSplits : GetJoinSplitsHash(txTo);
|
||||
hashJoinSplits = txdata.hashJoinSplits;
|
||||
}
|
||||
|
||||
if (!txTo.vShieldedSpend.empty()) {
|
||||
hashShieldedSpends = cache ? cache->hashShieldedSpends : GetShieldedSpendsHash(txTo);
|
||||
hashShieldedSpends = txdata.hashShieldedSpends;
|
||||
}
|
||||
|
||||
if (!txTo.vShieldedOutput.empty()) {
|
||||
hashShieldedOutputs = cache ? cache->hashShieldedOutputs : GetShieldedOutputsHash(txTo);
|
||||
hashShieldedOutputs = txdata.hashShieldedOutputs;
|
||||
}
|
||||
|
||||
uint32_t leConsensusBranchId = htole32(consensusBranchId);
|
||||
|
|
|
@ -116,7 +116,7 @@ uint256 SignatureHash(
|
|||
int nHashType,
|
||||
const CAmount& amount,
|
||||
uint32_t consensusBranchId,
|
||||
const PrecomputedTransactionData* cache = NULL);
|
||||
const PrecomputedTransactionData& txdata);
|
||||
|
||||
class BaseSignatureChecker
|
||||
{
|
||||
|
@ -144,14 +144,13 @@ private:
|
|||
const CTransaction* txTo;
|
||||
unsigned int nIn;
|
||||
const CAmount amount;
|
||||
const PrecomputedTransactionData* txdata;
|
||||
const PrecomputedTransactionData& txdata;
|
||||
|
||||
protected:
|
||||
virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
|
||||
|
||||
public:
|
||||
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(NULL) {}
|
||||
TransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
||||
TransactionSignatureChecker(const CTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(txdataIn) {}
|
||||
bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, uint32_t consensusBranchId) const;
|
||||
bool CheckLockTime(const CScriptNum& nLockTime) const;
|
||||
};
|
||||
|
@ -162,7 +161,7 @@ private:
|
|||
const CTransaction txTo;
|
||||
|
||||
public:
|
||||
MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, nInIn, amount), txTo(*txToIn) {}
|
||||
MutableTransactionSignatureChecker(const CMutableTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount) : TransactionSignatureChecker(&txTo, txdataIn, nInIn, amount), txTo(*txToIn) {}
|
||||
};
|
||||
|
||||
bool EvalScript(
|
||||
|
|
|
@ -22,7 +22,7 @@ private:
|
|||
bool store;
|
||||
|
||||
public:
|
||||
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {}
|
||||
CachingTransactionSignatureChecker(const CTransaction* txToIn, PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount, bool storeIn) : TransactionSignatureChecker(txToIn, txdataIn, nInIn, amount), store(storeIn) {}
|
||||
|
||||
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@ using namespace std;
|
|||
|
||||
typedef std::vector<unsigned char> valtype;
|
||||
|
||||
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
|
||||
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, const PrecomputedTransactionData& txToDataIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), txToData(txToDataIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, txToDataIn, nIn, amountIn) {}
|
||||
|
||||
bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& address, const CScript& scriptCode, uint32_t consensusBranchId) const
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ bool TransactionSignatureCreator::CreateSig(std::vector<unsigned char>& vchSig,
|
|||
|
||||
uint256 hash;
|
||||
try {
|
||||
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId);
|
||||
hash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, consensusBranchId, txToData);
|
||||
} catch (logic_error ex) {
|
||||
return false;
|
||||
}
|
||||
|
@ -172,6 +172,7 @@ bool SignSignature(
|
|||
const CKeyStore &keystore,
|
||||
const CScript& fromPubKey,
|
||||
CMutableTransaction& txTo,
|
||||
const PrecomputedTransactionData& txToData,
|
||||
unsigned int nIn,
|
||||
const CAmount& amount,
|
||||
int nHashType,
|
||||
|
@ -180,7 +181,7 @@ bool SignSignature(
|
|||
assert(nIn < txTo.vin.size());
|
||||
|
||||
CTransaction txToConst(txTo);
|
||||
TransactionSignatureCreator creator(&keystore, &txToConst, nIn, amount, nHashType);
|
||||
TransactionSignatureCreator creator(&keystore, &txToConst, txToData, nIn, amount, nHashType);
|
||||
|
||||
SignatureData sigdata;
|
||||
bool ret = ProduceSignature(creator, fromPubKey, sigdata, consensusBranchId);
|
||||
|
@ -192,6 +193,7 @@ bool SignSignature(
|
|||
const CKeyStore &keystore,
|
||||
const CTransaction& txFrom,
|
||||
CMutableTransaction& txTo,
|
||||
const PrecomputedTransactionData& txToData,
|
||||
unsigned int nIn,
|
||||
int nHashType,
|
||||
uint32_t consensusBranchId)
|
||||
|
@ -201,7 +203,7 @@ bool SignSignature(
|
|||
assert(txin.prevout.n < txFrom.vout.size());
|
||||
const CTxOut& txout = txFrom.vout[txin.prevout.n];
|
||||
|
||||
return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, consensusBranchId);
|
||||
return SignSignature(keystore, txout.scriptPubKey, txTo, txToData, nIn, txout.nValue, nHashType, consensusBranchId);
|
||||
}
|
||||
|
||||
static vector<valtype> CombineMultisig(const CScript& scriptPubKey, const BaseSignatureChecker& checker,
|
||||
|
|
|
@ -33,13 +33,14 @@ public:
|
|||
/** A signature creator for transactions. */
|
||||
class TransactionSignatureCreator : public BaseSignatureCreator {
|
||||
const CTransaction* txTo;
|
||||
const PrecomputedTransactionData& txToData;
|
||||
unsigned int nIn;
|
||||
int nHashType;
|
||||
CAmount amount;
|
||||
const TransactionSignatureChecker checker;
|
||||
|
||||
public:
|
||||
TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
|
||||
TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, const PrecomputedTransactionData& txToDataIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn=SIGHASH_ALL);
|
||||
const BaseSignatureChecker& Checker() const { return checker; }
|
||||
bool CreateSig(std::vector<unsigned char>& vchSig, const CKeyID& keyid, const CScript& scriptCode, uint32_t consensusBranchId) const;
|
||||
};
|
||||
|
@ -48,7 +49,7 @@ class MutableTransactionSignatureCreator : public TransactionSignatureCreator {
|
|||
CTransaction tx;
|
||||
|
||||
public:
|
||||
MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, nInIn, amount, nHashTypeIn), tx(*txToIn) {}
|
||||
MutableTransactionSignatureCreator(const CKeyStore* keystoreIn, const CMutableTransaction* txToIn, const PrecomputedTransactionData& txdataIn, unsigned int nInIn, const CAmount& amount, int nHashTypeIn) : TransactionSignatureCreator(keystoreIn, &tx, txdataIn, nInIn, amount, nHashTypeIn), tx(*txToIn) {}
|
||||
};
|
||||
|
||||
/** A signature creator that just produces 72-byte empty signatures. */
|
||||
|
@ -74,6 +75,7 @@ bool SignSignature(
|
|||
const CKeyStore &keystore,
|
||||
const CScript& fromPubKey,
|
||||
CMutableTransaction& txTo,
|
||||
const PrecomputedTransactionData& txToData,
|
||||
unsigned int nIn,
|
||||
const CAmount& amount,
|
||||
int nHashType,
|
||||
|
@ -82,6 +84,7 @@ bool SignSignature(
|
|||
const CKeyStore& keystore,
|
||||
const CTransaction& txFrom,
|
||||
CMutableTransaction& txTo,
|
||||
const PrecomputedTransactionData& txToData,
|
||||
unsigned int nIn,
|
||||
int nHashType,
|
||||
uint32_t consensusBranchId);
|
||||
|
|
|
@ -145,7 +145,7 @@ int zcash_script_verify_precomputed(
|
|||
preTx->tx.vin[nIn].scriptSig,
|
||||
CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen),
|
||||
flags,
|
||||
TransactionSignatureChecker(&preTx->tx, nIn, amount, preTx->txdata),
|
||||
TransactionSignatureChecker(&preTx->tx, preTx->txdata, nIn, amount),
|
||||
consensusBranchId,
|
||||
NULL);
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ int zcash_script_verify(
|
|||
tx.vin[nIn].scriptSig,
|
||||
CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen),
|
||||
flags,
|
||||
TransactionSignatureChecker(&tx, nIn, amount, txdata),
|
||||
TransactionSignatureChecker(&tx, txdata, nIn, amount),
|
||||
consensusBranchId,
|
||||
NULL);
|
||||
} catch (const std::exception&) {
|
||||
|
|
|
@ -157,7 +157,8 @@ BOOST_DATA_TEST_CASE(DoS_mapOrphans, boost::unit_test::data::xrange(static_cast<
|
|||
tx.vout.resize(1);
|
||||
tx.vout[0].nValue = 1*CENT;
|
||||
tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID());
|
||||
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
SignSignature(keystore, txPrev, tx, txdata, 0, SIGHASH_ALL, consensusBranchId);
|
||||
|
||||
AddOrphanTx(tx, i);
|
||||
}
|
||||
|
@ -177,7 +178,8 @@ BOOST_DATA_TEST_CASE(DoS_mapOrphans, boost::unit_test::data::xrange(static_cast<
|
|||
tx.vin[j].prevout.n = j;
|
||||
tx.vin[j].prevout.hash = txPrev.GetHash();
|
||||
}
|
||||
SignSignature(keystore, txPrev, tx, 0, SIGHASH_ALL, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
SignSignature(keystore, txPrev, tx, txdata, 0, SIGHASH_ALL, consensusBranchId);
|
||||
// Re-use same signature for other inputs
|
||||
// (they don't have to be valid for this test)
|
||||
for (unsigned int j = 1; j < tx.vin.size(); j++)
|
||||
|
|
|
@ -23,9 +23,9 @@ using namespace std;
|
|||
BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
|
||||
|
||||
CScript
|
||||
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn, uint32_t consensusBranchId)
|
||||
sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, const PrecomputedTransactionData& txdata, int whichIn, uint32_t consensusBranchId)
|
||||
{
|
||||
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, consensusBranchId);
|
||||
uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
CScript result;
|
||||
result << OP_0; // CHECKMULTISIG bug workaround
|
||||
|
@ -71,6 +71,7 @@ BOOST_DATA_TEST_CASE(multisig_verify, boost::unit_test::data::xrange(static_cast
|
|||
txFrom.vout[2].nValue = 10;
|
||||
|
||||
CMutableTransaction txTo[3]; // Spending transaction
|
||||
std::vector<PrecomputedTransactionData> txdata;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
txTo[i].vin.resize(1);
|
||||
|
@ -78,6 +79,7 @@ BOOST_DATA_TEST_CASE(multisig_verify, boost::unit_test::data::xrange(static_cast
|
|||
txTo[i].vin[0].prevout.n = i;
|
||||
txTo[i].vin[0].prevout.hash = txFrom.GetHash();
|
||||
txTo[i].vout[0].nValue = 1;
|
||||
txdata.push_back(PrecomputedTransactionData(txTo[i]));
|
||||
}
|
||||
|
||||
vector<CKey> keys;
|
||||
|
@ -86,21 +88,21 @@ BOOST_DATA_TEST_CASE(multisig_verify, boost::unit_test::data::xrange(static_cast
|
|||
// Test a AND b:
|
||||
keys.assign(1,key[0]);
|
||||
keys.push_back(key[1]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err));
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], txdata[0], 0, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], txdata[0], 0, amount), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
keys.assign(1,key[i]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err), strprintf("a&b 1: %d", i));
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], txdata[0], 0, consensusBranchId);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], txdata[0], 0, amount), consensusBranchId, &err), strprintf("a&b 1: %d", i));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
||||
|
||||
keys.assign(1,key[1]);
|
||||
keys.push_back(key[i]);
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], 0, consensusBranchId);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), consensusBranchId, &err), strprintf("a&b 2: %d", i));
|
||||
s = sign_multisig(a_and_b, keys, txTo[0], txdata[0], 0, consensusBranchId);
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], txdata[0], 0, amount), consensusBranchId, &err), strprintf("a&b 2: %d", i));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
}
|
||||
|
||||
|
@ -108,21 +110,21 @@ BOOST_DATA_TEST_CASE(multisig_verify, boost::unit_test::data::xrange(static_cast
|
|||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
keys.assign(1,key[i]);
|
||||
s = sign_multisig(a_or_b, keys, txTo[1], 0, consensusBranchId);
|
||||
s = sign_multisig(a_or_b, keys, txTo[1], txdata[1], 0, consensusBranchId);
|
||||
if (i == 0 || i == 1)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i));
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], txdata[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i));
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], txdata[1], 0, amount), consensusBranchId, &err), strprintf("a|b: %d", i));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
}
|
||||
}
|
||||
s.clear();
|
||||
s << OP_0 << OP_1;
|
||||
BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), consensusBranchId, &err));
|
||||
BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], txdata[1], 0, amount), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
|
||||
|
||||
|
||||
|
@ -131,15 +133,15 @@ BOOST_DATA_TEST_CASE(multisig_verify, boost::unit_test::data::xrange(static_cast
|
|||
{
|
||||
keys.assign(1,key[i]);
|
||||
keys.push_back(key[j]);
|
||||
s = sign_multisig(escrow, keys, txTo[2], 0, consensusBranchId);
|
||||
s = sign_multisig(escrow, keys, txTo[2], txdata[2], 0, consensusBranchId);
|
||||
if (i < j && i < 3 && j < 3)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), consensusBranchId, &err), strprintf("escrow 1: %d %d", i, j));
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], txdata[2], 0, amount), consensusBranchId, &err), strprintf("escrow 1: %d %d", i, j));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), consensusBranchId, &err), strprintf("escrow 2: %d %d", i, j));
|
||||
BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], txdata[2], 0, amount), consensusBranchId, &err), strprintf("escrow 2: %d %d", i, j));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +217,7 @@ BOOST_DATA_TEST_CASE(multisig_Sign, boost::unit_test::data::xrange(static_cast<i
|
|||
txFrom.vout[2].nValue = 10;
|
||||
|
||||
CMutableTransaction txTo[3]; // Spending transaction
|
||||
std::vector<PrecomputedTransactionData> txdata;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
txTo[i].vin.resize(1);
|
||||
|
@ -222,11 +225,12 @@ BOOST_DATA_TEST_CASE(multisig_Sign, boost::unit_test::data::xrange(static_cast<i
|
|||
txTo[i].vin[0].prevout.n = i;
|
||||
txTo[i].vin[0].prevout.hash = txFrom.GetHash();
|
||||
txTo[i].vout[0].nValue = 1;
|
||||
txdata.push_back(PrecomputedTransactionData(txTo[i]));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i));
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], txdata[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, Scri
|
|||
txTo.vin[0].scriptSig = scriptSig;
|
||||
txTo.vout[0].nValue = 1;
|
||||
|
||||
return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue), consensusBranchId, &err);
|
||||
const PrecomputedTransactionData txdata(txTo);
|
||||
return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, txdata, 0, txFrom.vout[0].nValue), consensusBranchId, &err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,6 +99,7 @@ BOOST_DATA_TEST_CASE(sign, boost::unit_test::data::xrange(static_cast<int>(Conse
|
|||
BOOST_CHECK(IsStandardTx(txFrom, reason, Params()));
|
||||
|
||||
CMutableTransaction txTo[8]; // Spending transactions
|
||||
std::vector<PrecomputedTransactionData> txToData;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
txTo[i].vin.resize(1);
|
||||
|
@ -106,10 +108,11 @@ BOOST_DATA_TEST_CASE(sign, boost::unit_test::data::xrange(static_cast<int>(Conse
|
|||
txTo[i].vin[0].prevout.hash = txFrom.GetHash();
|
||||
txTo[i].vout[0].nValue = 1;
|
||||
BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
|
||||
txToData.push_back(PrecomputedTransactionData(txTo[i]));
|
||||
}
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i));
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], txToData[i], 0, SIGHASH_ALL, consensusBranchId), 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:
|
||||
|
@ -199,6 +202,7 @@ BOOST_DATA_TEST_CASE(set, boost::unit_test::data::xrange(static_cast<int>(Consen
|
|||
BOOST_CHECK(IsStandardTx(txFrom, reason, Params()));
|
||||
|
||||
CMutableTransaction txTo[4]; // Spending transactions
|
||||
std::vector<PrecomputedTransactionData> txToData;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
txTo[i].vin.resize(1);
|
||||
|
@ -208,10 +212,11 @@ BOOST_DATA_TEST_CASE(set, boost::unit_test::data::xrange(static_cast<int>(Consen
|
|||
txTo[i].vout[0].nValue = 1*CENT;
|
||||
txTo[i].vout[0].scriptPubKey = inner[i];
|
||||
BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
|
||||
txToData.push_back(PrecomputedTransactionData(txTo[i]));
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i));
|
||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], txToData[i], 0, SIGHASH_ALL, consensusBranchId), strprintf("SignSignature %d", i));
|
||||
BOOST_CHECK_MESSAGE(IsStandardTx(txTo[i], reason, Params()), strprintf("txTo[%d].IsStandard", i));
|
||||
}
|
||||
}
|
||||
|
@ -347,9 +352,10 @@ BOOST_DATA_TEST_CASE(AreInputsStandard, boost::unit_test::data::xrange(static_ca
|
|||
txTo.vin[i].prevout.n = i;
|
||||
txTo.vin[i].prevout.hash = txFrom.GetHash();
|
||||
}
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId));
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 1, SIGHASH_ALL, consensusBranchId));
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, 2, SIGHASH_ALL, consensusBranchId));
|
||||
const PrecomputedTransactionData txToData(txTo);
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId));
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, txToData, 1, SIGHASH_ALL, consensusBranchId));
|
||||
BOOST_CHECK(SignSignature(keystore, txFrom, txTo, txToData, 2, SIGHASH_ALL, consensusBranchId));
|
||||
// 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:
|
||||
|
|
|
@ -78,8 +78,9 @@ void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, ui
|
|||
ScriptError err;
|
||||
CMutableTransaction txCredit = BuildCreditingTransaction(scriptPubKey);
|
||||
CMutableTransaction tx = BuildSpendingTransaction(scriptSig, txCredit);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
CMutableTransaction tx2 = tx;
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, 0, txCredit.vout[0].nValue), consensusBranchId, &err) == expect, message);
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, MutableTransactionSignatureChecker(&tx, txdata, 0, txCredit.vout[0].nValue), consensusBranchId, &err) == expect, message);
|
||||
BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message);
|
||||
#if defined(HAVE_SCRIPT_LIB)
|
||||
CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
@ -230,7 +231,8 @@ public:
|
|||
|
||||
TestBuilder& PushSig(const CKey& key, int nHashType = SIGHASH_ALL, unsigned int lenR = 32, unsigned int lenS = 32)
|
||||
{
|
||||
uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType, 0, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(spendTx);
|
||||
uint256 hash = SignatureHash(scriptPubKey, spendTx, 0, nHashType, 0, consensusBranchId, txdata);
|
||||
std::vector<unsigned char> vchSig, r, s;
|
||||
uint32_t iter = 0;
|
||||
do {
|
||||
|
@ -664,9 +666,9 @@ BOOST_DATA_TEST_CASE(script_PushData, boost::unit_test::data::xrange(static_cast
|
|||
}
|
||||
|
||||
CScript
|
||||
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, uint32_t consensusBranchId)
|
||||
sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, const PrecomputedTransactionData& txdata, uint32_t consensusBranchId)
|
||||
{
|
||||
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, consensusBranchId);
|
||||
uint256 hash = SignatureHash(scriptPubKey, transaction, 0, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
CScript result;
|
||||
//
|
||||
|
@ -688,11 +690,11 @@ sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transac
|
|||
return result;
|
||||
}
|
||||
CScript
|
||||
sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction, uint32_t consensusBranchId)
|
||||
sign_multisig(CScript scriptPubKey, const CKey &key, CTransaction transaction, const PrecomputedTransactionData& txdata, uint32_t consensusBranchId)
|
||||
{
|
||||
std::vector<CKey> keys;
|
||||
keys.push_back(key);
|
||||
return sign_multisig(scriptPubKey, keys, transaction, consensusBranchId);
|
||||
return sign_multisig(scriptPubKey, keys, transaction, txdata, consensusBranchId);
|
||||
}
|
||||
|
||||
// Parameterized testing over consensus branch ids
|
||||
|
@ -710,20 +712,21 @@ BOOST_DATA_TEST_CASE(script_CHECKMULTISIG12, boost::unit_test::data::xrange(stat
|
|||
|
||||
CMutableTransaction txFrom12 = BuildCreditingTransaction(scriptPubKey12);
|
||||
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
|
||||
const PrecomputedTransactionData txdata12(txTo12);
|
||||
|
||||
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12, txdata12, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, txdata12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
txTo12.vout[0].nValue = 2;
|
||||
BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, txdata12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12, txdata12, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, txdata12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
|
||||
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12, txdata12, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, txdata12, 0, txFrom12.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
}
|
||||
|
||||
|
@ -743,58 +746,59 @@ BOOST_DATA_TEST_CASE(script_CHECKMULTISIG23, boost::unit_test::data::xrange(stat
|
|||
|
||||
CMutableTransaction txFrom23 = BuildCreditingTransaction(scriptPubKey23);
|
||||
CMutableTransaction txTo23 = BuildSpendingTransaction(CScript(), txFrom23);
|
||||
const PrecomputedTransactionData txdata23(txTo23);
|
||||
|
||||
std::vector<CKey> keys;
|
||||
keys.push_back(key1); keys.push_back(key2);
|
||||
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key1); keys.push_back(key3);
|
||||
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key3);
|
||||
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
|
||||
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
|
||||
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
|
||||
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
|
||||
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
keys.clear();
|
||||
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
|
||||
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
|
||||
|
||||
keys.clear(); // Must have signatures
|
||||
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23, txdata23, consensusBranchId);
|
||||
BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, txdata23, 0, txFrom23.vout[0].nValue), consensusBranchId, &err));
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
|
||||
}
|
||||
|
||||
|
@ -818,65 +822,66 @@ BOOST_DATA_TEST_CASE(script_combineSigs, boost::unit_test::data::xrange(static_c
|
|||
|
||||
CMutableTransaction txFrom = BuildCreditingTransaction(GetScriptForDestination(keys[0].GetPubKey().GetID()));
|
||||
CMutableTransaction txTo = BuildSpendingTransaction(CScript(), txFrom);
|
||||
const PrecomputedTransactionData txToData(txTo);
|
||||
CScript& scriptPubKey = txFrom.vout[0].scriptPubKey;
|
||||
CScript& scriptSig = txTo.vin[0].scriptSig;
|
||||
|
||||
SignatureData empty;
|
||||
SignatureData combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, empty, consensusBranchId);
|
||||
SignatureData combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), empty, empty, consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig.empty());
|
||||
|
||||
// Single signature case:
|
||||
SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId); // changes scriptSig
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId); // changes scriptSig
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
CScript scriptSigCopy = scriptSig;
|
||||
// Signing again will give a different, valid signature:
|
||||
SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig);
|
||||
|
||||
// P2SH, single-signature case:
|
||||
CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
|
||||
keystore.AddCScript(pkSingle);
|
||||
scriptPubKey = GetScriptForDestination(CScriptID(pkSingle));
|
||||
SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
scriptSigCopy = scriptSig;
|
||||
SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy || combined.scriptSig == scriptSig);
|
||||
// dummy scriptSigCopy with placeholder, should always choose non-placeholder:
|
||||
scriptSigCopy = CScript() << OP_0 << vector<unsigned char>(pkSingle.begin(), pkSingle.end());
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSigCopy), SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSig), SignatureData(scriptSigCopy), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
|
||||
// Hardest case: Multisig 2-of-3
|
||||
scriptPubKey = GetScriptForMultisig(2, pubkeys);
|
||||
keystore.AddCScript(scriptPubKey);
|
||||
SignSignature(keystore, txFrom, txTo, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
SignSignature(keystore, txFrom, txTo, txToData, 0, SIGHASH_ALL, consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(scriptSig), empty, consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), empty, SignatureData(scriptSig), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == scriptSig);
|
||||
|
||||
// A couple of partially-signed versions:
|
||||
vector<unsigned char> sig1;
|
||||
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, consensusBranchId);
|
||||
uint256 hash1 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_ALL, 0, consensusBranchId, txToData);
|
||||
BOOST_CHECK(keys[0].Sign(hash1, sig1));
|
||||
sig1.push_back(SIGHASH_ALL);
|
||||
vector<unsigned char> sig2;
|
||||
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, consensusBranchId);
|
||||
uint256 hash2 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_NONE, 0, consensusBranchId, txToData);
|
||||
BOOST_CHECK(keys[1].Sign(hash2, sig2));
|
||||
sig2.push_back(SIGHASH_NONE);
|
||||
vector<unsigned char> sig3;
|
||||
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, consensusBranchId);
|
||||
uint256 hash3 = SignatureHash(scriptPubKey, txTo, 0, SIGHASH_SINGLE, 0, consensusBranchId, txToData);
|
||||
BOOST_CHECK(keys[2].Sign(hash3, sig3));
|
||||
sig3.push_back(SIGHASH_SINGLE);
|
||||
|
||||
|
@ -892,21 +897,21 @@ BOOST_DATA_TEST_CASE(script_combineSigs, boost::unit_test::data::xrange(static_c
|
|||
CScript complete13 = CScript() << OP_0 << sig1 << sig3;
|
||||
CScript complete23 = CScript() << OP_0 << sig2 << sig3;
|
||||
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial1b), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial1a), SignatureData(partial1b), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == partial1a);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1a), SignatureData(partial2a), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial1a), SignatureData(partial2a), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete12);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial1a), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial2a), SignatureData(partial1a), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete12);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial1b), SignatureData(partial2b), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial1b), SignatureData(partial2b), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete12);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial1b), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial3b), SignatureData(partial1b), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete13);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial2a), SignatureData(partial3a), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial2a), SignatureData(partial3a), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete23);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial2b), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial3b), SignatureData(partial2b), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == complete23);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, 0, amount), SignatureData(partial3b), SignatureData(partial3a), consensusBranchId);
|
||||
combined = CombineSignatures(scriptPubKey, MutableTransactionSignatureChecker(&txTo, txToData, 0, amount), SignatureData(partial3b), SignatureData(partial3a), consensusBranchId);
|
||||
BOOST_CHECK(combined.scriptSig == partial3c);
|
||||
}
|
||||
|
||||
|
|
|
@ -202,7 +202,8 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(tx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
assert(ed25519_sign(
|
||||
&joinSplitPrivKey,
|
||||
|
@ -236,10 +237,11 @@ BOOST_AUTO_TEST_CASE(sighash_test)
|
|||
CScript scriptCode;
|
||||
RandomScript(scriptCode);
|
||||
int nIn = insecure_rand() % txTo.vin.size();
|
||||
const PrecomputedTransactionData txdata(txTo);
|
||||
|
||||
uint256 sh, sho;
|
||||
sho = SignatureHashOld(scriptCode, txTo, nIn, nHashType);
|
||||
sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, consensusBranchId);
|
||||
sh = SignatureHash(scriptCode, txTo, nIn, nHashType, 0, consensusBranchId, txdata);
|
||||
#if defined(PRINT_SIGHASH_JSON)
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << txTo;
|
||||
|
@ -334,7 +336,8 @@ BOOST_AUTO_TEST_CASE(sighash_from_data)
|
|||
continue;
|
||||
}
|
||||
|
||||
sh = SignatureHash(scriptCode, tx, nIn, nHashType, 0, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
sh = SignatureHash(scriptCode, tx, nIn, nHashType, 0, consensusBranchId, txdata);
|
||||
BOOST_CHECK_MESSAGE(sh.GetHex() == sigHashHex, strTest);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
|
|||
CAmount amount = 0;
|
||||
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
|
||||
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
|
||||
verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), consensusBranchId, &err),
|
||||
verify_flags, TransactionSignatureChecker(&tx, txdata, i, amount), consensusBranchId, &err),
|
||||
strTest + comment);
|
||||
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err) + comment);
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
|
|||
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
|
||||
CAmount amount = 0;
|
||||
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
|
||||
verify_flags, TransactionSignatureChecker(&tx, i, amount, txdata), consensusBranchId, &err);
|
||||
verify_flags, TransactionSignatureChecker(&tx, txdata, i, amount), consensusBranchId, &err);
|
||||
}
|
||||
BOOST_CHECK_MESSAGE(!fValid, strTest + comment);
|
||||
BOOST_CHECK_MESSAGE(err != SCRIPT_ERR_OK, ScriptErrorString(err) + comment);
|
||||
|
@ -451,15 +451,17 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa
|
|||
jsdesc->nullifiers[0] = GetRandHash();
|
||||
jsdesc->nullifiers[1] = GetRandHash();
|
||||
|
||||
const PrecomputedTransactionData txdata(newTx);
|
||||
|
||||
BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state));
|
||||
BOOST_CHECK(ContextualCheckTransaction(newTx, state, Params(), 0, true));
|
||||
BOOST_CHECK(!ContextualCheckShieldedInputs(newTx, state, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true));
|
||||
BOOST_CHECK(!ContextualCheckShieldedInputs(newTx, txdata, state, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true));
|
||||
BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature");
|
||||
|
||||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(newTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
assert(ed25519_sign(
|
||||
&joinSplitPrivKey,
|
||||
|
@ -469,7 +471,7 @@ void test_simple_joinsplit_invalidity(uint32_t consensusBranchId, CMutableTransa
|
|||
state = CValidationState();
|
||||
BOOST_CHECK(CheckTransactionWithoutProofVerification(newTx, state));
|
||||
BOOST_CHECK(ContextualCheckTransaction(newTx, state, Params(), 0, true));
|
||||
BOOST_CHECK(ContextualCheckShieldedInputs(newTx, state, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true));
|
||||
BOOST_CHECK(ContextualCheckShieldedInputs(newTx, txdata, state, orchardAuth, Params().GetConsensus(), consensusBranchId, false, true));
|
||||
BOOST_CHECK_EQUAL(state.GetRejectReason(), "");
|
||||
}
|
||||
{
|
||||
|
@ -670,9 +672,11 @@ BOOST_AUTO_TEST_CASE(test_big_overwinter_transaction) {
|
|||
mtx.vout[i].scriptPubKey = CScript() << OP_1;
|
||||
}
|
||||
|
||||
PrecomputedTransactionData txdata(mtx);
|
||||
|
||||
// sign all inputs
|
||||
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
||||
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()), consensusBranchId);
|
||||
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, txdata, i, 1000, sigHashes.at(i % sigHashes.size()), consensusBranchId);
|
||||
assert(hashSigned);
|
||||
}
|
||||
|
||||
|
@ -682,7 +686,6 @@ BOOST_AUTO_TEST_CASE(test_big_overwinter_transaction) {
|
|||
ssout >> tx;
|
||||
|
||||
// check all inputs concurrently, with the cache
|
||||
PrecomputedTransactionData txdata(tx);
|
||||
boost::thread_group threadGroup;
|
||||
CCheckQueue<CScriptCheck> scriptcheckqueue(128);
|
||||
CCheckQueueControl<CScriptCheck> control(&scriptcheckqueue);
|
||||
|
@ -915,11 +918,13 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
amount = test[5].get_int64();
|
||||
}
|
||||
|
||||
const PrecomputedTransactionData txdata(tx);
|
||||
|
||||
BOOST_CHECK_EQUAL(
|
||||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_ALL,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[6].getValStr());
|
||||
|
||||
|
@ -928,7 +933,7 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_NONE,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[7].getValStr());
|
||||
}
|
||||
|
@ -938,7 +943,7 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_SINGLE,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[8].getValStr());
|
||||
}
|
||||
|
@ -948,7 +953,7 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_ALL | SIGHASH_ANYONECANPAY,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[9].getValStr());
|
||||
}
|
||||
|
@ -958,7 +963,7 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_NONE | SIGHASH_ANYONECANPAY,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[10].getValStr());
|
||||
}
|
||||
|
@ -968,7 +973,7 @@ BOOST_AUTO_TEST_CASE(TxV5)
|
|||
SignatureHash(
|
||||
scriptCode, tx, nIn,
|
||||
SIGHASH_SINGLE | SIGHASH_ANYONECANPAY,
|
||||
amount, *tx.GetConsensusBranchId()
|
||||
amount, *tx.GetConsensusBranchId(), txdata
|
||||
).GetHex(),
|
||||
test[11].getValStr());
|
||||
}
|
||||
|
|
|
@ -48,8 +48,9 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
|
|||
spends[i].vout[0].scriptPubKey = scriptPubKey;
|
||||
|
||||
// Sign:
|
||||
const PrecomputedTransactionData txdata(spends[i]);
|
||||
std::vector<unsigned char> vchSig;
|
||||
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, coinbaseTxns[0].vout[0].nValue, SPROUT_BRANCH_ID);
|
||||
uint256 hash = SignatureHash(scriptPubKey, spends[i], 0, SIGHASH_ALL, coinbaseTxns[0].vout[0].nValue, SPROUT_BRANCH_ID, txdata);
|
||||
BOOST_CHECK(coinbaseKey.Sign(hash, vchSig));
|
||||
vchSig.push_back((unsigned char)SIGHASH_ALL);
|
||||
spends[i].vin[0].scriptSig << vchSig;
|
||||
|
|
|
@ -446,12 +446,13 @@ TransactionBuilderResult TransactionBuilder::Build()
|
|||
//
|
||||
|
||||
auto consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams);
|
||||
const PrecomputedTransactionData txdata(mtx);
|
||||
|
||||
// Empty output script.
|
||||
uint256 dataToBeSigned;
|
||||
CScript scriptCode;
|
||||
try {
|
||||
dataToBeSigned = SignatureHash(scriptCode, mtx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
dataToBeSigned = SignatureHash(scriptCode, mtx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
} catch (std::logic_error ex) {
|
||||
librustzcash_sapling_proving_ctx_free(ctx);
|
||||
return TransactionBuilderResult("Could not construct signature hash: " + std::string(ex.what()));
|
||||
|
@ -498,7 +499,7 @@ TransactionBuilderResult TransactionBuilder::Build()
|
|||
SignatureData sigdata;
|
||||
bool signSuccess = ProduceSignature(
|
||||
TransactionSignatureCreator(
|
||||
keystore, &txNewConst, nIn, tIn.value, SIGHASH_ALL),
|
||||
keystore, &txNewConst, txdata, nIn, tIn.value, SIGHASH_ALL),
|
||||
tIn.scriptPubKey, sigdata, consensusBranchId);
|
||||
|
||||
if (!signSuccess) {
|
||||
|
|
|
@ -69,7 +69,8 @@ CMutableTransaction GetValidSproutReceiveTransaction(
|
|||
uint32_t consensusBranchId = SPROUT_BRANCH_ID;
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
// Add the signature
|
||||
assert(ed25519_sign(
|
||||
|
@ -184,7 +185,8 @@ CWalletTx GetValidSproutSpend(const libzcash::SproutSpendingKey& sk,
|
|||
uint32_t consensusBranchId = SPROUT_BRANCH_ID;
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
const PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
// Add the signature
|
||||
assert(ed25519_sign(
|
||||
|
|
|
@ -834,7 +834,8 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_);
|
||||
PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_, txdata);
|
||||
|
||||
// Add the signature
|
||||
if (!ed25519_sign(
|
||||
|
|
|
@ -361,7 +361,8 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
PrecomputedTransactionData txdata(signTx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
// Add the signature
|
||||
if (!ed25519_sign(
|
||||
|
|
|
@ -2889,8 +2889,9 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
|||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
PrecomputedTransactionData txdata(signTx);
|
||||
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId, txdata);
|
||||
|
||||
// Add the signature
|
||||
assert(ed25519_sign(
|
||||
|
|
|
@ -4767,13 +4767,14 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||
// Sign
|
||||
int nIn = 0;
|
||||
CTransaction txNewConst(txNew);
|
||||
const PrecomputedTransactionData txdata(txNewConst);
|
||||
for (const std::pair<const CWalletTx*, unsigned int>& coin : setCoins)
|
||||
{
|
||||
bool signSuccess;
|
||||
const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
|
||||
SignatureData sigdata;
|
||||
if (sign)
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, txdata, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
|
||||
else
|
||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
|
||||
|
||||
|
|
|
@ -238,10 +238,12 @@ double benchmark_large_tx(size_t nInputs)
|
|||
spending_tx.vin.emplace_back(input_hash, 0);
|
||||
}
|
||||
|
||||
PrecomputedTransactionData txdata(spending_tx);
|
||||
|
||||
// Sign for all the inputs
|
||||
auto consensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId;
|
||||
for (size_t i = 0; i < nInputs; i++) {
|
||||
SignSignature(tempKeystore, prevPubKey, spending_tx, i, 1000000, SIGHASH_ALL, consensusBranchId);
|
||||
SignSignature(tempKeystore, prevPubKey, spending_tx, txdata, i, 1000000, SIGHASH_ALL, consensusBranchId);
|
||||
}
|
||||
|
||||
// Spending tx has all its inputs signed and does not need to be mutated anymore
|
||||
|
@ -250,13 +252,12 @@ double benchmark_large_tx(size_t nInputs)
|
|||
// Benchmark signature verification costs:
|
||||
struct timeval tv_start;
|
||||
timer_start(tv_start);
|
||||
PrecomputedTransactionData txdata(final_spending_tx);
|
||||
for (size_t i = 0; i < nInputs; i++) {
|
||||
ScriptError serror = SCRIPT_ERR_OK;
|
||||
assert(VerifyScript(final_spending_tx.vin[i].scriptSig,
|
||||
prevPubKey,
|
||||
STANDARD_SCRIPT_VERIFY_FLAGS,
|
||||
TransactionSignatureChecker(&final_spending_tx, i, 1000000, txdata),
|
||||
TransactionSignatureChecker(&final_spending_tx, txdata, i, 1000000),
|
||||
consensusBranchId,
|
||||
&serror));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue