mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-21 04:09:09 +02:00
Merge #15288: Remove wallet -> node global function calls
f7efd87c8fChange brace formatting (Russell Yanofsky)a1df1b48a8Remove use of IsInitialBlockDownload in wallet code (Russell Yanofsky)1106a6fde4Remove use of uiInterface.LoadWallet in wallet code (Russell Yanofsky)318f41fb2ccircular-dependencies: Avoid treating some .h/.cpp files as a unit (Russell Yanofsky)d02b34c8a8Remove use of AcceptToMemoryPool in wallet code (Russell Yanofsky)e2c8ba9f6eRemove uses of InitMessage/Warning/Error in wallet code (Russell Yanofsky)c5e59a96a8Remove uses of GetAdjustedTime in wallet code (Russell Yanofsky)6d6bcc77c0Remove use of g_connman / PushInventory in wallet code (Russell Yanofsky)00dfb2a440Remove uses of g_connman in wallet code (Russell Yanofsky)cc3836e8f9Remove uses of fPruneMode in wallet code (Russell Yanofsky)cc02c796d3Remove uses of fee globals in wallet code (Russell Yanofsky)1fb0a4a04eRemove use of CalculateMemPoolAncestors in wallet code (Russell Yanofsky)cd32160af0Remove use of GetTransactionAncestry in wallet code (Russell Yanofsky)291276f7f4Remove use of GetCountWithDescendants in wallet code (Russell Yanofsky)bdc6628683Remove use of IsRBFOptIn in wallet code (Russell Yanofsky)80f52a2267Remove uses of CheckFinalTx in wallet code (Russell Yanofsky) Pull request description: This change removes wallet calls to node functions that access global chain and mempool state. This is the next step in the larger #10973 refactoring change, which removes all other accesses to node global variables from wallet code. Doing this is useful to provide a better defined interface between the wallet and node, and necessary to allow wallet and node code to run in separate processes in #10102. Tree-SHA512: 40dbaf1f59fb22b32e70b054b30ba5638d638aa3240fa30e0f721d53c721cd6138a7ab4d423a24d7d2fda0b956e68d44c733abc2c9259c3d6c9fd6d4be89aa23
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
#include <consensus/validation.h>
|
||||
#include <fs.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <key.h>
|
||||
#include <key_io.h>
|
||||
#include <keystore.h>
|
||||
@@ -940,7 +941,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
||||
wtx.BindWallet(this);
|
||||
bool fInsertedNew = ret.second;
|
||||
if (fInsertedNew) {
|
||||
wtx.nTimeReceived = GetAdjustedTime();
|
||||
wtx.nTimeReceived = chain().getAdjustedTime();
|
||||
wtx.nOrderPos = IncOrderPosNext(&batch);
|
||||
wtx.m_it_wtxOrdered = wtxOrdered.insert(std::make_pair(wtx.nOrderPos, &wtx));
|
||||
wtx.nTimeSmart = ComputeTimeSmart(wtx);
|
||||
@@ -1886,25 +1887,21 @@ void CWallet::ReacceptWalletTransactions()
|
||||
for (const std::pair<const int64_t, CWalletTx*>& item : mapSorted) {
|
||||
CWalletTx& wtx = *(item.second);
|
||||
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());
|
||||
if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain(locked_chain) == 0)
|
||||
{
|
||||
CValidationState state;
|
||||
/* 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());
|
||||
if (connman) {
|
||||
CInv inv(MSG_TX, GetHash());
|
||||
connman->ForEachNode([&inv](CNode* pnode)
|
||||
{
|
||||
pnode->PushInventory(inv);
|
||||
});
|
||||
if (pwallet->chain().p2pEnabled()) {
|
||||
pwallet->chain().relayTransaction(GetHash());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2075,11 +2072,10 @@ bool CWalletTx::InMempool() 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
|
||||
if (!CheckFinalTx(*tx))
|
||||
if (!locked_chain.checkFinalTx(*tx)) {
|
||||
return false;
|
||||
}
|
||||
int nDepth = GetDepthInMainChain(locked_chain);
|
||||
if (nDepth >= 1)
|
||||
return true;
|
||||
@@ -2115,7 +2111,7 @@ bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
|
||||
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;
|
||||
|
||||
@@ -2134,8 +2130,9 @@ std::vector<uint256> CWallet::ResendWalletTransactionsBefore(interfaces::Chain::
|
||||
for (const std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
|
||||
{
|
||||
CWalletTx& wtx = *item.second;
|
||||
if (wtx.RelayWalletTransaction(locked_chain, connman))
|
||||
if (wtx.RelayWalletTransaction(locked_chain)) {
|
||||
result.push_back(wtx.GetHash());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2159,7 +2156,7 @@ void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman
|
||||
// Rebroadcast unconfirmed txes older than 5 minutes before the last
|
||||
// block was found:
|
||||
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())
|
||||
WalletLogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
|
||||
}
|
||||
@@ -2263,7 +2260,6 @@ CAmount CWallet::GetImmatureWatchOnlyBalance() const
|
||||
// trusted.
|
||||
CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth) const
|
||||
{
|
||||
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
|
||||
auto locked_chain = chain().lock();
|
||||
LOCK(cs_wallet);
|
||||
|
||||
@@ -2271,7 +2267,7 @@ CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth) cons
|
||||
for (const auto& entry : mapWallet) {
|
||||
const CWalletTx& wtx = entry.second;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -2325,8 +2321,9 @@ void CWallet::AvailableCoins(interfaces::Chain::Lock& locked_chain, std::vector<
|
||||
const uint256& wtxid = entry.first;
|
||||
const CWalletTx* pcoin = &entry.second;
|
||||
|
||||
if (!CheckFinalTx(*pcoin->tx))
|
||||
if (!locked_chain.checkFinalTx(*pcoin->tx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pcoin->IsImmatureCoinBase(locked_chain))
|
||||
continue;
|
||||
@@ -2488,10 +2485,10 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
|
||||
FeeCalculation feeCalc;
|
||||
CCoinControl temp;
|
||||
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
|
||||
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
|
||||
for (OutputGroup& group : groups) {
|
||||
@@ -2861,10 +2858,10 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
CTxOut change_prototype_txout(0, scriptChange);
|
||||
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
|
||||
|
||||
CFeeRate discard_rate = GetDiscardRate(*this, ::feeEstimator);
|
||||
CFeeRate discard_rate = GetDiscardRate(*this);
|
||||
|
||||
// Get the fee rate to use effective values in coin selection
|
||||
CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, ::mempool, ::feeEstimator, &feeCalc);
|
||||
CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control, &feeCalc);
|
||||
|
||||
nFeeRet = 0;
|
||||
bool pick_new_inputs = true;
|
||||
@@ -2997,7 +2994,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
return false;
|
||||
}
|
||||
|
||||
nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
|
||||
nFeeNeeded = GetMinimumFee(*this, nBytes, coin_control, &feeCalc);
|
||||
if (feeCalc.reason == FeeReason::FALLBACK && !m_allow_fallback_fee) {
|
||||
// eventually allow a fallback fee
|
||||
strFailReason = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
|
||||
@@ -3025,7 +3022,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
// change output. Only try this once.
|
||||
if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
|
||||
unsigned int tx_size_with_change = nBytes + coin_selection_params.change_output_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size
|
||||
CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
|
||||
CAmount fee_needed_with_change = GetMinimumFee(*this, tx_size_with_change, coin_control, nullptr);
|
||||
CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
|
||||
if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
|
||||
pick_new_inputs = false;
|
||||
@@ -3130,16 +3127,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
|
||||
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||
LockPoints lp;
|
||||
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)) {
|
||||
if (!chain().checkChainLimits(tx)) {
|
||||
strFailReason = _("Transaction has too long of a mempool chain");
|
||||
return false;
|
||||
}
|
||||
@@ -3159,7 +3147,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
|
||||
/**
|
||||
* 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();
|
||||
@@ -3196,11 +3184,11 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
|
||||
if (fBroadcastTransactions)
|
||||
{
|
||||
// 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));
|
||||
// TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
|
||||
} else {
|
||||
wtx.RelayWalletTransaction(*locked_chain, connman);
|
||||
wtx.RelayWalletTransaction(*locked_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4092,17 +4080,17 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
std::vector<CWalletTx> vWtx;
|
||||
|
||||
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()));
|
||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||
if (nZapWalletRet != DBErrors::LOAD_OK) {
|
||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||
chain.initError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Loading wallet..."));
|
||||
chain.initMessage(_("Loading wallet..."));
|
||||
|
||||
int64_t nStart = GetTimeMillis();
|
||||
bool fFirstRun = true;
|
||||
@@ -4113,26 +4101,26 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
if (nLoadWalletRet != DBErrors::LOAD_OK)
|
||||
{
|
||||
if (nLoadWalletRet == DBErrors::CORRUPT) {
|
||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||
chain.initError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||
return nullptr;
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
|
||||
{
|
||||
InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
|
||||
" or address book entries might be missing or incorrect."),
|
||||
chain.initWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
|
||||
" or address book entries might be missing or incorrect."),
|
||||
walletFile));
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::TOO_NEW) {
|
||||
InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME)));
|
||||
chain.initError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME)));
|
||||
return nullptr;
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
|
||||
{
|
||||
InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
|
||||
chain.initError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
InitError(strprintf(_("Error loading %s"), walletFile));
|
||||
chain.initError(strprintf(_("Error loading %s"), walletFile));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -4151,7 +4139,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
walletInstance->WalletLogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
|
||||
if (nMaxVersion < walletInstance->GetVersion())
|
||||
{
|
||||
InitError(_("Cannot downgrade wallet"));
|
||||
chain.initError(_("Cannot downgrade wallet"));
|
||||
return nullptr;
|
||||
}
|
||||
walletInstance->SetMaxVersion(nMaxVersion);
|
||||
@@ -4164,7 +4152,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
// Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
|
||||
int max_version = walletInstance->nWalletVersion;
|
||||
if (!walletInstance->CanSupportFeature(FEATURE_HD_SPLIT) && max_version >=FEATURE_HD_SPLIT && max_version < FEATURE_PRE_SPLIT_KEYPOOL) {
|
||||
InitError(_("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified."));
|
||||
chain.initError(_("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified."));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -4192,7 +4180,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
// Regenerate the keypool if upgraded to HD
|
||||
if (hd_upgrade) {
|
||||
if (!walletInstance->TopUpKeyPool()) {
|
||||
InitError(_("Unable to generate keys"));
|
||||
chain.initError(_("Unable to generate keys"));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -4216,7 +4204,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
|
||||
// Top up the keypool
|
||||
if (walletInstance->CanGenerateKeys() && !walletInstance->TopUpKeyPool()) {
|
||||
InitError(_("Unable to generate initial keys"));
|
||||
chain.initError(_("Unable to generate initial keys"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -4224,34 +4212,34 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
walletInstance->ChainStateFlushed(locked_chain->getTipLocator());
|
||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||
// 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;
|
||||
} else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
LOCK(walletInstance->cs_KeyStore);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
|
||||
InitError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
|
||||
chain.initError(strprintf("Unknown address type '%s'", gArgs.GetArg("-addresstype", "")));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
|
||||
InitError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
|
||||
chain.initError(strprintf("Unknown change type '%s'", gArgs.GetArg("-changetype", "")));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (gArgs.IsArgSet("-mintxfee")) {
|
||||
CAmount n = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
|
||||
InitError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
|
||||
chain.initError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")));
|
||||
return nullptr;
|
||||
}
|
||||
if (n > HIGH_TX_FEE_PER_KB) {
|
||||
InitWarning(AmountHighWarn("-mintxfee") + " " +
|
||||
_("This is the minimum transaction fee you pay on every transaction."));
|
||||
chain.initWarning(AmountHighWarn("-mintxfee") + " " +
|
||||
_("This is the minimum transaction fee you pay on every transaction."));
|
||||
}
|
||||
walletInstance->m_min_fee = CFeeRate(n);
|
||||
}
|
||||
@@ -4260,12 +4248,12 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
if (gArgs.IsArgSet("-fallbackfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
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;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
InitWarning(AmountHighWarn("-fallbackfee") + " " +
|
||||
_("This is the transaction fee you may pay when fee estimates are not available."));
|
||||
chain.initWarning(AmountHighWarn("-fallbackfee") + " " +
|
||||
_("This is the transaction fee you may pay when fee estimates are not available."));
|
||||
}
|
||||
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
|
||||
walletInstance->m_allow_fallback_fee = nFeePerK != 0; //disable fallback fee in case value was set to 0, enable if non-null value
|
||||
@@ -4273,28 +4261,28 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
if (gArgs.IsArgSet("-discardfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
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;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
InitWarning(AmountHighWarn("-discardfee") + " " +
|
||||
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
|
||||
chain.initWarning(AmountHighWarn("-discardfee") + " " +
|
||||
_("This is the transaction fee you may discard if change is smaller than dust at this level"));
|
||||
}
|
||||
walletInstance->m_discard_rate = CFeeRate(nFeePerK);
|
||||
}
|
||||
if (gArgs.IsArgSet("-paytxfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
|
||||
InitError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
|
||||
chain.initError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
InitWarning(AmountHighWarn("-paytxfee") + " " +
|
||||
_("This is the transaction fee you will pay if you send a transaction."));
|
||||
chain.initWarning(AmountHighWarn("-paytxfee") + " " +
|
||||
_("This is the transaction fee you will pay if you send a transaction."));
|
||||
}
|
||||
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
|
||||
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()));
|
||||
return nullptr;
|
||||
}
|
||||
@@ -4335,20 +4323,19 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
//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
|
||||
// or if he ran -disablewallet for a longer time, then decided to re-enable
|
||||
if (fPruneMode)
|
||||
{
|
||||
if (chain.getPruneMode()) {
|
||||
int block_height = *tip_height;
|
||||
while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
|
||||
--block_height;
|
||||
}
|
||||
|
||||
if (rescan_height != block_height) {
|
||||
InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
|
||||
chain.initError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uiInterface.InitMessage(_("Rescanning..."));
|
||||
chain.initMessage(_("Rescanning..."));
|
||||
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
|
||||
@@ -4363,7 +4350,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
||||
{
|
||||
WalletRescanReserver reserver(walletInstance.get());
|
||||
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(locked_chain->getBlockHash(rescan_height), {} /* stop block */, reserver, true /* update */).status)) {
|
||||
InitError(_("Failed to rescan the wallet during initialization"));
|
||||
chain.initError(_("Failed to rescan the wallet during initialization"));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -4396,7 +4383,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.
|
||||
RegisterValidationInterface(walletInstance.get());
|
||||
@@ -4479,17 +4466,14 @@ bool CMerkleTx::IsImmatureCoinBase(interfaces::Chain::Lock& locked_chain) const
|
||||
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
|
||||
// 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
|
||||
// because we think that this newly generated transaction's change is
|
||||
// unavailable as we're not yet aware that it is in the mempool.
|
||||
bool ret = ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
|
||||
nullptr /* plTxnReplaced */, false /* bypass_limits */, nAbsurdFee);
|
||||
bool ret = locked_chain.submitToMemoryPool(tx, pwallet->chain().maxTxFee(), state);
|
||||
fInMempool |= ret;
|
||||
return ret;
|
||||
}
|
||||
@@ -4520,7 +4504,7 @@ std::vector<OutputGroup> CWallet::GroupOutputs(const std::vector<COutput>& outpu
|
||||
CInputCoin input_coin = output.GetInputCoin();
|
||||
|
||||
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)) {
|
||||
// Limit output groups to no more than 10 entries, to protect
|
||||
// against inadvertently creating a too-large transaction
|
||||
|
||||
Reference in New Issue
Block a user