Merge #16798: Refactor rawtransaction_util's SignTransaction to separate prevtx parsing

39034f1ee628dae0bc9da5b1b30b8a424e66d968 Refactor rawtransaction_util's SignTransaction to have previous tx parsing be separate (Andrew Chow)

Pull request description:

  Currently the `SignTransaction` function has to handle both the actual signing and parsing of previous transaction data. This PR splits it so that `SignTransaction` only handles the signing itself and adds a `ParsePrevouts` function which handles parsing the prevtx information.

  This allows for `SignTransaction` to just take any `SigningProvider`.

  Split from #16341

ACKs for top commit:
  MarcoFalke:
    ACK 39034f1ee628dae0bc9da5b1b30b8a424e66d968
  instagibbs:
    utACK 39034f1ee6
  ryanofsky:
    utACK 39034f1ee628dae0bc9da5b1b30b8a424e66d968. No change since previously reviewed b49bbb939be92a67ff77c3f7bca5bb94dd141906, https://github.com/bitcoin/bitcoin/pull/16341#pullrequestreview-278610269 other than rebase with no conflicts.

Tree-SHA512: 09f7733e90691766bfb5cf0f20e913dbf270bd3b51abdcad966b24d110e562ed85fd3d0d1d7bbea61f903340060052ec73c4817b09aee0dc1f3916d781a9e40c
This commit is contained in:
fanquake 2019-09-07 08:21:28 +08:00 committed by Konstantin Akimov
parent 0fe885f5de
commit b2a97a3b13
4 changed files with 24 additions and 8 deletions

View File

@ -779,7 +779,10 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
NodeContext& node = EnsureNodeContext(request.context);
FindCoins(node, coins);
return SignTransaction(mtx, request.params[2], &keystore, coins, true, request.params[3]);
// Parse the prevtxs array
ParsePrevouts(request.params[2], &keystore, coins);
return SignTransaction(mtx, &keystore, coins, request.params[3]);
}
UniValue sendrawtransaction(const JSONRPCRequest& request)

View File

@ -129,9 +129,8 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::
vErrorsRet.push_back(entry);
}
UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins, bool is_temp_keystore, const UniValue& hashType)
void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins)
{
// Add previous txouts given in the RPC call:
if (!prevTxsUnival.isNull()) {
UniValue prevTxs = prevTxsUnival.get_array();
for (unsigned int idx = 0; idx < prevTxs.size(); ++idx) {
@ -179,7 +178,7 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
}
// if redeemScript and private keys were given, add redeemScript to the keystore so it can be signed
if (is_temp_keystore && scriptPubKey.IsPayToScriptHash()) {
if (keystore && scriptPubKey.IsPayToScriptHash()) {
RPCTypeCheckObj(prevOut,
{
{"redeemScript", UniValueType(UniValue::VSTR)},
@ -193,7 +192,10 @@ UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxsUnival
}
}
}
}
UniValue SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, std::map<COutPoint, Coin>& coins, const UniValue& hashType)
{
int nHashType = ParseSighashString(hashType);
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);

View File

@ -12,19 +12,27 @@ class UniValue;
struct CMutableTransaction;
class Coin;
class COutPoint;
class SigningProvider;
/**
* Sign a transaction with the given keystore and previous transactions
*
* @param mtx The transaction to-be-signed
* @param prevTxs Array of previous txns outputs that tx depends on but may not yet be in the block chain
* @param keystore Temporary keystore containing signing keys
* @param coins Map of unspent outputs - coins in mempool and current chain UTXO set, may be extended by previous txns outputs after call
* @param tempKeystore Whether to use temporary keystore
* @param hashType The signature hash type
* @returns JSON object with details of signed transaction
*/
UniValue SignTransaction(CMutableTransaction& mtx, const UniValue& prevTxs, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins, bool tempKeystore, const UniValue& hashType);
UniValue SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore, std::map<COutPoint, Coin>& coins, const UniValue& hashType);
/**
* Parse a prevtxs UniValue array and get the map of coins from it
*
* @param prevTxs Array of previous txns outputs that tx depends on but may not yet be in the block chain
* @param keystore A pointer to the temprorary keystore if there is one
* @param coins Map of unspent outputs - coins in mempool and current chain UTXO set, may be extended by previous txns outputs after call
*/
void ParsePrevouts(const UniValue& prevTxsUnival, FillableSigningProvider* keystore, std::map<COutPoint, Coin>& coins);
/** Create a transaction from univalue parameters */
CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniValue& outputs_in, const UniValue& locktime);

View File

@ -3372,7 +3372,10 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
}
pwallet->chain().findCoins(coins);
return SignTransaction(mtx, request.params[1], &*pwallet->GetLegacyScriptPubKeyMan(), coins, false, request.params[2]);
// Parse the prevtxs array
ParsePrevouts(request.params[1], nullptr, coins);
return SignTransaction(mtx, &*pwallet->GetLegacyScriptPubKeyMan(), coins, request.params[2]);
}
static UniValue rescanblockchain(const JSONRPCRequest& request)