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:
@@ -5,6 +5,7 @@
|
||||
#include "asyncrpcoperation_sendmany.h"
|
||||
#include "asyncrpcqueue.h"
|
||||
#include "amount.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@@ -337,6 +338,12 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(z_outputs_total));
|
||||
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(minersFee));
|
||||
|
||||
// Grab the current consensus branch ID
|
||||
{
|
||||
LOCK(cs_main);
|
||||
consensusBranchId_ = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||
}
|
||||
|
||||
/**
|
||||
* SCENARIO #1
|
||||
*
|
||||
@@ -994,7 +1001,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||
// Empty output script.
|
||||
CScript scriptCode;
|
||||
CTransaction signTx(mtx);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, SIGVERSION_BASE);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId_);
|
||||
|
||||
// Add the signature
|
||||
if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
|
||||
|
||||
@@ -73,6 +73,7 @@ private:
|
||||
|
||||
UniValue contextinfo_; // optional data to include in return value from getStatus()
|
||||
|
||||
uint32_t consensusBranchId_;
|
||||
CAmount fee_;
|
||||
int mindepth_;
|
||||
std::string fromaddress_;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "asyncrpcqueue.h"
|
||||
#include "amount.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@@ -302,12 +303,15 @@ void AsyncRPCOperation_shieldcoinbase::sign_send_raw_transaction(UniValue obj)
|
||||
|
||||
|
||||
UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInfo & info) {
|
||||
uint32_t consensusBranchId;
|
||||
uint256 anchor;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||
anchor = pcoinsTip->GetBestAnchor();
|
||||
}
|
||||
|
||||
|
||||
if (anchor.IsNull()) {
|
||||
throw std::runtime_error("anchor is null");
|
||||
}
|
||||
@@ -369,7 +373,7 @@ 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, SIGVERSION_BASE);
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
|
||||
// Add the signature
|
||||
if (!(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "amount.h"
|
||||
#include "base58.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@@ -2840,7 +2841,8 @@ 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, 0, SIGVERSION_BASE);
|
||||
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId);
|
||||
|
||||
// Add the signature
|
||||
assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL,
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "base58.h"
|
||||
#include "checkpoints.h"
|
||||
#include "coincontrol.h"
|
||||
#include "consensus/upgrades.h"
|
||||
#include "consensus/validation.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
@@ -2768,6 +2769,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
}
|
||||
}
|
||||
|
||||
// Grab the current consensus branch ID
|
||||
auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus());
|
||||
|
||||
// Sign
|
||||
int nIn = 0;
|
||||
CTransaction txNewConst(txNew);
|
||||
@@ -2777,9 +2781,9 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
||||
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);
|
||||
signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.first->vout[coin.second].nValue, SIGHASH_ALL), scriptPubKey, sigdata, consensusBranchId);
|
||||
else
|
||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata);
|
||||
signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, sigdata, consensusBranchId);
|
||||
|
||||
if (!signSuccess)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user