mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-23 07:15:29 +01:00
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 \
|
netaddress.h \
|
||||||
netbase.h \
|
netbase.h \
|
||||||
netmessagemaker.h \
|
netmessagemaker.h \
|
||||||
|
node/coin.h \
|
||||||
node/transaction.h \
|
node/transaction.h \
|
||||||
noui.h \
|
noui.h \
|
||||||
optional.h \
|
optional.h \
|
||||||
|
@ -262,6 +263,7 @@ libbitcoin_server_a_SOURCES = \
|
||||||
miner.cpp \
|
miner.cpp \
|
||||||
net.cpp \
|
net.cpp \
|
||||||
net_processing.cpp \
|
net_processing.cpp \
|
||||||
|
node/coin.cpp \
|
||||||
node/transaction.cpp \
|
node/transaction.cpp \
|
||||||
noui.cpp \
|
noui.cpp \
|
||||||
outputtype.cpp \
|
outputtype.cpp \
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <interfaces/handler.h>
|
#include <interfaces/handler.h>
|
||||||
#include <interfaces/wallet.h>
|
#include <interfaces/wallet.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
#include <node/coin.h>
|
||||||
#include <policy/fees.h>
|
#include <policy/fees.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <policy/rbf.h>
|
#include <policy/rbf.h>
|
||||||
|
@ -287,6 +288,7 @@ public:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(coins); }
|
||||||
double guessVerificationProgress(const uint256& block_hash) override
|
double guessVerificationProgress(const uint256& block_hash) override
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
|
@ -19,6 +19,7 @@ class CFeeRate;
|
||||||
class CRPCCommand;
|
class CRPCCommand;
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
class CValidationState;
|
class CValidationState;
|
||||||
|
class Coin;
|
||||||
class uint256;
|
class uint256;
|
||||||
enum class RBFTransactionState;
|
enum class RBFTransactionState;
|
||||||
struct CBlockLocator;
|
struct CBlockLocator;
|
||||||
|
@ -168,6 +169,11 @@ public:
|
||||||
int64_t* time = nullptr,
|
int64_t* time = nullptr,
|
||||||
int64_t* max_time = nullptr) = 0;
|
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
|
//! Estimate fraction of total transactions verified if blocks up to
|
||||||
//! the specified block hash are verified.
|
//! the specified block hash are verified.
|
||||||
virtual double guessVerificationProgress(const uint256& block_hash) = 0;
|
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 <core_io.h>
|
||||||
#include <index/txindex.h>
|
#include <index/txindex.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
#include <interfaces/chain.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <keystore.h>
|
#include <keystore.h>
|
||||||
#include <merkleblock.h>
|
#include <merkleblock.h>
|
||||||
|
@ -790,23 +791,20 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
||||||
return EncodeHexTx(CTransaction(mergedTx));
|
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)
|
UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, const UniValue& prevTxsUnival, CBasicKeyStore *keystore, bool is_temp_keystore, const UniValue& hashType)
|
||||||
{
|
{
|
||||||
// Fetch previous transactions (inputs):
|
// Fetch previous transactions (inputs):
|
||||||
CCoinsView viewDummy;
|
std::map<COutPoint, Coin> coins;
|
||||||
CCoinsViewCache view(&viewDummy);
|
for (const CTxIn& txin : mtx.vin) {
|
||||||
{
|
coins[txin.prevout]; // Create empty map entry keyed by prevout.
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
chain.findCoins(coins);
|
||||||
|
|
||||||
// Add previous txouts given in the RPC call:
|
// Add previous txouts given in the RPC call:
|
||||||
if (!prevTxsUnival.isNull()) {
|
if (!prevTxsUnival.isNull()) {
|
||||||
|
@ -838,10 +836,10 @@ UniValue SignTransaction(interfaces::Chain& chain, CMutableTransaction& mtx, con
|
||||||
CScript scriptPubKey(pkData.begin(), pkData.end());
|
CScript scriptPubKey(pkData.begin(), pkData.end());
|
||||||
|
|
||||||
{
|
{
|
||||||
const Coin& coin = view.AccessCoin(out);
|
auto coin = coins.find(out);
|
||||||
if (!coin.IsSpent() && coin.out.scriptPubKey != scriptPubKey) {
|
if (coin != coins.end() && !coin->second.IsSpent() && coin->second.out.scriptPubKey != scriptPubKey) {
|
||||||
std::string err("Previous output scriptPubKey mismatch:\n");
|
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);
|
ScriptToAsmStr(scriptPubKey);
|
||||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
|
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.out.nValue = AmountFromValue(find_value(prevOut, "amount"));
|
||||||
}
|
}
|
||||||
newcoin.nHeight = 1;
|
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
|
// 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:
|
// Sign what we can:
|
||||||
for (unsigned int i = 0; i < mtx.vin.size(); i++) {
|
for (unsigned int i = 0; i < mtx.vin.size(); i++) {
|
||||||
CTxIn& txin = mtx.vin[i];
|
CTxIn& txin = mtx.vin[i];
|
||||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
auto coin = coins.find(txin.prevout);
|
||||||
if (coin.IsSpent()) {
|
if (coin == coins.end() || coin->second.IsSpent()) {
|
||||||
TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
|
TxInErrorToJSON(txin, vErrors, "Input not found or already spent");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const CScript& prevPubKey = coin.out.scriptPubKey;
|
const CScript& prevPubKey = coin->second.out.scriptPubKey;
|
||||||
const CAmount& amount = coin.out.nValue;
|
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:
|
// Only sign SIGHASH_SINGLE if there's a corresponding output:
|
||||||
if (!fHashSingle || (i < mtx.vout.size())) {
|
if (!fHashSingle || (i < mtx.vout.size())) {
|
||||||
ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, nHashType), prevPubKey, sigdata);
|
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
|
// amount must be specified for valid segwit signature
|
||||||
if (amount == MAX_MONEY && !txin.scriptWitness.IsNull()) {
|
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;
|
ScriptError serror = SCRIPT_ERR_OK;
|
||||||
|
|
Loading…
Add table
Reference in a new issue