11
11
#include < core_io.h>
12
12
#include < index/txindex.h>
13
13
#include < init.h>
14
+ #include < interfaces/chain.h>
14
15
#include < key_io.h>
15
16
#include < keystore.h>
16
17
#include < merkleblock.h>
@@ -790,23 +791,20 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
790
791
return EncodeHexTx (CTransaction (mergedTx));
791
792
}
792
793
794
+ // TODO(https://github.com/bitcoin/bitcoin/pull/10973#discussion_r267084237):
795
+ // This function is called from both wallet and node rpcs
796
+ // (signrawtransactionwithwallet and signrawtransactionwithkey). It should be
797
+ // moved to a util file so wallet code doesn't need to link against node code.
798
+ // Also the dependency on interfaces::Chain should be removed, so
799
+ // signrawtransactionwithkey doesn't need access to a Chain instance.
793
800
UniValue SignTransaction (interfaces::Chain& chain, CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
794
801
{
795
802
// Fetch previous transactions (inputs):
796
- CCoinsView viewDummy;
797
- CCoinsViewCache view (&viewDummy);
798
- {
799
- LOCK2 (cs_main, mempool.cs );
800
- CCoinsViewCache &viewChain = *pcoinsTip;
801
- CCoinsViewMemPool viewMempool (&viewChain, mempool);
802
- view.SetBackend (viewMempool); // temporarily switch cache backend to db+mempool view
803
-
804
- for (const CTxIn& txin : mtx.vin ) {
805
- view.AccessCoin (txin.prevout ); // Load entries from viewChain into view; can fail.
806
- }
807
-
808
- view.SetBackend (viewDummy); // switch back to avoid locking mempool for too long
803
+ std::map<COutPoint, Coin> coins;
804
+ for (const CTxIn& txin : mtx.vin ) {
805
+ coins[txin.prevout ]; // Create empty map entry keyed by prevout.
809
806
}
807
+ chain.findCoins (coins);
810
808
811
809
// Add previous txouts given in the RPC call:
812
810
if (!prevTxsUnival.isNull ()) {
@@ -838,10 +836,10 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
838
836
CScript scriptPubKey (pkData.begin (), pkData.end ());
839
837
840
838
{
841
- const Coin& coin = view. AccessCoin (out);
842
- if (! coin.IsSpent () && coin.out .scriptPubKey != scriptPubKey) {
839
+ auto coin = coins. find (out);
840
+ if (coin != coins. end () && ! coin-> second .IsSpent () && coin-> second .out .scriptPubKey != scriptPubKey) {
843
841
std::string err (" Previous output scriptPubKey mismatch:\n " );
844
- err = err + ScriptToAsmStr (coin.out .scriptPubKey ) + " \n vs:\n " +
842
+ err = err + ScriptToAsmStr (coin-> second .out .scriptPubKey ) + " \n vs:\n " +
845
843
ScriptToAsmStr (scriptPubKey);
846
844
throw JSONRPCError (RPC_DESERIALIZATION_ERROR, err);
847
845
}
@@ -852,7 +850,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
852
850
newcoin.out .nValue = AmountFromValue (find_value (prevOut, " amount" ));
853
851
}
854
852
newcoin.nHeight = 1 ;
855
- view. AddCoin ( out, std::move (newcoin), true );
853
+ coins[ out] = std::move (newcoin);
856
854
}
857
855
858
856
// if redeemScript and private keys were given, add redeemScript to the keystore so it can be signed
@@ -896,15 +894,15 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
896
894
// Sign what we can:
897
895
for (unsigned int i = 0 ; i < mtx.vin .size (); i++) {
898
896
CTxIn& txin = mtx.vin [i];
899
- const Coin& coin = view. AccessCoin (txin.prevout );
900
- if (coin.IsSpent ()) {
897
+ auto coin = coins. find (txin.prevout );
898
+ if (coin == coins. end () || coin-> second .IsSpent ()) {
901
899
TxInErrorToJSON (txin, vErrors, " Input not found or already spent" );
902
900
continue ;
903
901
}
904
- const CScript& prevPubKey = coin.out .scriptPubKey ;
905
- const CAmount& amount = coin.out .nValue ;
902
+ const CScript& prevPubKey = coin-> second .out .scriptPubKey ;
903
+ const CAmount& amount = coin-> second .out .nValue ;
906
904
907
- SignatureData sigdata = DataFromTransaction (mtx, i, coin.out );
905
+ SignatureData sigdata = DataFromTransaction (mtx, i, coin-> second .out );
908
906
// Only sign SIGHASH_SINGLE if there's a corresponding output:
909
907
if (!fHashSingle || (i < mtx.vout .size ())) {
910
908
ProduceSignature (*keystore, MutableTransactionSignatureCreator (&mtx, i, amount, nHashType), prevPubKey, sigdata);
@@ -914,7 +912,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
914
912
915
913
// amount must be specified for valid segwit signature
916
914
if (amount == MAX_MONEY && !txin.scriptWitness .IsNull ()) {
917
- throw JSONRPCError (RPC_TYPE_ERROR, strprintf (" Missing amount for %s" , coin.out .ToString ()));
915
+ throw JSONRPCError (RPC_TYPE_ERROR, strprintf (" Missing amount for %s" , coin-> second .out .ToString ()));
918
916
}
919
917
920
918
ScriptError serror = SCRIPT_ERR_OK;
0 commit comments