Remove use of CCoinsViewMemPool::GetCoin in wallet code
This commit does not change behavior.
This commit is contained in:
parent
4e4d9e9f85
commit
b1b2b23892
6 changed files with 75 additions and 23 deletions
|
@ -154,6 +154,7 @@ BITCOIN_CORE_H = \
|
|||
netaddress.h \
|
||||
netbase.h \
|
||||
netmessagemaker.h \
|
||||
node/coin.h \
|
||||
node/transaction.h \
|
||||
noui.h \
|
||||
optional.h \
|
||||
|
@ -262,6 +263,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
miner.cpp \
|
||||
net.cpp \
|
||||
net_processing.cpp \
|
||||
node/coin.cpp \
|
||||
node/transaction.cpp \
|
||||
noui.cpp \
|
||||
outputtype.cpp \
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <interfaces/handler.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <net.h>
|
||||
#include <node/coin.h>
|
||||
#include <policy/fees.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/rbf.h>
|
||||
|
@ -287,6 +288,7 @@ public:
|
|||
}
|
||||
return true;
|
||||
}
|
||||
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(coins); }
|
||||
double guessVerificationProgress(const uint256& block_hash) override
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
|
|
@ -19,6 +19,7 @@ class CFeeRate;
|
|||
class CRPCCommand;
|
||||
class CScheduler;
|
||||
class CValidationState;
|
||||
class Coin;
|
||||
class uint256;
|
||||
enum class RBFTransactionState;
|
||||
struct CBlockLocator;
|
||||
|
@ -168,6 +169,11 @@ public:
|
|||
int64_t* time = nullptr,
|
||||
int64_t* max_time = nullptr) = 0;
|
||||
|
||||
//! Look up unspent output information. Returns coins in the mempool and in
|
||||
//! the current chain UTXO set. Iterates through all the keys in the map and
|
||||
//! populates the values.
|
||||
virtual void findCoins(std::map<COutPoint, Coin>& coins) = 0;
|
||||
|
||||
//! Estimate fraction of total transactions verified if blocks up to
|
||||
//! the specified block hash are verified.
|
||||
virtual double guessVerificationProgress(const uint256& block_hash) = 0;
|
||||
|
|
22
src/node/coin.cpp
Normal file
22
src/node/coin.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2019 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <node/coin.h>
|
||||
|
||||
#include <txmempool.h>
|
||||
#include <validation.h>
|
||||
|
||||
void FindCoins(std::map<COutPoint, Coin>& coins)
|
||||
{
|
||||
LOCK2(cs_main, ::mempool.cs);
|
||||
assert(pcoinsTip);
|
||||
CCoinsViewCache& chain_view = *::pcoinsTip;
|
||||
CCoinsViewMemPool mempool_view(&chain_view, ::mempool);
|
||||
for (auto& coin : coins) {
|
||||
if (!mempool_view.GetCoin(coin.first, coin.second)) {
|
||||
// Either the coin is not in the CCoinsViewCache or is spent. Clear it.
|
||||
coin.second.Clear();
|
||||
}
|
||||
}
|
||||
}
|
22
src/node/coin.h
Normal file
22
src/node/coin.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2019 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_NODE_COIN_H
|
||||
#define BITCOIN_NODE_COIN_H
|
||||
|
||||
#include <map>
|
||||
|
||||
class COutPoint;
|
||||
class Coin;
|
||||
|
||||
/**
|
||||
* Look up unspent output information. Returns coins in the mempool and in the
|
||||
* current chain UTXO set. Iterates through all the keys in the map and
|
||||
* populates the values.
|
||||
*
|
||||
* @param[in,out] coins map to fill
|
||||
*/
|
||||
void FindCoins(std::map<COutPoint, Coin>& coins);
|
||||
|
||||
#endif // BITCOIN_NODE_COIN_H
|
|
@ -11,6 +11,7 @@
|
|||
#include <core_io.h>
|
||||
#include <index/txindex.h>
|
||||
#include <init.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <key_io.h>
|
||||
#include <keystore.h>
|
||||
#include <merkleblock.h>
|
||||
|
@ -790,23 +791,20 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
|||
return EncodeHexTx(CTransaction(mergedTx));
|
||||
}
|
||||
|
||||
// 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, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
|
||||
{
|
||||
// Fetch previous transactions (inputs):
|
||||
CCoinsView viewDummy;
|
||||
CCoinsViewCache view(&viewDummy);
|
||||
{
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
CCoinsViewCache &viewChain = *pcoinsTip;
|
||||
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
for (const CTxIn& txin : mtx.vin) {
|
||||
view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
|
||||
}
|
||||
|
||||
view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
|
||||
std::map<COutPoint, Coin> coins;
|
||||
for (const CTxIn& txin : mtx.vin) {
|
||||
coins[txin.prevout]; // Create empty map entry keyed by prevout.
|
||||
}
|
||||
chain.findCoins(coins);
|
||||
|
||||
// Add previous txouts given in the RPC call:
|
||||
if (!prevTxsUnival.isNull()) {
|
||||
|
@ -838,10 +836,10 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
|||
CScript scriptPubKey(pkData.begin(), pkData.end());
|
||||
|
||||
{
|
||||
const Coin& coin = view.AccessCoin(out);
|
||||
if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
|
||||
auto coin = coins.find(out);
|
||||
if (coin != coins.end() && !coin->second.IsSpent() && coin->second.out.scriptPubKey != scriptPubKey) {
|
||||
std::string err("Previous output scriptPubKey mismatch:\n");
|
||||
err = err + ScriptToAsmStr(coin.out.scriptPubKey) + "\nvs:\n"+
|
||||
err = err + ScriptToAsmStr(coin->second.out.scriptPubKey) + "\nvs:\n"+
|
||||
ScriptToAsmStr(scriptPubKey);
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
|
||||
}
|
||||
|
@ -852,7 +850,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
|||
newcoin.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
|
||||
}
|
||||
newcoin.nHeight = 1;
|
||||
view.AddCoin(out, std::move(newcoin), true);
|
||||
coins[out] = std::move(newcoin);
|
||||
}
|
||||
|
||||
// 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
|
|||
// Sign what we can:
|
||||
for (unsigned int i = 0; i < mtx.vin.size(); i++) {
|
||||
CTxIn& txin = mtx.vin[i];
|
||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||
if (coin.IsSpent()) {
|
||||
auto coin = coins.find(txin.prevout);
|
||||
if (coin == coins.end() || coin->second.IsSpent()) {
|
||||
TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
|
||||
continue;
|
||||
}
|
||||
const CScript& prevPubKey = coin.out.scriptPubKey;
|
||||
const CAmount& amount = coin.out.nValue;
|
||||
const CScript& prevPubKey = coin->second.out.scriptPubKey;
|
||||
const CAmount& amount = coin->second.out.nValue;
|
||||
|
||||
SignatureData sigdata = DataFromTransaction(mtx, i, coin.out);
|
||||
SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out);
|
||||
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
||||
if (!fHashSingle || (i < mtx.vout.size())) {
|
||||
ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
|
||||
|
@ -914,7 +912,7 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
|||
|
||||
// amount must be specified for valid segwit signature
|
||||
if (amount == MAX_MONEY && !txin.scriptWitness.IsNull()) {
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing amount for %s", coin.out.ToString()));
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing amount for %s", coin->second.out.ToString()));
|
||||
}
|
||||
|
||||
ScriptError serror = SCRIPT_ERR_OK;
|
||||
|
|
Loading…
Reference in a new issue