mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
merge bitcoin#15288: Remove wallet -> node global function calls
This commit is contained in:
parent
a97eebd068
commit
2c98320c1a
@ -8,9 +8,18 @@ MAPPING = {
|
|||||||
'core_write.cpp': 'core_io.cpp',
|
'core_write.cpp': 'core_io.cpp',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Directories with header-based modules, where the assumption that .cpp files
|
||||||
|
# define functions and variables declared in corresponding .h files is
|
||||||
|
# incorrect.
|
||||||
|
HEADER_MODULE_PATHS = [
|
||||||
|
'interfaces/'
|
||||||
|
]
|
||||||
|
|
||||||
def module_name(path):
|
def module_name(path):
|
||||||
if path in MAPPING:
|
if path in MAPPING:
|
||||||
path = MAPPING[path]
|
path = MAPPING[path]
|
||||||
|
if any(path.startswith(dirpath) for dirpath in HEADER_MODULE_PATHS):
|
||||||
|
return path
|
||||||
if path.endswith(".h"):
|
if path.endswith(".h"):
|
||||||
return path[:-2]
|
return path[:-2]
|
||||||
if path.endswith(".c"):
|
if path.endswith(".c"):
|
||||||
|
@ -76,7 +76,7 @@ bench_bench_dash_SOURCES += bench/coin_selection.cpp
|
|||||||
bench_bench_dash_SOURCES += bench/wallet_balance.cpp
|
bench_bench_dash_SOURCES += bench/wallet_balance.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS) $(GMP_LIBS)
|
bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS) $(GMP_LIBS)
|
||||||
bench_bench_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
bench_bench_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||||
|
|
||||||
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)
|
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)
|
||||||
|
@ -111,7 +111,7 @@ CTransactionBuilder::CTransactionBuilder(std::shared_ptr<CWallet> pwalletIn, con
|
|||||||
tallyItem(tallyItemIn)
|
tallyItem(tallyItemIn)
|
||||||
{
|
{
|
||||||
// Generate a feerate which will be used to consider if the remainder is dust and will go into fees or not
|
// Generate a feerate which will be used to consider if the remainder is dust and will go into fees or not
|
||||||
coinControl.m_discard_feerate = ::GetDiscardRate(*pwallet.get(), ::feeEstimator);
|
coinControl.m_discard_feerate = ::GetDiscardRate(*pwallet.get());
|
||||||
// Generate a feerate which will be used by calculations of this class and also by CWallet::CreateTransaction
|
// Generate a feerate which will be used by calculations of this class and also by CWallet::CreateTransaction
|
||||||
coinControl.m_feerate = std::max(::feeEstimator.estimateSmartFee((int)pwallet->m_confirm_target, nullptr, true), pwallet->m_pay_tx_fee);
|
coinControl.m_feerate = std::max(::feeEstimator.estimateSmartFee((int)pwallet->m_confirm_target, nullptr, true), pwallet->m_pay_tx_fee);
|
||||||
// Change always goes back to origin
|
// Change always goes back to origin
|
||||||
@ -307,7 +307,7 @@ bool CTransactionBuilder::Commit(std::string& strResult)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(tx, {}, {}, dummyReserveKey, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, {}, {}, dummyReserveKey, state)) {
|
||||||
strResult = state.GetRejectReason();
|
strResult = state.GetRejectReason();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,19 @@
|
|||||||
|
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <coinjoin/coinjoin.h>
|
||||||
|
#include <interfaces/wallet.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <policy/fees.h>
|
||||||
|
#include <policy/policy.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
|
#include <protocol.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
#include <threadsafety.h>
|
||||||
|
#include <timedata.h>
|
||||||
|
#include <txmempool.h>
|
||||||
|
#include <ui_interface.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
@ -146,6 +157,17 @@ class LockImpl : public Chain::Lock
|
|||||||
}
|
}
|
||||||
return nullopt;
|
return nullopt;
|
||||||
}
|
}
|
||||||
|
bool checkFinalTx(const CTransaction& tx) override
|
||||||
|
{
|
||||||
|
LockAnnotation lock(::cs_main);
|
||||||
|
return CheckFinalTx(tx);
|
||||||
|
}
|
||||||
|
bool submitToMemoryPool(CTransactionRef tx, CAmount absurd_fee, CValidationState& state) override
|
||||||
|
{
|
||||||
|
LockAnnotation lock(::cs_main);
|
||||||
|
return AcceptToMemoryPool(::mempool, state, tx, nullptr /* missing inputs */,
|
||||||
|
false /* bypass limits */, absurd_fee);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
|
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
|
||||||
@ -191,6 +213,56 @@ public:
|
|||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash));
|
return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash));
|
||||||
}
|
}
|
||||||
|
bool hasDescendantsInMempool(const uint256& txid) override
|
||||||
|
{
|
||||||
|
LOCK(::mempool.cs);
|
||||||
|
auto it_mp = ::mempool.mapTx.find(txid);
|
||||||
|
return it_mp != ::mempool.mapTx.end() && it_mp->GetCountWithDescendants() > 1;
|
||||||
|
}
|
||||||
|
void relayTransaction(const uint256& txid) override
|
||||||
|
{
|
||||||
|
CInv inv(CCoinJoin::GetDSTX(txid) ? MSG_DSTX : MSG_TX, txid);
|
||||||
|
g_connman->ForEachNode([&inv](CNode* node) { node->PushInventory(inv); });
|
||||||
|
}
|
||||||
|
void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) override
|
||||||
|
{
|
||||||
|
::mempool.GetTransactionAncestry(txid, ancestors, descendants);
|
||||||
|
}
|
||||||
|
bool checkChainLimits(CTransactionRef tx) override
|
||||||
|
{
|
||||||
|
LockPoints lp;
|
||||||
|
CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
|
||||||
|
CTxMemPool::setEntries ancestors;
|
||||||
|
auto limit_ancestor_count = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
|
||||||
|
auto limit_ancestor_size = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
|
||||||
|
auto limit_descendant_count = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
|
||||||
|
auto limit_descendant_size = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
|
||||||
|
std::string unused_error_string;
|
||||||
|
LOCK(::mempool.cs);
|
||||||
|
return ::mempool.CalculateMemPoolAncestors(entry, ancestors, limit_ancestor_count, limit_ancestor_size,
|
||||||
|
limit_descendant_count, limit_descendant_size, unused_error_string);
|
||||||
|
}
|
||||||
|
CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
|
||||||
|
{
|
||||||
|
return ::feeEstimator.estimateSmartFee(num_blocks, calc, conservative);
|
||||||
|
}
|
||||||
|
unsigned int estimateMaxBlocks() override
|
||||||
|
{
|
||||||
|
return ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
|
}
|
||||||
|
CFeeRate mempoolMinFee() override
|
||||||
|
{
|
||||||
|
return ::mempool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
|
||||||
|
}
|
||||||
|
CAmount maxTxFee() override { return ::maxTxFee; }
|
||||||
|
bool getPruneMode() override { return ::fPruneMode; }
|
||||||
|
bool p2pEnabled() override { return g_connman != nullptr; }
|
||||||
|
bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
|
||||||
|
int64_t getAdjustedTime() override { return GetAdjustedTime(); }
|
||||||
|
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
|
||||||
|
void initWarning(const std::string& message) override { InitWarning(message); }
|
||||||
|
void initError(const std::string& message) override { InitError(message); }
|
||||||
|
void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -5,20 +5,29 @@
|
|||||||
#ifndef BITCOIN_INTERFACES_CHAIN_H
|
#ifndef BITCOIN_INTERFACES_CHAIN_H
|
||||||
#define BITCOIN_INTERFACES_CHAIN_H
|
#define BITCOIN_INTERFACES_CHAIN_H
|
||||||
|
|
||||||
#include <optional.h>
|
#include <optional.h> // For Optional and nullopt
|
||||||
|
#include <primitives/transaction.h> // For CTransactionRef
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class CBlock;
|
class CBlock;
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
|
class CValidationState;
|
||||||
|
class CFeeRate;
|
||||||
class uint256;
|
class uint256;
|
||||||
struct CBlockLocator;
|
struct CBlockLocator;
|
||||||
|
struct FeeCalculation;
|
||||||
|
|
||||||
|
typedef std::shared_ptr<const CTransaction> CTransactionRef;
|
||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
|
|
||||||
|
class Wallet;
|
||||||
|
|
||||||
//! Interface for giving wallet processes access to blockchain state.
|
//! Interface for giving wallet processes access to blockchain state.
|
||||||
class Chain
|
class Chain
|
||||||
{
|
{
|
||||||
@ -102,6 +111,13 @@ public:
|
|||||||
//! is guaranteed to be an ancestor of the block used to create the
|
//! is guaranteed to be an ancestor of the block used to create the
|
||||||
//! locator.
|
//! locator.
|
||||||
virtual Optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
|
virtual Optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
|
||||||
|
|
||||||
|
//! Check if transaction will be final given chain height current time.
|
||||||
|
virtual bool checkFinalTx(const CTransaction& tx) = 0;
|
||||||
|
|
||||||
|
//! Add transaction to memory pool if the transaction fee is below the
|
||||||
|
//! amount specified by absurd_fee (as a safeguard). */
|
||||||
|
virtual bool submitToMemoryPool(CTransactionRef tx, CAmount absurd_fee, CValidationState& state) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Return Lock interface. Chain is locked when this is called, and
|
//! Return Lock interface. Chain is locked when this is called, and
|
||||||
@ -127,6 +143,57 @@ public:
|
|||||||
//! 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;
|
||||||
|
|
||||||
|
//! Check if transaction has descendants in mempool.
|
||||||
|
virtual bool hasDescendantsInMempool(const uint256& txid) = 0;
|
||||||
|
|
||||||
|
//! Relay transaction.
|
||||||
|
virtual void relayTransaction(const uint256& txid) = 0;
|
||||||
|
|
||||||
|
//! Calculate mempool ancestor and descendant counts for the given transaction.
|
||||||
|
virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) = 0;
|
||||||
|
|
||||||
|
//! Check chain limits.
|
||||||
|
virtual bool checkChainLimits(CTransactionRef tx) = 0;
|
||||||
|
|
||||||
|
//! Estimate smart fee.
|
||||||
|
virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0;
|
||||||
|
|
||||||
|
//! Fee estimator max target.
|
||||||
|
virtual unsigned int estimateMaxBlocks() = 0;
|
||||||
|
|
||||||
|
//! Pool min fee.
|
||||||
|
virtual CFeeRate mempoolMinFee() = 0;
|
||||||
|
|
||||||
|
//! Get node max tx fee setting (-maxtxfee).
|
||||||
|
//! This could be replaced by a per-wallet max fee, as proposed at
|
||||||
|
//! https://github.com/bitcoin/bitcoin/issues/15355
|
||||||
|
//! But for the time being, wallets call this to access the node setting.
|
||||||
|
virtual CAmount maxTxFee() = 0;
|
||||||
|
|
||||||
|
//! Check if pruning is enabled.
|
||||||
|
virtual bool getPruneMode() = 0;
|
||||||
|
|
||||||
|
//! Check if p2p enabled.
|
||||||
|
virtual bool p2pEnabled() = 0;
|
||||||
|
|
||||||
|
// Check if in IBD.
|
||||||
|
virtual bool isInitialBlockDownload() = 0;
|
||||||
|
|
||||||
|
//! Get adjusted time.
|
||||||
|
virtual int64_t getAdjustedTime() = 0;
|
||||||
|
|
||||||
|
//! Send init message.
|
||||||
|
virtual void initMessage(const std::string& message) = 0;
|
||||||
|
|
||||||
|
//! Send init warning.
|
||||||
|
virtual void initWarning(const std::string& message) = 0;
|
||||||
|
|
||||||
|
//! Send init error.
|
||||||
|
virtual void initError(const std::string& message) = 0;
|
||||||
|
|
||||||
|
//! Send wallet load notification to the GUI.
|
||||||
|
virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
//! Interface to let node manage chain clients (wallets, or maybe tools for
|
||||||
|
@ -419,7 +419,7 @@ public:
|
|||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
|
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
|
||||||
{
|
{
|
||||||
return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::shared_ptr<CWallet> wallet) { fn(MakeWallet(wallet)); }));
|
return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::unique_ptr<Wallet>& wallet) { fn(std::move(wallet)); }));
|
||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
|
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
auto locked_chain = m_wallet.chain().lock();
|
auto locked_chain = m_wallet.chain().lock();
|
||||||
LOCK2(mempool.cs, m_wallet.cs_wallet);
|
LOCK2(mempool.cs, m_wallet.cs_wallet);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_key, g_connman.get(), state)) {
|
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_key, state)) {
|
||||||
reject_reason = state.GetRejectReason();
|
reject_reason = state.GetRejectReason();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ WalletTx MakeWalletTx(interfaces::Chain::Lock& locked_chain, CWallet& wallet, co
|
|||||||
//! Construct wallet tx status struct.
|
//! Construct wallet tx status struct.
|
||||||
WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx)
|
WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx)
|
||||||
{
|
{
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
LockAnnotation lock(::cs_main); // Temporary, for mapBlockIndex below. Removed in upcoming commit.
|
||||||
|
|
||||||
WalletTxStatus result;
|
WalletTxStatus result;
|
||||||
auto mi = ::BlockIndex().find(wtx.hashBlock);
|
auto mi = ::BlockIndex().find(wtx.hashBlock);
|
||||||
@ -120,7 +120,7 @@ WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const C
|
|||||||
result.depth_in_main_chain = wtx.GetDepthInMainChain(locked_chain);
|
result.depth_in_main_chain = wtx.GetDepthInMainChain(locked_chain);
|
||||||
result.time_received = wtx.nTimeReceived;
|
result.time_received = wtx.nTimeReceived;
|
||||||
result.lock_time = wtx.tx->nLockTime;
|
result.lock_time = wtx.tx->nLockTime;
|
||||||
result.is_final = CheckFinalTx(*wtx.tx);
|
result.is_final = locked_chain.checkFinalTx(*wtx.tx);
|
||||||
result.is_trusted = wtx.IsTrusted(locked_chain);
|
result.is_trusted = wtx.IsTrusted(locked_chain);
|
||||||
result.is_abandoned = wtx.isAbandoned();
|
result.is_abandoned = wtx.isAbandoned();
|
||||||
result.is_coinbase = wtx.IsCoinBase();
|
result.is_coinbase = wtx.IsCoinBase();
|
||||||
@ -539,7 +539,7 @@ public:
|
|||||||
{
|
{
|
||||||
FeeCalculation fee_calc;
|
FeeCalculation fee_calc;
|
||||||
CAmount result;
|
CAmount result;
|
||||||
result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, ::mempool, ::feeEstimator, &fee_calc);
|
result = GetMinimumFee(*m_wallet, tx_bytes, coin_control, &fee_calc);
|
||||||
if (returned_target) *returned_target = fee_calc.returnedTarget;
|
if (returned_target) *returned_target = fee_calc.returnedTarget;
|
||||||
if (reason) *reason = fee_calc.reason;
|
if (reason) *reason = fee_calc.reason;
|
||||||
return result;
|
return result;
|
||||||
|
@ -247,7 +247,7 @@ static UniValue gobject_prepare(const JSONRPCRequest& request)
|
|||||||
CReserveKey reservekey(pwallet);
|
CReserveKey reservekey(pwallet);
|
||||||
// -- send the tx to the network
|
// -- send the tx to the network
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(tx, {}, {}, reservekey, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, {}, {}, reservekey, state)) {
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "CommitTransaction failed! Reason given: " + state.GetRejectReason());
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "CommitTransaction failed! Reason given: " + state.GetRejectReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,7 +868,8 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR});
|
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VSTR});
|
||||||
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
||||||
unsigned int conf_target = ParseConfirmTarget(request.params[0]);
|
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
|
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||||
bool conservative = true;
|
bool conservative = true;
|
||||||
if (!request.params[1].isNull()) {
|
if (!request.params[1].isNull()) {
|
||||||
FeeEstimateMode fee_mode;
|
FeeEstimateMode fee_mode;
|
||||||
@ -939,7 +940,8 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
|
|||||||
|
|
||||||
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true);
|
RPCTypeCheck(request.params, {UniValue::VNUM, UniValue::VNUM}, true);
|
||||||
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
|
||||||
unsigned int conf_target = ParseConfirmTarget(request.params[0]);
|
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
|
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||||
double threshold = 0.95;
|
double threshold = 0.95;
|
||||||
if (!request.params[1].isNull()) {
|
if (!request.params[1].isNull()) {
|
||||||
threshold = request.params[1].get_real();
|
threshold = request.params[1].get_real();
|
||||||
|
@ -4,12 +4,10 @@
|
|||||||
|
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <keystore.h>
|
#include <keystore.h>
|
||||||
#include <policy/fees.h>
|
|
||||||
#include <pubkey.h>
|
#include <pubkey.h>
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
#include <tinyformat.h>
|
#include <tinyformat.h>
|
||||||
#include <util/strencodings.h>
|
#include <util/strencodings.h>
|
||||||
#include <validation.h>
|
|
||||||
|
|
||||||
InitInterfaces* g_rpc_interfaces = nullptr;
|
InitInterfaces* g_rpc_interfaces = nullptr;
|
||||||
|
|
||||||
@ -96,10 +94,9 @@ UniValue DescribeAddress(const CTxDestination& dest)
|
|||||||
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ParseConfirmTarget(const UniValue& value)
|
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target)
|
||||||
{
|
{
|
||||||
int target = value.get_int();
|
int target = value.get_int();
|
||||||
unsigned int max_target = ::feeEstimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
|
||||||
if (target < 1 || (unsigned int)target > max_target) {
|
if (target < 1 || (unsigned int)target > max_target) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u - %u", 1, max_target));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid conf_target, must be between %u - %u", 1, max_target));
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
|
|||||||
UniValue DescribeAddress(const CTxDestination& dest);
|
UniValue DescribeAddress(const CTxDestination& dest);
|
||||||
|
|
||||||
//! Parse a confirm target option and raise an RPC error if it is invalid.
|
//! Parse a confirm target option and raise an RPC error if it is invalid.
|
||||||
unsigned int ParseConfirmTarget(const UniValue& value);
|
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
|
||||||
|
|
||||||
/** Returns, given services flags, a list of humanly readable (known) network services */
|
/** Returns, given services flags, a list of humanly readable (known) network services */
|
||||||
UniValue GetServicesNames(ServiceFlags services);
|
UniValue GetServicesNames(ServiceFlags services);
|
||||||
|
@ -55,7 +55,7 @@ void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_s
|
|||||||
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
|
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
|
||||||
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
|
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
|
||||||
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
|
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
|
||||||
void CClientUIInterface::LoadWallet(std::shared_ptr<CWallet> wallet) { return g_ui_signals.LoadWallet(wallet); }
|
void CClientUIInterface::LoadWallet(std::unique_ptr<interfaces::Wallet>& wallet) { return g_ui_signals.LoadWallet(wallet); }
|
||||||
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
|
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
|
||||||
void CClientUIInterface::NotifyBlockTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(b, i); }
|
void CClientUIInterface::NotifyBlockTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(b, i); }
|
||||||
void CClientUIInterface::NotifyChainLock(const std::string& bestChainLockHash, int bestChainLockHeight) { return g_ui_signals.NotifyChainLock(bestChainLockHash, bestChainLockHeight); }
|
void CClientUIInterface::NotifyChainLock(const std::string& bestChainLockHash, int bestChainLockHeight) { return g_ui_signals.NotifyChainLock(bestChainLockHash, bestChainLockHeight); }
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class CWallet;
|
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
class CDeterministicMNList;
|
class CDeterministicMNList;
|
||||||
namespace boost {
|
namespace boost {
|
||||||
@ -20,6 +19,10 @@ class connection;
|
|||||||
}
|
}
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
namespace interfaces {
|
||||||
|
class Wallet;
|
||||||
|
} // namespace interfaces
|
||||||
|
|
||||||
/** General change type (added, updated, removed). */
|
/** General change type (added, updated, removed). */
|
||||||
enum ChangeType
|
enum ChangeType
|
||||||
{
|
{
|
||||||
@ -102,7 +105,7 @@ public:
|
|||||||
ADD_SIGNALS_DECL_WRAPPER(NotifyAlertChanged, void, );
|
ADD_SIGNALS_DECL_WRAPPER(NotifyAlertChanged, void, );
|
||||||
|
|
||||||
/** A wallet has been loaded. */
|
/** A wallet has been loaded. */
|
||||||
ADD_SIGNALS_DECL_WRAPPER(LoadWallet, void, std::shared_ptr<CWallet> wallet);
|
ADD_SIGNALS_DECL_WRAPPER(LoadWallet, void, std::unique_ptr<interfaces::Wallet>& wallet);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show progress e.g. for verifychain.
|
* Show progress e.g. for verifychain.
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <wallet/fees.h>
|
#include <wallet/fees.h>
|
||||||
|
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <txmempool.h>
|
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <wallet/coincontrol.h>
|
#include <wallet/coincontrol.h>
|
||||||
@ -18,9 +17,9 @@ CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes)
|
|||||||
return GetRequiredFeeRate(wallet).GetFee(nTxBytes);
|
return GetRequiredFeeRate(wallet).GetFee(nTxBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
|
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc)
|
||||||
{
|
{
|
||||||
CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, pool, estimator, feeCalc).GetFee(nTxBytes);
|
CAmount fee_needed = GetMinimumFeeRate(wallet, coin_control, feeCalc).GetFee(nTxBytes);
|
||||||
// Always obey the maximum
|
// Always obey the maximum
|
||||||
if (fee_needed > maxTxFee) {
|
if (fee_needed > maxTxFee) {
|
||||||
fee_needed = maxTxFee;
|
fee_needed = maxTxFee;
|
||||||
@ -34,7 +33,7 @@ CFeeRate GetRequiredFeeRate(const CWallet& wallet)
|
|||||||
return std::max(wallet.m_min_fee, ::minRelayTxFee);
|
return std::max(wallet.m_min_fee, ::minRelayTxFee);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc)
|
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc)
|
||||||
{
|
{
|
||||||
/* User control of how to calculate fee uses the following parameter precedence:
|
/* User control of how to calculate fee uses the following parameter precedence:
|
||||||
1. coin_control.m_feerate
|
1. coin_control.m_feerate
|
||||||
@ -63,14 +62,14 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
|||||||
if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
|
if (coin_control.m_fee_mode == FeeEstimateMode::CONSERVATIVE) conservative_estimate = true;
|
||||||
else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;
|
else if (coin_control.m_fee_mode == FeeEstimateMode::ECONOMICAL) conservative_estimate = false;
|
||||||
|
|
||||||
feerate_needed = estimator.estimateSmartFee(target, feeCalc, conservative_estimate);
|
feerate_needed = wallet.chain().estimateSmartFee(target, conservative_estimate, feeCalc);
|
||||||
if (feerate_needed == CFeeRate(0)) {
|
if (feerate_needed == CFeeRate(0)) {
|
||||||
// if we don't have enough data for estimateSmartFee, then use fallback fee
|
// if we don't have enough data for estimateSmartFee, then use fallback fee
|
||||||
feerate_needed = wallet.m_fallback_fee;
|
feerate_needed = wallet.m_fallback_fee;
|
||||||
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
|
if (feeCalc) feeCalc->reason = FeeReason::FALLBACK;
|
||||||
}
|
}
|
||||||
// Obey mempool min fee when using smart fee estimation
|
// Obey mempool min fee when using smart fee estimation
|
||||||
CFeeRate min_mempool_feerate = pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000);
|
CFeeRate min_mempool_feerate = wallet.chain().mempoolMinFee();
|
||||||
if (feerate_needed < min_mempool_feerate) {
|
if (feerate_needed < min_mempool_feerate) {
|
||||||
feerate_needed = min_mempool_feerate;
|
feerate_needed = min_mempool_feerate;
|
||||||
if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
|
if (feeCalc) feeCalc->reason = FeeReason::MEMPOOL_MIN;
|
||||||
@ -86,10 +85,10 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
|
|||||||
return feerate_needed;
|
return feerate_needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator)
|
CFeeRate GetDiscardRate(const CWallet& wallet)
|
||||||
{
|
{
|
||||||
unsigned int highest_target = estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
unsigned int highest_target = wallet.chain().estimateMaxBlocks();
|
||||||
CFeeRate discard_rate = estimator.estimateSmartFee(highest_target, nullptr /* FeeCalculation */, false /* conservative */);
|
CFeeRate discard_rate = wallet.chain().estimateSmartFee(highest_target, false /* conservative */);
|
||||||
// Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
|
// Don't let discard_rate be greater than longest possible fee estimate if we get a valid fee estimate
|
||||||
discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
|
discard_rate = (discard_rate == CFeeRate(0)) ? wallet.m_discard_rate : std::min(discard_rate, wallet.m_discard_rate);
|
||||||
// Discard rate must be at least dustRelayFee
|
// Discard rate must be at least dustRelayFee
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
|
|
||||||
#include <amount.h>
|
#include <amount.h>
|
||||||
|
|
||||||
class CBlockPolicyEstimator;
|
|
||||||
class CCoinControl;
|
class CCoinControl;
|
||||||
class CFeeRate;
|
class CFeeRate;
|
||||||
class CTxMemPool;
|
|
||||||
class CWallet;
|
class CWallet;
|
||||||
struct FeeCalculation;
|
struct FeeCalculation;
|
||||||
|
|
||||||
@ -25,7 +23,7 @@ CAmount GetRequiredFee(const CWallet& wallet, unsigned int nTxBytes);
|
|||||||
* Estimate the minimum fee considering user set parameters
|
* Estimate the minimum fee considering user set parameters
|
||||||
* and the required fee
|
* and the required fee
|
||||||
*/
|
*/
|
||||||
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc);
|
CAmount GetMinimumFee(const CWallet& wallet, unsigned int nTxBytes, const CCoinControl& coin_control, FeeCalculation* feeCalc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the minimum required feerate taking into account the
|
* Return the minimum required feerate taking into account the
|
||||||
@ -37,11 +35,11 @@ CFeeRate GetRequiredFeeRate(const CWallet& wallet);
|
|||||||
* Estimate the minimum fee rate considering user set parameters
|
* Estimate the minimum fee rate considering user set parameters
|
||||||
* and the required fee
|
* and the required fee
|
||||||
*/
|
*/
|
||||||
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, const CTxMemPool& pool, const CBlockPolicyEstimator& estimator, FeeCalculation* feeCalc);
|
CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_control, FeeCalculation* feeCalc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the maximum feerate for discarding change.
|
* Return the maximum feerate for discarding change.
|
||||||
*/
|
*/
|
||||||
CFeeRate GetDiscardRate(const CWallet& wallet, const CBlockPolicyEstimator& estimator);
|
CFeeRate GetDiscardRate(const CWallet& wallet);
|
||||||
|
|
||||||
#endif // BITCOIN_WALLET_FEES_H
|
#endif // BITCOIN_WALLET_FEES_H
|
||||||
|
@ -264,12 +264,15 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
|
|||||||
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
|
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
|
||||||
fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
|
fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
|
||||||
if (error || !fs::exists(wallet_dir)) {
|
if (error || !fs::exists(wallet_dir)) {
|
||||||
return InitError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
|
chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), wallet_dir.string()));
|
||||||
|
return false;
|
||||||
} else if (!fs::is_directory(wallet_dir)) {
|
} else if (!fs::is_directory(wallet_dir)) {
|
||||||
return InitError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
|
chain.initError(strprintf(_("Specified -walletdir \"%s\" is not a directory"), wallet_dir.string()));
|
||||||
|
return false;
|
||||||
// The canonical path transforms relative paths into absolute ones, so we check the non-canonical version
|
// The canonical path transforms relative paths into absolute ones, so we check the non-canonical version
|
||||||
} else if (!wallet_dir.is_absolute()) {
|
} else if (!wallet_dir.is_absolute()) {
|
||||||
return InitError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
|
chain.initError(strprintf(_("Specified -walletdir \"%s\" is a relative path"), wallet_dir.string()));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
|
gArgs.ForceSetArg("-walletdir", canonical_wallet_dir.string());
|
||||||
}
|
}
|
||||||
@ -290,14 +293,15 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
|
|||||||
WalletLocation location(wallet_file);
|
WalletLocation location(wallet_file);
|
||||||
|
|
||||||
if (!wallet_paths.insert(location.GetPath()).second) {
|
if (!wallet_paths.insert(location.GetPath()).second) {
|
||||||
return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file));
|
chain.initError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string error_string;
|
std::string error_string;
|
||||||
std::string warning_string;
|
std::string warning_string;
|
||||||
bool verify_success = CWallet::Verify(chain, location, salvage_wallet, error_string, warning_string);
|
bool verify_success = CWallet::Verify(chain, location, salvage_wallet, error_string, warning_string);
|
||||||
if (!error_string.empty()) InitError(error_string);
|
if (!error_string.empty()) chain.initError(error_string);
|
||||||
if (!warning_string.empty()) InitWarning(warning_string);
|
if (!warning_string.empty()) chain.initWarning(warning_string);
|
||||||
if (!verify_success) return false;
|
if (!verify_success) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,8 +136,9 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
|||||||
if (!request.params[2].isNull())
|
if (!request.params[2].isNull())
|
||||||
fRescan = request.params[2].get_bool();
|
fRescan = request.params[2].get_bool();
|
||||||
|
|
||||||
if (fRescan && fPruneMode)
|
if (fRescan && pwallet->chain().getPruneMode()) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||||
|
}
|
||||||
|
|
||||||
if (fRescan && !reserver.reserve()) {
|
if (fRescan && !reserver.reserve()) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
|
||||||
@ -282,7 +283,7 @@ UniValue importaddress(const JSONRPCRequest& request)
|
|||||||
if (!request.params[2].isNull())
|
if (!request.params[2].isNull())
|
||||||
fRescan = request.params[2].get_bool();
|
fRescan = request.params[2].get_bool();
|
||||||
|
|
||||||
if (fRescan && fPruneMode)
|
if (fRescan && pwallet->chain().getPruneMode())
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||||
|
|
||||||
WalletRescanReserver reserver(pwallet);
|
WalletRescanReserver reserver(pwallet);
|
||||||
@ -473,7 +474,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
|
|||||||
if (!request.params[2].isNull())
|
if (!request.params[2].isNull())
|
||||||
fRescan = request.params[2].get_bool();
|
fRescan = request.params[2].get_bool();
|
||||||
|
|
||||||
if (fRescan && fPruneMode)
|
if (fRescan && pwallet->chain().getPruneMode())
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Rescan is disabled in pruned mode");
|
||||||
|
|
||||||
WalletRescanReserver reserver(pwallet);
|
WalletRescanReserver reserver(pwallet);
|
||||||
@ -531,7 +532,7 @@ UniValue importwallet(const JSONRPCRequest& request)
|
|||||||
},
|
},
|
||||||
}.ToString());
|
}.ToString());
|
||||||
|
|
||||||
if (fPruneMode)
|
if (pwallet->chain().getPruneMode())
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode");
|
||||||
|
|
||||||
WalletRescanReserver reserver(pwallet);
|
WalletRescanReserver reserver(pwallet);
|
||||||
|
@ -302,7 +302,7 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet
|
|||||||
if (nValue > curBalance)
|
if (nValue > curBalance)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
|
||||||
|
|
||||||
if (pwallet->GetBroadcastTransactions() && !g_connman) {
|
if (pwallet->GetBroadcastTransactions() && !pwallet->chain().p2pEnabled()) {
|
||||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet
|
|||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, reservekey, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, reservekey, state)) {
|
||||||
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
|
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
}
|
}
|
||||||
@ -414,7 +414,7 @@ static UniValue sendtoaddress(const JSONRPCRequest& request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!request.params[7].isNull()) {
|
if (!request.params[7].isNull()) {
|
||||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[7]);
|
coin_control.m_confirm_target = ParseConfirmTarget(request.params[7], pwallet->chain().estimateMaxBlocks());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request.params[8].isNull()) {
|
if (!request.params[8].isNull()) {
|
||||||
@ -653,7 +653,6 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request)
|
|||||||
// the user could have gotten from another RPC command prior to now
|
// the user could have gotten from another RPC command prior to now
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
|
||||||
auto locked_chain = pwallet->chain().lock();
|
auto locked_chain = pwallet->chain().lock();
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
|
|
||||||
@ -677,8 +676,9 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request)
|
|||||||
CAmount nAmount = 0;
|
CAmount nAmount = 0;
|
||||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
||||||
const CWalletTx& wtx = pairWtx.second;
|
const CWalletTx& wtx = pairWtx.second;
|
||||||
if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
|
if (wtx.IsCoinBase() || !locked_chain->checkFinalTx(*wtx.tx)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (const CTxOut& txout : wtx.tx->vout)
|
for (const CTxOut& txout : wtx.tx->vout)
|
||||||
if (txout.scriptPubKey == scriptPubKey)
|
if (txout.scriptPubKey == scriptPubKey)
|
||||||
@ -727,7 +727,6 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request)
|
|||||||
// the user could have gotten from another RPC command prior to now
|
// the user could have gotten from another RPC command prior to now
|
||||||
pwallet->BlockUntilSyncedToCurrentChain();
|
pwallet->BlockUntilSyncedToCurrentChain();
|
||||||
|
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
|
||||||
auto locked_chain = pwallet->chain().lock();
|
auto locked_chain = pwallet->chain().lock();
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
|
|
||||||
@ -745,7 +744,7 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request)
|
|||||||
CAmount nAmount = 0;
|
CAmount nAmount = 0;
|
||||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
||||||
const CWalletTx& wtx = pairWtx.second;
|
const CWalletTx& wtx = pairWtx.second;
|
||||||
if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
|
if (wtx.IsCoinBase() || !locked_chain->checkFinalTx(*wtx.tx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (const CTxOut& txout : wtx.tx->vout)
|
for (const CTxOut& txout : wtx.tx->vout)
|
||||||
@ -919,7 +918,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
|
|||||||
auto locked_chain = pwallet->chain().lock();
|
auto locked_chain = pwallet->chain().lock();
|
||||||
LOCK2(mempool.cs, pwallet->cs_wallet);
|
LOCK2(mempool.cs, pwallet->cs_wallet);
|
||||||
|
|
||||||
if (pwallet->GetBroadcastTransactions() && !g_connman) {
|
if (pwallet->GetBroadcastTransactions() && !pwallet->chain().p2pEnabled()) {
|
||||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,7 +948,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!request.params[8].isNull()) {
|
if (!request.params[8].isNull()) {
|
||||||
coin_control.m_confirm_target = ParseConfirmTarget(request.params[8]);
|
coin_control.m_confirm_target = ParseConfirmTarget(request.params[8], pwallet->chain().estimateMaxBlocks());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request.params[9].isNull()) {
|
if (!request.params[9].isNull()) {
|
||||||
@ -1012,7 +1011,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
|
|||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, keyChange, g_connman.get(), state)) {
|
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, keyChange, state)) {
|
||||||
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
|
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
|
||||||
}
|
}
|
||||||
@ -1110,8 +1109,6 @@ struct tallyitem
|
|||||||
|
|
||||||
static UniValue ListReceived(interfaces::Chain::Lock& locked_chain, CWallet * const pwallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
|
static UniValue ListReceived(interfaces::Chain::Lock& locked_chain, CWallet * const pwallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
|
||||||
{
|
{
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
|
||||||
|
|
||||||
// Minimum confirmations
|
// Minimum confirmations
|
||||||
int nMinDepth = 1;
|
int nMinDepth = 1;
|
||||||
if (!params[0].isNull())
|
if (!params[0].isNull())
|
||||||
@ -1145,7 +1142,7 @@ static UniValue ListReceived(interfaces::Chain::Lock& locked_chain, CWallet * co
|
|||||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
for (const std::pair<const uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
|
||||||
const CWalletTx& wtx = pairWtx.second;
|
const CWalletTx& wtx = pairWtx.second;
|
||||||
|
|
||||||
if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
|
if (wtx.IsCoinBase() || !locked_chain.checkFinalTx(*wtx.tx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
int nDepth = wtx.GetDepthInMainChain(locked_chain);
|
||||||
@ -2776,7 +2773,7 @@ static UniValue upgradetohd(const JSONRPCRequest& request)
|
|||||||
SecureString secureMnemonic;
|
SecureString secureMnemonic;
|
||||||
secureMnemonic.reserve(256);
|
secureMnemonic.reserve(256);
|
||||||
if (!generate_mnemonic) {
|
if (!generate_mnemonic) {
|
||||||
if (::ChainstateActive().IsInitialBlockDownload()) {
|
if (pwallet->chain().isInitialBlockDownload()) {
|
||||||
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Cannot set mnemonic while still in Initial Block Download");
|
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Cannot set mnemonic while still in Initial Block Download");
|
||||||
}
|
}
|
||||||
secureMnemonic = request.params[0].get_str().c_str();
|
secureMnemonic = request.params[0].get_str().c_str();
|
||||||
@ -3040,7 +3037,7 @@ static UniValue resendwallettransactions(const JSONRPCRequest& request)
|
|||||||
}.ToString()
|
}.ToString()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!g_connman)
|
if (!pwallet->chain().p2pEnabled())
|
||||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||||
|
|
||||||
auto locked_chain = pwallet->chain().lock();
|
auto locked_chain = pwallet->chain().lock();
|
||||||
@ -3050,7 +3047,7 @@ static UniValue resendwallettransactions(const JSONRPCRequest& request)
|
|||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(*locked_chain, GetTime(), g_connman.get());
|
std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(*locked_chain, GetTime());
|
||||||
UniValue result(UniValue::VARR);
|
UniValue result(UniValue::VARR);
|
||||||
for (const uint256& txid : txids)
|
for (const uint256& txid : txids)
|
||||||
{
|
{
|
||||||
@ -3332,7 +3329,7 @@ void FundTransaction(CWallet* const pwallet, CMutableTransaction& tx, CAmount& f
|
|||||||
if (options.exists("feeRate")) {
|
if (options.exists("feeRate")) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
|
||||||
}
|
}
|
||||||
coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
|
coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"], pwallet->chain().estimateMaxBlocks());
|
||||||
}
|
}
|
||||||
if (options.exists("estimate_mode")) {
|
if (options.exists("estimate_mode")) {
|
||||||
if (options.exists("feeRate")) {
|
if (options.exists("feeRate")) {
|
||||||
|
@ -95,7 +95,7 @@ public:
|
|||||||
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {{GetScriptForDestination(tallyItem.txdest), nAmount, false}}, tx, reserveKey, nFeeRet, nChangePosRet, strError, coinControl));
|
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {{GetScriptForDestination(tallyItem.txdest), nAmount, false}}, tx, reserveKey, nFeeRet, nChangePosRet, strError, coinControl));
|
||||||
}
|
}
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reserveKey, nullptr, state));
|
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reserveKey, state));
|
||||||
AddTxToChain(tx->GetHash());
|
AddTxToChain(tx->GetHash());
|
||||||
for (size_t n = 0; n < tx->vout.size(); ++n) {
|
for (size_t n = 0; n < tx->vout.size(); ++n) {
|
||||||
if (nChangePosRet != -1 && n == nChangePosRet) {
|
if (nChangePosRet != -1 && n == nChangePosRet) {
|
||||||
|
@ -373,7 +373,7 @@ public:
|
|||||||
CCoinControl dummy;
|
CCoinControl dummy;
|
||||||
BOOST_CHECK(wallet->CreateTransaction(*m_locked_chain, {recipient}, tx, reservekey, fee, changePos, error, dummy));
|
BOOST_CHECK(wallet->CreateTransaction(*m_locked_chain, {recipient}, tx, reservekey, fee, changePos, error, dummy));
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reservekey, nullptr, state));
|
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reservekey, state));
|
||||||
CMutableTransaction blocktx;
|
CMutableTransaction blocktx;
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
@ -581,7 +581,7 @@ public:
|
|||||||
CCoinControl coinControl;
|
CCoinControl coinControl;
|
||||||
BOOST_CHECK(wallet->CreateTransaction(*wallet->chain().lock(), GetRecipients(vecEntries), tx, reserveKey, nFeeRet, nChangePosRet, strError, coinControl));
|
BOOST_CHECK(wallet->CreateTransaction(*wallet->chain().lock(), GetRecipients(vecEntries), tx, reserveKey, nFeeRet, nChangePosRet, strError, coinControl));
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reserveKey, nullptr, state));
|
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reserveKey, state));
|
||||||
CMutableTransaction blocktx;
|
CMutableTransaction blocktx;
|
||||||
{
|
{
|
||||||
LOCK(wallet->cs_wallet);
|
LOCK(wallet->cs_wallet);
|
||||||
@ -927,7 +927,7 @@ BOOST_FIXTURE_TEST_CASE(select_coins_grouped_by_addresses, ListCoinsTestingSetup
|
|||||||
tx2, reservekey2, fee, changePos, error, dummy));
|
tx2, reservekey2, fee, changePos, error, dummy));
|
||||||
}
|
}
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
BOOST_CHECK(wallet->CommitTransaction(tx1, {}, {}, reservekey1, nullptr, state));
|
BOOST_CHECK(wallet->CommitTransaction(tx1, {}, {}, reservekey1, state));
|
||||||
reservekey2.KeepKey();
|
reservekey2.KeepKey();
|
||||||
BOOST_CHECK_EQUAL(wallet->GetAvailableBalance(), 0);
|
BOOST_CHECK_EQUAL(wallet->GetAvailableBalance(), 0);
|
||||||
CreateAndProcessBlock({CMutableTransaction(*tx2)}, GetScriptForRawPubKey({}));
|
CreateAndProcessBlock({CMutableTransaction(*tx2)}, GetScriptForRawPubKey({}));
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <crypto/common.h>
|
#include <crypto/common.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <interfaces/chain.h>
|
#include <interfaces/chain.h>
|
||||||
|
#include <interfaces/wallet.h>
|
||||||
#include <key.h>
|
#include <key.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <keystore.h>
|
#include <keystore.h>
|
||||||
@ -1079,7 +1080,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
|||||||
wtx.BindWallet(this);
|
wtx.BindWallet(this);
|
||||||
bool fInsertedNew = ret.second;
|
bool fInsertedNew = ret.second;
|
||||||
if (fInsertedNew) {
|
if (fInsertedNew) {
|
||||||
wtx.nTimeReceived = GetAdjustedTime();
|
wtx.nTimeReceived = chain().getAdjustedTime();
|
||||||
wtx.nOrderPos = IncOrderPosNext(&batch);
|
wtx.nOrderPos = IncOrderPosNext(&batch);
|
||||||
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
||||||
wtx.nTimeSmart = ComputeTimeSmart(wtx);
|
wtx.nTimeSmart = ComputeTimeSmart(wtx);
|
||||||
@ -2301,21 +2302,21 @@ void CWallet::ReacceptWalletTransactions()
|
|||||||
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
|
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
|
||||||
CWalletTx& wtx = *(item.second);
|
CWalletTx& wtx = *(item.second);
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
wtx.AcceptToMemoryPool(*locked_chain, maxTxFee, state);
|
wtx.AcceptToMemoryPool(*locked_chain, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain, CConnman* connman)
|
bool CWalletTx::RelayWalletTransaction(interfaces::Chain::Lock& locked_chain)
|
||||||
{
|
{
|
||||||
assert(pwallet->GetBroadcastTransactions());
|
assert(pwallet->GetBroadcastTransactions());
|
||||||
if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain(locked_chain) == 0)
|
if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain(locked_chain) == 0)
|
||||||
{
|
{
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
/* GetDepthInMainChain already catches known conflicts. */
|
/* GetDepthInMainChain already catches known conflicts. */
|
||||||
if (InMempool() || AcceptToMemoryPool(locked_chain, maxTxFee, state)) {
|
if (InMempool() || AcceptToMemoryPool(locked_chain, state)) {
|
||||||
pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
|
pwallet->WalletLogPrintf("Relaying wtx %s\n", GetHash().ToString());
|
||||||
if (connman) {
|
if (pwallet->chain().p2pEnabled()) {
|
||||||
connman->RelayTransaction(*tx);
|
pwallet->chain().relayTransaction(GetHash());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2576,10 +2577,8 @@ bool CWalletTx::InMempool() const
|
|||||||
|
|
||||||
bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain) const
|
bool CWalletTx::IsTrusted(interfaces::Chain::Lock& locked_chain) const
|
||||||
{
|
{
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
|
||||||
|
|
||||||
// Quick answer in most cases
|
// Quick answer in most cases
|
||||||
if (!CheckFinalTx(*tx))
|
if (!locked_chain.checkFinalTx(*tx))
|
||||||
return false;
|
return false;
|
||||||
int nDepth = GetDepthInMainChain(locked_chain);
|
int nDepth = GetDepthInMainChain(locked_chain);
|
||||||
if (nDepth >= 1)
|
if (nDepth >= 1)
|
||||||
@ -2618,7 +2617,7 @@ bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
|
|||||||
return CTransaction(tx1) == CTransaction(tx2);
|
return CTransaction(tx1) == CTransaction(tx2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime, CConnman* connman)
|
std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime)
|
||||||
{
|
{
|
||||||
std::vector<uint256> result;
|
std::vector<uint256> result;
|
||||||
|
|
||||||
@ -2637,7 +2636,7 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::
|
|||||||
for (const std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
|
for (const std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
|
||||||
{
|
{
|
||||||
CWalletTx& wtx = *item.second;
|
CWalletTx& wtx = *item.second;
|
||||||
if (wtx.RelayWalletTransaction(locked_chain, connman))
|
if (wtx.RelayWalletTransaction(locked_chain))
|
||||||
result.push_back(wtx.GetHash());
|
result.push_back(wtx.GetHash());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -2662,7 +2661,7 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman
|
|||||||
// Rebroadcast unconfirmed txes older than 5 minutes before the last
|
// Rebroadcast unconfirmed txes older than 5 minutes before the last
|
||||||
// block was found:
|
// block was found:
|
||||||
auto locked_chain = chain().assumeLocked(); // Temporary. Removed in upcoming lock cleanup
|
auto locked_chain = chain().assumeLocked(); // Temporary. Removed in upcoming lock cleanup
|
||||||
std::vector<uint256> relayed = ResendWalletTransactionsBefore(*locked_chain, nBestBlockTime-5*60, connman);
|
std::vector<uint256> relayed = ResendWalletTransactionsBefore(*locked_chain, nBestBlockTime-5*60);
|
||||||
if (!relayed.empty())
|
if (!relayed.empty())
|
||||||
WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
|
WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
|
||||||
}
|
}
|
||||||
@ -2807,7 +2806,6 @@ CAmount CWallet::GetNormalizedAnonymizedBalance() const
|
|||||||
// trusted.
|
// trusted.
|
||||||
CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, const bool fAddLocked) const
|
CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, const bool fAddLocked) const
|
||||||
{
|
{
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
|
||||||
auto locked_chain = chain().lock();
|
auto locked_chain = chain().lock();
|
||||||
LOCK(cs_wallet);
|
LOCK(cs_wallet);
|
||||||
|
|
||||||
@ -2815,7 +2813,7 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, cons
|
|||||||
for (const auto& entry : mapWallet) {
|
for (const auto& entry : mapWallet) {
|
||||||
const CWalletTx& wtx = entry.second;
|
const CWalletTx& wtx = entry.second;
|
||||||
const int depth = wtx.GetDepthInMainChain(*locked_chain);
|
const int depth = wtx.GetDepthInMainChain(*locked_chain);
|
||||||
if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase(*locked_chain)) {
|
if (depth < 0 || !locked_chain->checkFinalTx(*wtx.tx) || wtx.IsImmatureCoinBase(*locked_chain)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2869,7 +2867,7 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
|||||||
for (auto pcoin : GetSpendableTXs()) {
|
for (auto pcoin : GetSpendableTXs()) {
|
||||||
const uint256& wtxid = pcoin->GetHash();
|
const uint256& wtxid = pcoin->GetHash();
|
||||||
|
|
||||||
if (!CheckFinalTx(*pcoin->tx))
|
if (!locked_chain.checkFinalTx(*pcoin->tx))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pcoin->IsImmatureCoinBase(locked_chain))
|
if (pcoin->IsImmatureCoinBase(locked_chain))
|
||||||
@ -3044,10 +3042,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
|
|||||||
FeeCalculation feeCalc;
|
FeeCalculation feeCalc;
|
||||||
CCoinControl temp;
|
CCoinControl temp;
|
||||||
temp.m_confirm_target = 1008;
|
temp.m_confirm_target = 1008;
|
||||||
CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, ::mempool, ::feeEstimator, &feeCalc);
|
CFeeRate long_term_feerate = GetMinimumFeeRate(*this, temp, &feeCalc);
|
||||||
|
|
||||||
// Calculate cost of change
|
// Calculate cost of change
|
||||||
CAmount cost_of_change = GetDiscardRate(*this, ::feeEstimator).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
|
CAmount cost_of_change = GetDiscardRate(*this).GetFee(coin_selection_params.change_spend_size) + coin_selection_params.effective_fee.GetFee(coin_selection_params.change_output_size);
|
||||||
|
|
||||||
// Filter by the min conf specs and add to utxo_pool and calculate effective value
|
// Filter by the min conf specs and add to utxo_pool and calculate effective value
|
||||||
for (OutputGroup& group : groups) {
|
for (OutputGroup& group : groups) {
|
||||||
@ -3572,7 +3570,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||||||
txNew.nLockTime = GetLocktimeForNewTransaction(locked_chain);
|
txNew.nLockTime = GetLocktimeForNewTransaction(locked_chain);
|
||||||
|
|
||||||
FeeCalculation feeCalc;
|
FeeCalculation feeCalc;
|
||||||
CFeeRate discard_rate = coin_control.m_discard_feerate ? *coin_control.m_discard_feerate : GetDiscardRate(*this, ::feeEstimator);
|
CFeeRate discard_rate = coin_control.m_discard_feerate ? *coin_control.m_discard_feerate : GetDiscardRate(*this);
|
||||||
unsigned int nBytes{0};
|
unsigned int nBytes{0};
|
||||||
{
|
{
|
||||||
std::vector<CInputCoin> vecCoins;
|
std::vector<CInputCoin> vecCoins;
|
||||||
@ -3727,7 +3725,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||||||
txin.scriptSig = CScript();
|
txin.scriptSig = CScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
nFee = GetMinimumFee(*this, nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
|
nFee = GetMinimumFee(*this, nBytes, coin_control, &feeCalc);
|
||||||
|
|
||||||
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
// If we made it here and we aren't even able to meet the relay fee on the next pass, give up
|
||||||
// because we must be at the maximum allowed fee.
|
// because we must be at the maximum allowed fee.
|
||||||
@ -3905,16 +3903,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||||||
|
|
||||||
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||||
LockPoints lp;
|
if (!chain().checkChainLimits(tx)) {
|
||||||
CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp);
|
|
||||||
CTxMemPool::setEntries setAncestors;
|
|
||||||
size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
|
|
||||||
size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
|
|
||||||
size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
|
|
||||||
size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
|
|
||||||
std::string errString;
|
|
||||||
LOCK(::mempool.cs);
|
|
||||||
if (!::mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
|
|
||||||
strFailReason = _("Transaction has too long of a mempool chain");
|
strFailReason = _("Transaction has too long of a mempool chain");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3934,7 +3923,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
|||||||
/**
|
/**
|
||||||
* Call after CreateTransaction unless you want to abort
|
* Call after CreateTransaction unless you want to abort
|
||||||
*/
|
*/
|
||||||
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
|
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CValidationState& state)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
auto locked_chain = chain().lock();
|
auto locked_chain = chain().lock();
|
||||||
@ -3976,11 +3965,11 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
|||||||
if (fBroadcastTransactions)
|
if (fBroadcastTransactions)
|
||||||
{
|
{
|
||||||
// Broadcast
|
// Broadcast
|
||||||
if (!wtx.AcceptToMemoryPool(*locked_chain, maxTxFee, state)) {
|
if (!wtx.AcceptToMemoryPool(*locked_chain, state)) {
|
||||||
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", FormatStateMessage(state));
|
WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", FormatStateMessage(state));
|
||||||
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
||||||
} else {
|
} else {
|
||||||
wtx.RelayWalletTransaction(*locked_chain, connman);
|
wtx.RelayWalletTransaction(*locked_chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4929,17 +4918,17 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
std::vector<CWalletTx> vWtx;
|
std::vector<CWalletTx> vWtx;
|
||||||
|
|
||||||
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
|
if (gArgs.GetBoolArg("-zapwallettxes", false)) {
|
||||||
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
chain.initMessage(_("Zapping all transactions from wallet..."));
|
||||||
|
|
||||||
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(chain, location, WalletDatabase::Create(location.GetPath()));
|
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(chain, location, WalletDatabase::Create(location.GetPath()));
|
||||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||||
if (nZapWalletRet != DBErrors::LOAD_OK) {
|
if (nZapWalletRet != DBErrors::LOAD_OK) {
|
||||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
chain.initError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Loading wallet..."));
|
chain.initMessage(_("Loading wallet..."));
|
||||||
|
|
||||||
int64_t nStart = GetTimeMillis();
|
int64_t nStart = GetTimeMillis();
|
||||||
bool fFirstRun = true;
|
bool fFirstRun = true;
|
||||||
@ -4949,7 +4938,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
AddWallet(walletInstance);
|
AddWallet(walletInstance);
|
||||||
auto error = [&](const std::string& strError) {
|
auto error = [&](const std::string& strError) {
|
||||||
RemoveWallet(walletInstance);
|
RemoveWallet(walletInstance);
|
||||||
InitError(strError);
|
chain.initError(strError);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
DBErrors nLoadWalletRet;
|
DBErrors nLoadWalletRet;
|
||||||
@ -4966,7 +4955,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
}
|
}
|
||||||
else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
|
else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
|
||||||
{
|
{
|
||||||
InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
|
chain.initWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
|
||||||
" or address book entries might be missing or incorrect."),
|
" or address book entries might be missing or incorrect."),
|
||||||
walletFile));
|
walletFile));
|
||||||
}
|
}
|
||||||
@ -5055,7 +5044,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
std::string strBackupError;
|
std::string strBackupError;
|
||||||
if(!walletInstance->AutoBackupWallet("", strBackupWarning, strBackupError)) {
|
if(!walletInstance->AutoBackupWallet("", strBackupWarning, strBackupError)) {
|
||||||
if (!strBackupWarning.empty()) {
|
if (!strBackupWarning.empty()) {
|
||||||
InitWarning(strBackupWarning);
|
chain.initWarning(strBackupWarning);
|
||||||
}
|
}
|
||||||
if (!strBackupError.empty()) {
|
if (!strBackupError.empty()) {
|
||||||
return error(strBackupError);
|
return error(strBackupError);
|
||||||
@ -5063,12 +5052,12 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
}
|
}
|
||||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||||
// Make it impossible to disable private keys after creation
|
// Make it impossible to disable private keys after creation
|
||||||
InitError(strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile));
|
chain.initError(strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile));
|
||||||
return NULL;
|
return NULL;
|
||||||
} else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
} else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||||
LOCK(walletInstance->cs_KeyStore);
|
LOCK(walletInstance->cs_KeyStore);
|
||||||
if (!walletInstance->mapKeys.empty() || !walletInstance->mapCryptedKeys.empty()) {
|
if (!walletInstance->mapKeys.empty() || !walletInstance->mapCryptedKeys.empty()) {
|
||||||
InitWarning(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
|
chain.initWarning(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys"), walletFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (gArgs.IsArgSet("-usehd")) {
|
else if (gArgs.IsArgSet("-usehd")) {
|
||||||
@ -5091,11 +5080,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
if (gArgs.IsArgSet("-mintxfee")) {
|
if (gArgs.IsArgSet("-mintxfee")) {
|
||||||
CAmount n = 0;
|
CAmount n = 0;
|
||||||
if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
|
if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
|
||||||
InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
|
chain.initError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (n > HIGH_TX_FEE_PER_KB) {
|
if (n > HIGH_TX_FEE_PER_KB) {
|
||||||
InitWarning(AmountHighWarn("-mintxfee") + " " +
|
chain.initWarning(AmountHighWarn("-mintxfee") + " " +
|
||||||
_("This is the minimum transaction fee you pay on every transaction."));
|
_("This is the minimum transaction fee you pay on every transaction."));
|
||||||
}
|
}
|
||||||
walletInstance->m_min_fee = CFeeRate(n);
|
walletInstance->m_min_fee = CFeeRate(n);
|
||||||
@ -5106,11 +5095,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
if (gArgs.IsArgSet("-fallbackfee")) {
|
if (gArgs.IsArgSet("-fallbackfee")) {
|
||||||
CAmount nFeePerK = 0;
|
CAmount nFeePerK = 0;
|
||||||
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
|
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
|
||||||
InitError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
|
chain.initError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", "")));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||||
InitWarning(AmountHighWarn("-fallbackfee") + " " +
|
chain.initWarning(AmountHighWarn("-fallbackfee") + " " +
|
||||||
_("This is the transaction fee you may pay when fee estimates are not available."));
|
_("This is the transaction fee you may pay when fee estimates are not available."));
|
||||||
}
|
}
|
||||||
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
|
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
|
||||||
@ -5119,11 +5108,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
if (gArgs.IsArgSet("-discardfee")) {
|
if (gArgs.IsArgSet("-discardfee")) {
|
||||||
CAmount nFeePerK = 0;
|
CAmount nFeePerK = 0;
|
||||||
if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
|
if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
|
||||||
InitError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
|
chain.initError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", "")));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||||
InitWarning(AmountHighWarn("-discardfee") + " " +
|
chain.initWarning(AmountHighWarn("-discardfee") + " " +
|
||||||
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
|
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
|
||||||
}
|
}
|
||||||
walletInstance->m_discard_rate = CFeeRate(nFeePerK);
|
walletInstance->m_discard_rate = CFeeRate(nFeePerK);
|
||||||
@ -5131,16 +5120,16 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
if (gArgs.IsArgSet("-paytxfee")) {
|
if (gArgs.IsArgSet("-paytxfee")) {
|
||||||
CAmount nFeePerK = 0;
|
CAmount nFeePerK = 0;
|
||||||
if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
|
if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
|
||||||
InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
|
chain.initError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||||
InitWarning(AmountHighWarn("-paytxfee") + " " +
|
chain.initWarning(AmountHighWarn("-paytxfee") + " " +
|
||||||
_("This is the transaction fee you will pay if you send a transaction."));
|
_("This is the transaction fee you will pay if you send a transaction."));
|
||||||
}
|
}
|
||||||
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
|
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
|
||||||
if (walletInstance->m_pay_tx_fee < ::minRelayTxFee) {
|
if (walletInstance->m_pay_tx_fee < ::minRelayTxFee) {
|
||||||
InitError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
chain.initError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||||
gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
|
gArgs.GetArg("-paytxfee", ""), ::minRelayTxFee.ToString()));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -5180,7 +5169,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
//We can't rescan beyond non-pruned blocks, stop and throw an error
|
//We can't rescan beyond non-pruned blocks, stop and throw an error
|
||||||
//this might happen if a user uses an old wallet within a pruned node
|
//this might happen if a user uses an old wallet within a pruned node
|
||||||
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
||||||
if (fPruneMode)
|
if (chain.getPruneMode())
|
||||||
{
|
{
|
||||||
int block_height = *tip_height;
|
int block_height = *tip_height;
|
||||||
while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
|
while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
|
||||||
@ -5192,7 +5181,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiInterface.InitMessage(_("Rescanning..."));
|
chain.initMessage(_("Rescanning..."));
|
||||||
walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
|
walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
|
||||||
|
|
||||||
// No need to read and scan block if block was created before
|
// No need to read and scan block if block was created before
|
||||||
@ -5242,7 +5231,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uiInterface.LoadWallet(walletInstance);
|
chain.loadWallet(interfaces::MakeWallet(walletInstance));
|
||||||
|
|
||||||
// Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main.
|
// Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main.
|
||||||
RegisterValidationInterface(walletInstance.get());
|
RegisterValidationInterface(walletInstance.get());
|
||||||
@ -5543,17 +5532,14 @@ bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
|||||||
return GetBlocksToMaturity(locked_chain) > 0;
|
return GetBlocksToMaturity(locked_chain) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletTx::AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, const CAmount& nAbsurdFee, CValidationState& state)
|
bool CWalletTx::AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, CValidationState& state)
|
||||||
{
|
{
|
||||||
LockAnnotation lock(::cs_main); // Temporary, for AcceptToMemoryPool below. Removed in upcoming commit.
|
|
||||||
|
|
||||||
// We must set fInMempool here - while it will be re-set to true by the
|
// We must set fInMempool here - while it will be re-set to true by the
|
||||||
// entered-mempool callback, if we did not there would be a race where a
|
// entered-mempool callback, if we did not there would be a race where a
|
||||||
// user could call sendmoney in a loop and hit spurious out of funds errors
|
// user could call sendmoney in a loop and hit spurious out of funds errors
|
||||||
// because we think that this newly generated transaction's change is
|
// because we think that this newly generated transaction's change is
|
||||||
// unavailable as we're not yet aware that it is in the mempool.
|
// unavailable as we're not yet aware that it is in the mempool.
|
||||||
bool ret = ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
|
bool ret = locked_chain.submitToMemoryPool(tx, pwallet->chain().maxTxFee(), state);
|
||||||
false /* bypass_limits */, nAbsurdFee);
|
|
||||||
fInMempool |= ret;
|
fInMempool |= ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -5567,7 +5553,7 @@ std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outpu
|
|||||||
CInputCoin input_coin = output.GetInputCoin();
|
CInputCoin input_coin = output.GetInputCoin();
|
||||||
|
|
||||||
size_t ancestors, descendants;
|
size_t ancestors, descendants;
|
||||||
mempool.GetTransactionAncestry(output.tx->GetHash(), ancestors, descendants);
|
chain().getTransactionAncestry(output.tx->GetHash(), ancestors, descendants);
|
||||||
if (!single_coin && ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
|
if (!single_coin && ExtractDestination(output.tx->tx->vout[output.i].scriptPubKey, dst)) {
|
||||||
// Limit output groups to no more than 10 entries, to protect
|
// Limit output groups to no more than 10 entries, to protect
|
||||||
// against inadvertently creating a too-large transaction
|
// against inadvertently creating a too-large transaction
|
||||||
|
@ -103,8 +103,6 @@ class COutput;
|
|||||||
class CReserveKey;
|
class CReserveKey;
|
||||||
class CScript;
|
class CScript;
|
||||||
class CTxDSIn;
|
class CTxDSIn;
|
||||||
class CTxMemPool;
|
|
||||||
class CBlockPolicyEstimator;
|
|
||||||
class CWalletTx;
|
class CWalletTx;
|
||||||
struct FeeCalculation;
|
struct FeeCalculation;
|
||||||
enum class FeeEstimateMode;
|
enum class FeeEstimateMode;
|
||||||
@ -542,10 +540,10 @@ public:
|
|||||||
int64_t GetTxTime() const;
|
int64_t GetTxTime() const;
|
||||||
|
|
||||||
// RelayWalletTransaction may only be called if fBroadcastTransactions!
|
// RelayWalletTransaction may only be called if fBroadcastTransactions!
|
||||||
bool RelayWalletTransaction(interfaces::Chain::Lock& locked_chain, CConnman* connman);
|
bool RelayWalletTransaction(interfaces::Chain::Lock& locked_chain);
|
||||||
|
|
||||||
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
|
/** Pass this transaction to the mempool. Fails if absolute fee exceeds absurd fee. */
|
||||||
bool AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, const CAmount& nAbsurdFee, CValidationState& state);
|
bool AcceptToMemoryPool(interfaces::Chain::Lock& locked_chain, CValidationState& state);
|
||||||
|
|
||||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
||||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
||||||
@ -1021,7 +1019,7 @@ public:
|
|||||||
void ReacceptWalletTransactions();
|
void ReacceptWalletTransactions();
|
||||||
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
// ResendWalletTransactionsBefore may only be called if fBroadcastTransactions!
|
// ResendWalletTransactionsBefore may only be called if fBroadcastTransactions!
|
||||||
std::vector<uint256> ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime, CConnman* connman);
|
std::vector<uint256> ResendWalletTransactionsBefore(interfaces::Chain::Lock& locked_chain, int64_t nTime);
|
||||||
struct Balance {
|
struct Balance {
|
||||||
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
|
CAmount m_mine_trusted{0}; //!< Trusted, at depth=GetBalance.min_depth or more
|
||||||
CAmount m_mine_untrusted_pending{0}; //!< Untrusted, but in mempool (pending)
|
CAmount m_mine_untrusted_pending{0}; //!< Untrusted, but in mempool (pending)
|
||||||
@ -1057,7 +1055,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
|
||||||
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true, int nExtraPayloadSize = 0);
|
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true, int nExtraPayloadSize = 0);
|
||||||
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CConnman* connman, CValidationState& state);
|
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CReserveKey& reservekey, CValidationState& state);
|
||||||
|
|
||||||
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
|
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user