diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -892,8 +893,16 @@ keystore.AddKey(key); } - return SignTransaction(*g_rpc_node->chain, mtx, request.params[2], - &keystore, true, request.params[3]); + // Fetch previous transactions (inputs): + std::map coins; + for (const CTxIn &txin : mtx.vin) { + // Create empty map entry keyed by prevout. + coins[txin.prevout]; + } + FindCoins(coins); + + return SignTransaction(mtx, request.params[2], &keystore, coins, true, + request.params[3]); } static UniValue sendrawtransaction(const Config &config, diff --git a/src/rpc/rawtransaction_util.h b/src/rpc/rawtransaction_util.h --- a/src/rpc/rawtransaction_util.h +++ b/src/rpc/rawtransaction_util.h @@ -5,20 +5,33 @@ #ifndef BITCOIN_RPC_RAWTRANSACTION_UTIL_H #define BITCOIN_RPC_RAWTRANSACTION_UTIL_H +#include + class CBasicKeyStore; class CChainParams; -class UniValue; class CMutableTransaction; +class Coin; +class COutPoint; +class UniValue; -namespace interfaces { -class Chain; -} // namespace interfaces - -/** Sign a transaction with the given keystore and previous transactions */ -UniValue SignTransaction(interfaces::Chain &chain, CMutableTransaction &mtx, - const UniValue &prevTxs, CBasicKeyStore *keystore, - bool tempKeystore, const UniValue &hashType); +/** + * 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, + CBasicKeyStore *keystore, + std::map &coins, bool tempKeystore, + const UniValue &hashType); /** Create a transaction from univalue parameters */ CMutableTransaction ConstructTransaction(const CChainParams ¶ms, diff --git a/src/rpc/rawtransaction_util.cpp b/src/rpc/rawtransaction_util.cpp --- a/src/rpc/rawtransaction_util.cpp +++ b/src/rpc/rawtransaction_util.cpp @@ -157,24 +157,11 @@ vErrorsRet.push_back(entry); } -// TODO(https://github.com/bitcoin/bitcoin/pull/10973#discussion_r267084237): -// This function is called from both wallet and node rpcs -// (signrawtransactionwithwallet and signrawtransactionwithkey). It should be -// moved to a util file so wallet code doesn't need to link against node code. -// Also the dependency on interfaces::Chain should be removed, so -// signrawtransactionwithkey doesn't need access to a Chain instance. -UniValue SignTransaction(interfaces::Chain &chain, CMutableTransaction &mtx, +UniValue SignTransaction(CMutableTransaction &mtx, const UniValue &prevTxsUnival, - CBasicKeyStore *keystore, bool is_temp_keystore, - const UniValue &hashType) { - // Fetch previous transactions (inputs): - std::map coins; - for (const CTxIn &txin : mtx.vin) { - // Create empty map entry keyed by prevout. - coins[txin.prevout]; - } - chain.findCoins(coins); - + CBasicKeyStore *keystore, + std::map &coins, + bool is_temp_keystore, const UniValue &hashType) { // Add previous txouts given in the RPC call: if (!prevTxsUnival.isNull()) { UniValue prevTxs = prevTxsUnival.get_array(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3804,8 +3804,16 @@ LOCK(pwallet->cs_wallet); EnsureWalletIsUnlocked(pwallet); - return SignTransaction(pwallet->chain(), mtx, request.params[1], pwallet, - false, request.params[2]); + // Fetch previous transactions (inputs): + std::map coins; + for (const CTxIn &txin : mtx.vin) { + // Create empty map entry keyed by prevout. + coins[txin.prevout]; + } + pwallet->chain().findCoins(coins); + + return SignTransaction(mtx, request.params[1], pwallet, coins, false, + request.params[2]); } UniValue generate(const Config &config, const JSONRPCRequest &request) {