aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/crypter.cpp3
-rw-r--r--src/wallet/crypter.h1
-rw-r--r--src/wallet/db.cpp6
-rw-r--r--src/wallet/db.h4
-rw-r--r--src/wallet/feebumper.cpp92
-rw-r--r--src/wallet/feebumper.h8
-rw-r--r--src/wallet/fees.cpp1
-rw-r--r--src/wallet/init.cpp3
-rw-r--r--src/wallet/ismine.cpp1
-rw-r--r--src/wallet/load.cpp13
-rw-r--r--src/wallet/psbtwallet.h2
-rw-r--r--src/wallet/rpcdump.cpp1
-rw-r--r--src/wallet/rpcwallet.cpp43
-rw-r--r--src/wallet/test/wallet_tests.cpp4
-rw-r--r--src/wallet/wallet.cpp188
-rw-r--r--src/wallet/wallet.h22
-rw-r--r--src/wallet/walletdb.cpp9
-rw-r--r--src/wallet/walletdb.h5
-rw-r--r--src/wallet/wallettool.h1
19 files changed, 171 insertions, 236 deletions
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index 0b76c1a0eb..f6179aa298 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -6,11 +6,8 @@
#include <crypto/aes.h>
#include <crypto/sha512.h>
-#include <script/script.h>
-#include <script/standard.h>
#include <util/system.h>
-#include <string>
#include <vector>
int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
index 17a4e9820c..4367a5047f 100644
--- a/src/wallet/crypter.h
+++ b/src/wallet/crypter.h
@@ -9,7 +9,6 @@
#include <support/allocators/secure.h>
#include <script/signingprovider.h>
-#include <atomic>
const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 26aeb754ad..e48eee6c2c 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -412,7 +412,7 @@ bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& er
return true;
}
-bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
+bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::vector<std::string>& warnings, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
{
std::string walletFile;
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(file_path, walletFile);
@@ -424,11 +424,11 @@ bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::string& w
BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename);
if (r == BerkeleyEnvironment::VerifyResult::RECOVER_OK)
{
- warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
+ warnings.push_back(strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if"
" your balance or transactions are incorrect you should"
" restore from a backup.").translated,
- walletFile, backup_filename, walletDir);
+ walletFile, backup_filename, walletDir));
}
if (r == BerkeleyEnvironment::VerifyResult::RECOVER_FAIL)
{
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 94f41eaf16..abec3ae4e2 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -10,9 +10,7 @@
#include <fs.h>
#include <serialize.h>
#include <streams.h>
-#include <sync.h>
#include <util/system.h>
-#include <version.h>
#include <atomic>
#include <map>
@@ -246,7 +244,7 @@ public:
/* verifies the database environment */
static bool VerifyEnvironment(const fs::path& file_path, std::string& errorStr);
/* verifies the database file */
- static bool VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc);
+ static bool VerifyDatabaseFile(const fs::path& file_path, std::vector<std::string>& warnings, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc);
template <typename K, typename T>
bool Read(const K& key, T& value)
diff --git a/src/wallet/feebumper.cpp b/src/wallet/feebumper.cpp
index b87231293f..0a4bb3f396 100644
--- a/src/wallet/feebumper.cpp
+++ b/src/wallet/feebumper.cpp
@@ -2,7 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <wallet/coincontrol.h>
#include <wallet/feebumper.h>
@@ -17,15 +16,15 @@
//! Check whether transaction has descendant in wallet or mempool, or has been
//! mined, or conflicts with a mined transaction. Return a feebumper::Result.
-static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chain, const CWallet* wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet)
+static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chain, const CWallet& wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
- if (wallet->HasWalletSpend(wtx.GetHash())) {
+ if (wallet.HasWalletSpend(wtx.GetHash())) {
errors.push_back("Transaction has descendants in the wallet");
return feebumper::Result::INVALID_PARAMETER;
}
{
- if (wallet->chain().hasDescendantsInMempool(wtx.GetHash())) {
+ if (wallet.chain().hasDescendantsInMempool(wtx.GetHash())) {
errors.push_back("Transaction has descendants in the mempool");
return feebumper::Result::INVALID_PARAMETER;
}
@@ -48,7 +47,7 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
// check that original tx consists entirely of our inputs
// if not, we can't bump the fee, because the wallet has no way of knowing the value of the other inputs (thus the fee)
- if (!wallet->IsAllFromMe(*wtx.tx, ISMINE_SPENDABLE)) {
+ if (!wallet.IsAllFromMe(*wtx.tx, ISMINE_SPENDABLE)) {
errors.push_back("Transaction contains inputs that don't belong to this wallet");
return feebumper::Result::WALLET_ERROR;
}
@@ -58,13 +57,13 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
}
//! Check if the user provided a valid feeRate
-static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
+static feebumper::Result CheckFeeRate(const CWallet& wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
// check that fee rate is higher than mempool's minimum fee
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
// This may occur if the user set FeeRate, TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
// in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
// moment earlier. In this case, we report an error to the user, who may adjust the fee.
- CFeeRate minMempoolFeeRate = wallet->chain().mempoolMinFee();
+ CFeeRate minMempoolFeeRate = wallet.chain().mempoolMinFee();
if (newFeerate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
errors.push_back(strprintf(
@@ -76,7 +75,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
CAmount new_total_fee = newFeerate.GetFee(maxTxSize);
- CFeeRate incrementalRelayFee = std::max(wallet->chain().relayIncrementalFee(), CFeeRate(WALLET_INCREMENTAL_RELAY_FEE));
+ CFeeRate incrementalRelayFee = std::max(wallet.chain().relayIncrementalFee(), CFeeRate(WALLET_INCREMENTAL_RELAY_FEE));
// Given old total fee and transaction size, calculate the old feeRate
CAmount old_fee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut();
@@ -91,7 +90,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
return feebumper::Result::INVALID_PARAMETER;
}
- CAmount requiredFee = GetRequiredFee(*wallet, maxTxSize);
+ CAmount requiredFee = GetRequiredFee(wallet, maxTxSize);
if (new_total_fee < requiredFee) {
errors.push_back(strprintf("Insufficient total fee (cannot be less than required fee %s)",
FormatMoney(requiredFee)));
@@ -99,7 +98,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
}
// Check that in all cases the new fee doesn't violate maxTxFee
- const CAmount max_tx_fee = wallet->m_default_max_tx_fee;
+ const CAmount max_tx_fee = wallet.m_default_max_tx_fee;
if (new_total_fee > max_tx_fee) {
errors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)",
FormatMoney(new_total_fee), FormatMoney(max_tx_fee)));
@@ -109,7 +108,7 @@ static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wt
return feebumper::Result::OK;
}
-static CFeeRate EstimateFeeRate(CWallet* wallet, const CWalletTx& wtx, CCoinControl& coin_control, CAmount& old_fee)
+static CFeeRate EstimateFeeRate(const CWallet& wallet, const CWalletTx& wtx, CCoinControl& coin_control, CAmount& old_fee)
{
// Get the fee rate of the original transaction. This is calculated from
// the tx fee/vsize, so it may have been rounded down. Add 1 satoshi to the
@@ -123,15 +122,15 @@ static CFeeRate EstimateFeeRate(CWallet* wallet, const CWalletTx& wtx, CCoinCont
// the minimum of that and the wallet's conservative
// WALLET_INCREMENTAL_RELAY_FEE value to future proof against changes to
// network wide policy for incremental relay fee that our node may not be
- // aware of. This ensures we're over the over the required relay fee rate
+ // aware of. This ensures we're over the required relay fee rate
// (BIP 125 rule 4). The replacement tx will be at least as large as the
// original tx, so the total fee will be greater (BIP 125 rule 3)
- CFeeRate node_incremental_relay_fee = wallet->chain().relayIncrementalFee();
+ CFeeRate node_incremental_relay_fee = wallet.chain().relayIncrementalFee();
CFeeRate wallet_incremental_relay_fee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
feerate += std::max(node_incremental_relay_fee, wallet_incremental_relay_fee);
// Fee rate must also be at least the wallet's GetMinimumFeeRate
- CFeeRate min_feerate(GetMinimumFeeRate(*wallet, coin_control, /* feeCalc */ nullptr));
+ CFeeRate min_feerate(GetMinimumFeeRate(wallet, coin_control, /* feeCalc */ nullptr));
// Set the required fee rate for the replacement transaction in coin control.
return std::max(feerate, min_feerate);
@@ -139,11 +138,11 @@ static CFeeRate EstimateFeeRate(CWallet* wallet, const CWalletTx& wtx, CCoinCont
namespace feebumper {
-bool TransactionCanBeBumped(const CWallet* wallet, const uint256& txid)
+bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid)
{
- auto locked_chain = wallet->chain().lock();
- LOCK(wallet->cs_wallet);
- const CWalletTx* wtx = wallet->GetWalletTx(txid);
+ auto locked_chain = wallet.chain().lock();
+ LOCK(wallet.cs_wallet);
+ const CWalletTx* wtx = wallet.GetWalletTx(txid);
if (wtx == nullptr) return false;
std::vector<std::string> errors_dummy;
@@ -166,7 +165,7 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
}
const CWalletTx& wtx = it->second;
- Result result = PreconditionChecks(*locked_chain, wallet, wtx, errors);
+ Result result = PreconditionChecks(*locked_chain, *wallet, wtx, errors);
if (result != Result::OK) {
return result;
}
@@ -276,17 +275,17 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
}
-Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
+Result CreateRateBumpTransaction(CWallet& wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
{
// We are going to modify coin control later, copy to re-use
CCoinControl new_coin_control(coin_control);
- auto locked_chain = wallet->chain().lock();
- LOCK(wallet->cs_wallet);
+ auto locked_chain = wallet.chain().lock();
+ LOCK(wallet.cs_wallet);
errors.clear();
- auto it = wallet->mapWallet.find(txid);
- if (it == wallet->mapWallet.end()) {
+ auto it = wallet.mapWallet.find(txid);
+ if (it == wallet.mapWallet.end()) {
errors.push_back("Invalid or non-wallet transaction id");
return Result::INVALID_ADDRESS_OR_KEY;
}
@@ -300,7 +299,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
// Fill in recipients(and preserve a single change key if there is one)
std::vector<CRecipient> recipients;
for (const auto& output : wtx.tx->vout) {
- if (!wallet->IsChange(output)) {
+ if (!wallet.IsChange(output)) {
CRecipient recipient = {output.scriptPubKey, output.nValue, false};
recipients.push_back(recipient);
} else {
@@ -313,8 +312,8 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
if (coin_control.m_feerate) {
// The user provided a feeRate argument.
// We calculate this here to avoid compiler warning on the cs_wallet lock
- const int64_t maxTxSize = CalculateMaximumSignedTxSize(*wtx.tx, wallet);
- Result res = CheckFeeRate(wallet, wtx, *(new_coin_control.m_feerate), maxTxSize, errors);
+ const int64_t maxTxSize = CalculateMaximumSignedTxSize(*wtx.tx, &wallet);
+ Result res = CheckFeeRate(wallet, wtx, *new_coin_control.m_feerate, maxTxSize, errors);
if (res != Result::OK) {
return res;
}
@@ -342,7 +341,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
CAmount fee_ret;
int change_pos_in_out = -1; // No requested location for change
std::string fail_reason;
- if (!wallet->CreateTransaction(*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) {
+ if (!wallet.CreateTransaction(*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) {
errors.push_back("Unable to create transaction: " + fail_reason);
return Result::WALLET_ERROR;
}
@@ -353,7 +352,7 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
// Write back transaction
mtx = CMutableTransaction(*tx_new);
// Mark new tx not replaceable, if requested.
- if (!coin_control.m_signal_bip125_rbf.get_value_or(wallet->m_signal_rbf)) {
+ if (!coin_control.m_signal_bip125_rbf.get_value_or(wallet.m_signal_rbf)) {
for (auto& input : mtx.vin) {
if (input.nSequence < 0xfffffffe) input.nSequence = 0xfffffffe;
}
@@ -362,21 +361,21 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
return Result::OK;
}
-bool SignTransaction(CWallet* wallet, CMutableTransaction& mtx) {
- auto locked_chain = wallet->chain().lock();
- LOCK(wallet->cs_wallet);
- return wallet->SignTransaction(mtx);
+bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx) {
+ auto locked_chain = wallet.chain().lock();
+ LOCK(wallet.cs_wallet);
+ return wallet.SignTransaction(mtx);
}
-Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
+Result CommitTransaction(CWallet& wallet, const uint256& txid, CMutableTransaction&& mtx, std::vector<std::string>& errors, uint256& bumped_txid)
{
- auto locked_chain = wallet->chain().lock();
- LOCK(wallet->cs_wallet);
+ auto locked_chain = wallet.chain().lock();
+ LOCK(wallet.cs_wallet);
if (!errors.empty()) {
return Result::MISC_ERROR;
}
- auto it = txid.IsNull() ? wallet->mapWallet.end() : wallet->mapWallet.find(txid);
- if (it == wallet->mapWallet.end()) {
+ auto it = txid.IsNull() ? wallet.mapWallet.end() : wallet.mapWallet.find(txid);
+ if (it == wallet.mapWallet.end()) {
errors.push_back("Invalid or non-wallet transaction id");
return Result::MISC_ERROR;
}
@@ -393,22 +392,11 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
mapValue_t mapValue = oldWtx.mapValue;
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
- CValidationState state;
- if (!wallet->CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm, state)) {
- // NOTE: CommitTransaction never returns false, so this should never happen.
- errors.push_back(strprintf("The transaction was rejected: %s", FormatStateMessage(state)));
- return Result::WALLET_ERROR;
- }
-
- bumped_txid = tx->GetHash();
- if (state.IsInvalid()) {
- // This can happen if the mempool rejected the transaction. Report
- // what happened in the "errors" response.
- errors.push_back(strprintf("Error: The transaction was rejected: %s", FormatStateMessage(state)));
- }
+ wallet.CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm);
// mark the original tx as bumped
- if (!wallet->MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
+ bumped_txid = tx->GetHash();
+ if (!wallet.MarkReplaced(oldWtx.GetHash(), bumped_txid)) {
// TODO: see if JSON-RPC has a standard way of returning a response
// along with an exception. It would be good to return information about
// wtxBumped to the caller even if marking the original transaction
diff --git a/src/wallet/feebumper.h b/src/wallet/feebumper.h
index 0c4e1cb7dd..9357397606 100644
--- a/src/wallet/feebumper.h
+++ b/src/wallet/feebumper.h
@@ -26,7 +26,7 @@ enum class Result
};
//! Return whether transaction can be bumped.
-bool TransactionCanBeBumped(const CWallet* wallet, const uint256& txid);
+bool TransactionCanBeBumped(const CWallet& wallet, const uint256& txid);
//! Create bumpfee transaction based on total amount.
Result CreateTotalBumpTransaction(const CWallet* wallet,
@@ -39,7 +39,7 @@ Result CreateTotalBumpTransaction(const CWallet* wallet,
CMutableTransaction& mtx);
//! Create bumpfee transaction based on feerate estimates.
-Result CreateRateBumpTransaction(CWallet* wallet,
+Result CreateRateBumpTransaction(CWallet& wallet,
const uint256& txid,
const CCoinControl& coin_control,
std::vector<std::string>& errors,
@@ -50,13 +50,13 @@ Result CreateRateBumpTransaction(CWallet* wallet,
//! Sign the new transaction,
//! @return false if the tx couldn't be found or if it was
//! impossible to create the signature(s)
-bool SignTransaction(CWallet* wallet, CMutableTransaction& mtx);
+bool SignTransaction(CWallet& wallet, CMutableTransaction& mtx);
//! Commit the bumpfee transaction.
//! @return success in case of CWallet::CommitTransaction was successful,
//! but sets errors if the tx could not be added to the mempool (will try later)
//! or if the old transaction could not be marked as replaced.
-Result CommitTransaction(CWallet* wallet,
+Result CommitTransaction(CWallet& wallet,
const uint256& txid,
CMutableTransaction&& mtx,
std::vector<std::string>& errors,
diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp
index 2792058f2a..249bc833c6 100644
--- a/src/wallet/fees.cpp
+++ b/src/wallet/fees.cpp
@@ -5,7 +5,6 @@
#include <wallet/fees.h>
-#include <util/system.h>
#include <wallet/coincontrol.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 43b6ead028..3657a157b6 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -11,7 +11,6 @@
#include <util/system.h>
#include <util/translation.h>
#include <wallet/wallet.h>
-#include <wallet/walletutil.h>
#include <walletinitinterface.h>
class WalletInit : public WalletInitInterface {
@@ -122,8 +121,6 @@ bool WalletInit::ParameterInteraction() const
if (gArgs.GetBoolArg("-sysperms", false))
return InitError("-sysperms is not allowed in combination with enabled wallet functionality");
- if (gArgs.GetArg("-prune", 0) && gArgs.GetBoolArg("-rescan", false))
- return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.").translated);
return true;
}
diff --git a/src/wallet/ismine.cpp b/src/wallet/ismine.cpp
index b7ef2d4490..029b922785 100644
--- a/src/wallet/ismine.cpp
+++ b/src/wallet/ismine.cpp
@@ -7,7 +7,6 @@
#include <key.h>
#include <script/script.h>
-#include <script/sign.h>
#include <script/signingprovider.h>
#include <wallet/wallet.h>
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index b5d3b8c305..071befaebf 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -7,6 +7,7 @@
#include <interfaces/chain.h>
#include <scheduler.h>
+#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
#include <wallet/wallet.h>
@@ -53,10 +54,10 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
}
std::string error_string;
- std::string warning_string;
- bool verify_success = CWallet::Verify(chain, location, salvage_wallet, error_string, warning_string);
+ std::vector<std::string> warnings;
+ bool verify_success = CWallet::Verify(chain, location, salvage_wallet, error_string, warnings);
if (!error_string.empty()) chain.initError(error_string);
- if (!warning_string.empty()) chain.initWarning(warning_string);
+ if (!warnings.empty()) chain.initWarning(Join(warnings, "\n"));
if (!verify_success) return false;
}
@@ -66,8 +67,12 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
bool LoadWallets(interfaces::Chain& chain, const std::vector<std::string>& wallet_files)
{
for (const std::string& walletFile : wallet_files) {
- std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile));
+ std::string error;
+ std::vector<std::string> warnings;
+ std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile), error, warnings);
+ if (!warnings.empty()) chain.initWarning(Join(warnings, "\n"));
if (!pwallet) {
+ chain.initError(error);
return false;
}
AddWallet(pwallet);
diff --git a/src/wallet/psbtwallet.h b/src/wallet/psbtwallet.h
index a24a0967d2..a7e52df6d9 100644
--- a/src/wallet/psbtwallet.h
+++ b/src/wallet/psbtwallet.h
@@ -5,9 +5,7 @@
#ifndef BITCOIN_WALLET_PSBTWALLET_H
#define BITCOIN_WALLET_PSBTWALLET_H
-#include <node/transaction.h>
#include <psbt.h>
-#include <primitives/transaction.h>
#include <wallet/wallet.h>
/**
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index f52e4318c8..1cd4cb93b4 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -7,7 +7,6 @@
#include <interfaces/chain.h>
#include <key_io.h>
#include <merkleblock.h>
-#include <rpc/server.h>
#include <rpc/util.h>
#include <script/descriptor.h>
#include <script/script.h>
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index dc437e5cd8..e571501221 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -4,12 +4,10 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <amount.h>
-#include <consensus/validation.h>
#include <core_io.h>
#include <init.h>
#include <interfaces/chain.h>
#include <key_io.h>
-#include <node/transaction.h>
#include <outputtype.h>
#include <policy/feerate.h>
#include <policy/fees.h>
@@ -22,6 +20,7 @@
#include <util/bip32.h>
#include <util/fees.h>
#include <util/moneystr.h>
+#include <util/string.h>
#include <util/system.h>
#include <util/url.h>
#include <util/validation.h>
@@ -37,7 +36,6 @@
#include <univalue.h>
-#include <functional>
static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
@@ -342,11 +340,7 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
- CValidationState state;
- if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
- strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
- }
+ pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
return tx;
}
@@ -927,12 +921,7 @@ static UniValue sendmany(const JSONRPCRequest& request)
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strFailReason, coin_control);
if (!fCreated)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
- CValidationState state;
- if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
- strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
- throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
- }
-
+ pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */);
return tx->GetHash().GetHex();
}
@@ -2583,13 +2572,14 @@ static UniValue loadwallet(const JSONRPCRequest& request)
}
}
- std::string error, warning;
+ std::string error;
+ std::vector<std::string> warning;
std::shared_ptr<CWallet> const wallet = LoadWallet(*g_rpc_interfaces->chain, location, error, warning);
if (!wallet) throw JSONRPCError(RPC_WALLET_ERROR, error);
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
- obj.pushKV("warning", warning);
+ obj.pushKV("warning", Join(warning, "\n"));
return obj;
}
@@ -2695,12 +2685,12 @@ static UniValue createwallet(const JSONRPCRequest& request)
}
SecureString passphrase;
passphrase.reserve(100);
- std::string warning;
+ std::vector<std::string> warnings;
if (!request.params[3].isNull()) {
passphrase = request.params[3].get_str().c_str();
if (passphrase.empty()) {
// Empty string means unencrypted
- warning = "Empty string given as passphrase, wallet will not be encrypted.";
+ warnings.emplace_back("Empty string given as passphrase, wallet will not be encrypted.");
}
}
@@ -2709,9 +2699,8 @@ static UniValue createwallet(const JSONRPCRequest& request)
}
std::string error;
- std::string create_warning;
std::shared_ptr<CWallet> wallet;
- WalletCreationStatus status = CreateWallet(*g_rpc_interfaces->chain, passphrase, flags, request.params[0].get_str(), error, create_warning, wallet);
+ WalletCreationStatus status = CreateWallet(*g_rpc_interfaces->chain, passphrase, flags, request.params[0].get_str(), error, warnings, wallet);
switch (status) {
case WalletCreationStatus::CREATION_FAILED:
throw JSONRPCError(RPC_WALLET_ERROR, error);
@@ -2722,15 +2711,9 @@ static UniValue createwallet(const JSONRPCRequest& request)
// no default case, so the compiler can warn about missing cases
}
- if (warning.empty()) {
- warning = create_warning;
- } else if (!warning.empty() && !create_warning.empty()){
- warning += "; " + create_warning;
- }
-
UniValue obj(UniValue::VOBJ);
obj.pushKV("name", wallet->GetName());
- obj.pushKV("warning", warning);
+ obj.pushKV("warning", Join(warnings, "\n"));
return obj;
}
@@ -3417,7 +3400,7 @@ static UniValue bumpfee(const JSONRPCRequest& request)
res = feebumper::CreateTotalBumpTransaction(pwallet, hash, coin_control, totalFee, errors, old_fee, new_fee, mtx);
} else {
// Targeting feerate bump.
- res = feebumper::CreateRateBumpTransaction(pwallet, hash, coin_control, errors, old_fee, new_fee, mtx);
+ res = feebumper::CreateRateBumpTransaction(*pwallet, hash, coin_control, errors, old_fee, new_fee, mtx);
}
if (res != feebumper::Result::OK) {
switch(res) {
@@ -3440,12 +3423,12 @@ static UniValue bumpfee(const JSONRPCRequest& request)
}
// sign bumped transaction
- if (!feebumper::SignTransaction(pwallet, mtx)) {
+ if (!feebumper::SignTransaction(*pwallet, mtx)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
}
// commit the bumped transaction
uint256 txid;
- if (feebumper::CommitTransaction(pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
+ if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
throw JSONRPCError(RPC_WALLET_ERROR, errors[0]);
}
UniValue result(UniValue::VOBJ);
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 73523ca36d..a2b2a7b227 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -8,7 +8,6 @@
#include <stdint.h>
#include <vector>
-#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <policy/policy.h>
#include <rpc/server.h>
@@ -451,8 +450,7 @@ public:
auto locked_chain = m_chain->lock();
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, fee, changePos, error, dummy));
}
- CValidationState state;
- BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, state));
+ wallet->CommitTransaction(tx, {}, {});
CMutableTransaction blocktx;
{
LOCK(wallet->cs_wallet);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 09f08220db..159d4f78c6 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -27,13 +27,11 @@
#include <util/rbf.h>
#include <util/translation.h>
#include <util/validation.h>
-#include <validation.h>
#include <wallet/coincontrol.h>
#include <wallet/fees.h>
#include <algorithm>
#include <assert.h>
-#include <future>
#include <boost/algorithm/string/replace.hpp>
@@ -140,16 +138,16 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
}
}
-std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::string& warning)
+std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::vector<std::string>& warnings)
{
- if (!CWallet::Verify(chain, location, false, error, warning)) {
+ if (!CWallet::Verify(chain, location, false, error, warnings)) {
error = "Wallet file verification failed: " + error;
return nullptr;
}
- std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location);
+ std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, error, warnings);
if (!wallet) {
- error = "Wallet loading failed.";
+ error = "Wallet loading failed: " + error;
return nullptr;
}
AddWallet(wallet);
@@ -157,12 +155,12 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocati
return wallet;
}
-std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning)
+std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::vector<std::string>& warnings)
{
- return LoadWallet(chain, WalletLocation(name), error, warning);
+ return LoadWallet(chain, WalletLocation(name), error, warnings);
}
-WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result)
+WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::vector<std::string>& warnings, std::shared_ptr<CWallet>& result)
{
// Indicate that the wallet is actually supposed to be blank and not just blank to make it encrypted
bool create_blank = (wallet_creation_flags & WALLET_FLAG_BLANK_WALLET);
@@ -180,9 +178,8 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
}
// Wallet::Verify will check if we're trying to create a wallet with a duplicate name.
- std::string wallet_error;
- if (!CWallet::Verify(chain, location, false, wallet_error, warning)) {
- error = "Wallet file verification failed: " + wallet_error;
+ if (!CWallet::Verify(chain, location, false, error, warnings)) {
+ error = "Wallet file verification failed: " + error;
return WalletCreationStatus::CREATION_FAILED;
}
@@ -193,9 +190,9 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
}
// Make the wallet
- std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, wallet_creation_flags);
+ std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, error, warnings, wallet_creation_flags);
if (!wallet) {
- error = "Wallet creation failed";
+ error = "Wallet creation failed: " + error;
return WalletCreationStatus::CREATION_FAILED;
}
@@ -2739,8 +2736,11 @@ bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAm
}
std::vector<OutputGroup> groups = GroupOutputs(vCoins, !coin_control.m_avoid_partial_spends);
- size_t max_ancestors = (size_t)std::max<int64_t>(1, gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT));
- size_t max_descendants = (size_t)std::max<int64_t>(1, gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
+ unsigned int limit_ancestor_count;
+ unsigned int limit_descendant_count;
+ chain().getPackageLimits(limit_ancestor_count, limit_descendant_count);
+ size_t max_ancestors = (size_t)std::max<int64_t>(1, limit_ancestor_count);
+ size_t max_descendants = (size_t)std::max<int64_t>(1, limit_descendant_count);
bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
bool res = nTargetValue <= nValueFromPresetInputs ||
@@ -3284,51 +3284,44 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
return true;
}
-/**
- * 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, CValidationState& state)
+void CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm)
{
- {
- auto locked_chain = chain().lock();
- LOCK(cs_wallet);
+ auto locked_chain = chain().lock();
+ LOCK(cs_wallet);
- CWalletTx wtxNew(this, std::move(tx));
- wtxNew.mapValue = std::move(mapValue);
- wtxNew.vOrderForm = std::move(orderForm);
- wtxNew.fTimeReceivedIsTxTime = true;
- wtxNew.fFromMe = true;
+ CWalletTx wtxNew(this, std::move(tx));
+ wtxNew.mapValue = std::move(mapValue);
+ wtxNew.vOrderForm = std::move(orderForm);
+ wtxNew.fTimeReceivedIsTxTime = true;
+ wtxNew.fFromMe = true;
- WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
- {
+ WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
- // Add tx to wallet, because if it has change it's also ours,
- // otherwise just for transaction history.
- AddToWallet(wtxNew);
+ // Add tx to wallet, because if it has change it's also ours,
+ // otherwise just for transaction history.
+ AddToWallet(wtxNew);
- // Notify that old coins are spent
- for (const CTxIn& txin : wtxNew.tx->vin)
- {
- CWalletTx &coin = mapWallet.at(txin.prevout.hash);
- coin.BindWallet(this);
- NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
- }
- }
+ // Notify that old coins are spent
+ for (const CTxIn& txin : wtxNew.tx->vin) {
+ CWalletTx &coin = mapWallet.at(txin.prevout.hash);
+ coin.BindWallet(this);
+ NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
+ }
- // Get the inserted-CWalletTx from mapWallet so that the
- // fInMempool flag is cached properly
- CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
+ // Get the inserted-CWalletTx from mapWallet so that the
+ // fInMempool flag is cached properly
+ CWalletTx& wtx = mapWallet.at(wtxNew.GetHash());
- if (fBroadcastTransactions)
- {
- std::string err_string;
- if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
- WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
- // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
- }
- }
+ if (!fBroadcastTransactions) {
+ // Don't submit tx to the mempool
+ return;
+ }
+
+ std::string err_string;
+ if (!wtx.SubmitMemoryPoolAndRelay(err_string, true, *locked_chain)) {
+ WalletLogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", err_string);
+ // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
}
- return true;
}
DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
@@ -3467,21 +3460,6 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
return WalletBatch(*database).EraseName(EncodeDestination(address));
}
-const std::string& CWallet::GetLabelName(const CScript& scriptPubKey) const
-{
- CTxDestination address;
- if (ExtractDestination(scriptPubKey, address) && !scriptPubKey.IsUnspendable()) {
- auto mi = mapAddressBook.find(address);
- if (mi != mapAddressBook.end()) {
- return mi->second.name;
- }
- }
- // A scriptPubKey that doesn't have an entry in the address book is
- // associated with the default label ("").
- const static std::string DEFAULT_LABEL_NAME;
- return DEFAULT_LABEL_NAME;
-}
-
/**
* Mark old keypool keys as used,
* and generate all new keys
@@ -4196,7 +4174,7 @@ void CWallet::MarkPreSplitKeys()
}
}
-bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::string& warning_string)
+bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::vector<std::string>& warnings)
{
// Do some checking on wallet path. It should be either a:
//
@@ -4250,10 +4228,10 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
}
}
- return WalletBatch::VerifyDatabaseFile(wallet_path, warning_string, error_string);
+ return WalletBatch::VerifyDatabaseFile(wallet_path, warnings, error_string);
}
-std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags)
+std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::vector<std::string>& warnings, uint64_t wallet_creation_flags)
{
const std::string walletFile = WalletDataFilePath(location.GetPath()).string();
@@ -4266,7 +4244,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(&chain, location, WalletDatabase::Create(location.GetPath()));
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
if (nZapWalletRet != DBErrors::LOAD_OK) {
- chain.initError(strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile));
+ error = strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile);
return nullptr;
}
}
@@ -4279,29 +4257,28 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
// should be possible to use std::allocate_shared.
std::shared_ptr<CWallet> walletInstance(new CWallet(&chain, location, WalletDatabase::Create(location.GetPath())), ReleaseWallet);
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
- if (nLoadWalletRet != DBErrors::LOAD_OK)
- {
+ if (nLoadWalletRet != DBErrors::LOAD_OK) {
if (nLoadWalletRet == DBErrors::CORRUPT) {
- chain.initError(strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile));
+ error = strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile);
return nullptr;
}
else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
{
- chain.initWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
+ warnings.push_back(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
" or address book entries might be missing or incorrect.").translated,
walletFile));
}
else if (nLoadWalletRet == DBErrors::TOO_NEW) {
- chain.initError(strprintf(_("Error loading %s: Wallet requires newer version of %s").translated, walletFile, PACKAGE_NAME));
+ error = strprintf(_("Error loading %s: Wallet requires newer version of %s").translated, walletFile, PACKAGE_NAME);
return nullptr;
}
else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
{
- chain.initError(strprintf(_("Wallet needed to be rewritten: restart %s to complete").translated, PACKAGE_NAME));
+ error = strprintf(_("Wallet needed to be rewritten: restart %s to complete").translated, PACKAGE_NAME);
return nullptr;
}
else {
- chain.initError(strprintf(_("Error loading %s").translated, walletFile));
+ error = strprintf(_("Error loading %s").translated, walletFile);
return nullptr;
}
}
@@ -4320,7 +4297,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
walletInstance->WalletLogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
if (nMaxVersion < walletInstance->GetVersion())
{
- chain.initError(_("Cannot downgrade wallet").translated);
+ error = _("Cannot downgrade wallet").translated;
return nullptr;
}
walletInstance->SetMaxVersion(nMaxVersion);
@@ -4333,7 +4310,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->GetVersion();
if (!walletInstance->CanSupportFeature(FEATURE_HD_SPLIT) && max_version >= FEATURE_HD_SPLIT && max_version < FEATURE_PRE_SPLIT_KEYPOOL) {
- 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.").translated);
+ error = _("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use -upgradewallet=169900 or -upgradewallet with no version specified.").translated;
return nullptr;
}
@@ -4361,7 +4338,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
// Regenerate the keypool if upgraded to HD
if (hd_upgrade) {
if (!walletInstance->TopUpKeyPool()) {
- chain.initError(_("Unable to generate keys").translated);
+ error = _("Unable to generate keys").translated;
return nullptr;
}
}
@@ -4381,7 +4358,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
// Top up the keypool
if (walletInstance->CanGenerateKeys() && !walletInstance->TopUpKeyPool()) {
- chain.initError(_("Unable to generate initial keys").translated);
+ error = _("Unable to generate initial keys").translated;
return nullptr;
}
@@ -4389,33 +4366,33 @@ 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
- chain.initError(strprintf(_("Error loading %s: Private keys can only be disabled during creation").translated, walletFile));
+ error = strprintf(_("Error loading %s: Private keys can only be disabled during creation").translated, walletFile);
return NULL;
} else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
LOCK(walletInstance->cs_KeyStore);
if (!walletInstance->mapKeys.empty() || !walletInstance->mapCryptedKeys.empty()) {
- chain.initWarning(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys").translated, walletFile));
+ warnings.push_back(strprintf(_("Warning: Private keys detected in wallet {%s} with disabled private keys").translated, walletFile));
}
}
if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
- chain.initError(strprintf(_("Unknown address type '%s'").translated, gArgs.GetArg("-addresstype", "")));
+ error = strprintf(_("Unknown address type '%s'").translated, gArgs.GetArg("-addresstype", ""));
return nullptr;
}
if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
- chain.initError(strprintf(_("Unknown change type '%s'").translated, gArgs.GetArg("-changetype", "")));
+ error = strprintf(_("Unknown change type '%s'").translated, gArgs.GetArg("-changetype", ""));
return nullptr;
}
if (gArgs.IsArgSet("-mintxfee")) {
CAmount n = 0;
if (!ParseMoney(gArgs.GetArg("-mintxfee", ""), n) || 0 == n) {
- chain.initError(AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")).translated);
+ error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")).translated;
return nullptr;
}
if (n > HIGH_TX_FEE_PER_KB) {
- chain.initWarning(AmountHighWarn("-mintxfee").translated + " " +
+ warnings.push_back(AmountHighWarn("-mintxfee").translated + " " +
_("This is the minimum transaction fee you pay on every transaction.").translated);
}
walletInstance->m_min_fee = CFeeRate(n);
@@ -4424,11 +4401,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
if (gArgs.IsArgSet("-fallbackfee")) {
CAmount nFeePerK = 0;
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
- chain.initError(strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'").translated, gArgs.GetArg("-fallbackfee", "")));
+ error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'").translated, gArgs.GetArg("-fallbackfee", ""));
return nullptr;
}
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
- chain.initWarning(AmountHighWarn("-fallbackfee").translated + " " +
+ warnings.push_back(AmountHighWarn("-fallbackfee").translated + " " +
_("This is the transaction fee you may pay when fee estimates are not available.").translated);
}
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
@@ -4439,11 +4416,11 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
if (gArgs.IsArgSet("-discardfee")) {
CAmount nFeePerK = 0;
if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
- chain.initError(strprintf(_("Invalid amount for -discardfee=<amount>: '%s'").translated, gArgs.GetArg("-discardfee", "")));
+ error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'").translated, gArgs.GetArg("-discardfee", ""));
return nullptr;
}
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
- chain.initWarning(AmountHighWarn("-discardfee").translated + " " +
+ warnings.push_back(AmountHighWarn("-discardfee").translated + " " +
_("This is the transaction fee you may discard if change is smaller than dust at this level").translated);
}
walletInstance->m_discard_rate = CFeeRate(nFeePerK);
@@ -4451,41 +4428,40 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
if (gArgs.IsArgSet("-paytxfee")) {
CAmount nFeePerK = 0;
if (!ParseMoney(gArgs.GetArg("-paytxfee", ""), nFeePerK)) {
- chain.initError(AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")).translated);
+ error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")).translated;
return nullptr;
}
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
- chain.initWarning(AmountHighWarn("-paytxfee").translated + " " +
+ warnings.push_back(AmountHighWarn("-paytxfee").translated + " " +
_("This is the transaction fee you will pay if you send a transaction.").translated);
}
walletInstance->m_pay_tx_fee = CFeeRate(nFeePerK, 1000);
if (walletInstance->m_pay_tx_fee < chain.relayMinFee()) {
- chain.initError(strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)").translated,
- gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString()));
+ error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)").translated,
+ gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString());
return nullptr;
}
}
- if (gArgs.IsArgSet("-maxtxfee"))
- {
+ if (gArgs.IsArgSet("-maxtxfee")) {
CAmount nMaxFee = 0;
if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) {
- chain.initError(AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")).translated);
+ error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")).translated;
return nullptr;
}
if (nMaxFee > HIGH_MAX_TX_FEE) {
- chain.initWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.").translated);
+ warnings.push_back(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.").translated);
}
if (CFeeRate(nMaxFee, 1000) < chain.relayMinFee()) {
- chain.initError(strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)").translated,
- gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString()));
+ error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)").translated,
+ gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString());
return nullptr;
}
walletInstance->m_default_max_tx_fee = nMaxFee;
}
if (chain.relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
- chain.initWarning(AmountHighWarn("-minrelaytxfee").translated + " " +
+ warnings.push_back(AmountHighWarn("-minrelaytxfee").translated + " " +
_("The wallet will avoid paying less than the minimum relay fee.").translated);
}
@@ -4535,7 +4511,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
}
if (rescan_height != block_height) {
- chain.initError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)").translated);
+ error = _("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)").translated;
return nullptr;
}
}
@@ -4554,7 +4530,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)) {
- chain.initError(_("Failed to rescan the wallet during initialization").translated);
+ error = _("Failed to rescan the wallet during initialization").translated;
return nullptr;
}
}
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 006775e83b..85c277ff50 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -11,7 +11,6 @@
#include <interfaces/handler.h>
#include <outputtype.h>
#include <policy/feerate.h>
-#include <script/sign.h>
#include <tinyformat.h>
#include <ui_interface.h>
#include <util/strencodings.h>
@@ -48,7 +47,7 @@ bool RemoveWallet(const std::shared_ptr<CWallet>& wallet);
bool HasWallets();
std::vector<std::shared_ptr<CWallet>> GetWallets();
std::shared_ptr<CWallet> GetWallet(const std::string& name);
-std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::string& warning);
+std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::vector<std::string>& warnings);
enum class WalletCreationStatus {
SUCCESS,
@@ -56,7 +55,7 @@ enum class WalletCreationStatus {
ENCRYPTION_FAILED
};
-WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result);
+WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::vector<std::string>& warnings, std::shared_ptr<CWallet>& result);
//! Default for -keypool
static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000;
@@ -1147,7 +1146,16 @@ public:
*/
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut,
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true);
- bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CValidationState& state);
+ /**
+ * Submit the transaction to the node's mempool and then relay to peers.
+ * Should be called after CreateTransaction unless you want to abort
+ * broadcasting the transaction.
+ *
+ * @param tx[in] The transaction to be broadcast.
+ * @param mapValue[in] key-values to be set on the transaction.
+ * @param orderForm[in] BIP 70 / BIP 21 order form details to be set on the transaction.
+ */
+ void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
{
@@ -1246,8 +1254,6 @@ public:
bool DelAddressBook(const CTxDestination& address);
- const std::string& GetLabelName(const CScript& scriptPubKey) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
-
unsigned int GetKeyPoolSize() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
{
AssertLockHeld(cs_wallet);
@@ -1321,10 +1327,10 @@ public:
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
//! Verify wallet naming and perform salvage on the wallet if required
- static bool Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::string& warning_string);
+ static bool Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::vector<std::string>& warnings);
/* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
- static std::shared_ptr<CWallet> CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, uint64_t wallet_creation_flags = 0);
+ static std::shared_ptr<CWallet> CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::vector<std::string>& warnings, uint64_t wallet_creation_flags = 0);
/**
* Wallet post-init setup
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 635997afc9..a9e6763c6d 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -5,8 +5,6 @@
#include <wallet/walletdb.h>
-#include <consensus/tx_check.h>
-#include <consensus/validation.h>
#include <fs.h>
#include <key_io.h>
#include <protocol.h>
@@ -218,8 +216,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
ssKey >> hash;
CWalletTx wtx(nullptr /* pwallet */, MakeTransactionRef());
ssValue >> wtx;
- CValidationState state;
- if (!(CheckTransaction(*wtx.tx, state) && (wtx.GetHash() == hash) && state.IsValid()))
+ if (wtx.GetHash() != hash)
return false;
// Undo serialize changes in 31600
@@ -729,9 +726,9 @@ bool WalletBatch::VerifyEnvironment(const fs::path& wallet_path, std::string& er
return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr);
}
-bool WalletBatch::VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr)
+bool WalletBatch::VerifyDatabaseFile(const fs::path& wallet_path, std::vector<std::string>& warnings, std::string& errorStr)
{
- return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warningStr, errorStr, WalletBatch::Recover);
+ return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warnings, errorStr, WalletBatch::Recover);
}
bool WalletBatch::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h
index 0fee35934d..b1781d5ccf 100644
--- a/src/wallet/walletdb.h
+++ b/src/wallet/walletdb.h
@@ -7,15 +7,12 @@
#define BITCOIN_WALLET_WALLETDB_H
#include <amount.h>
-#include <primitives/transaction.h>
#include <script/sign.h>
#include <wallet/db.h>
#include <key.h>
-#include <list>
#include <stdint.h>
#include <string>
-#include <utility>
#include <vector>
/**
@@ -263,7 +260,7 @@ public:
/* verifies the database environment */
static bool VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr);
/* verifies the database file */
- static bool VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr);
+ static bool VerifyDatabaseFile(const fs::path& wallet_path, std::vector<std::string>& warnings, std::string& errorStr);
//! write the hdchain model (external chain child index counter)
bool WriteHDChain(const CHDChain& chain);
diff --git a/src/wallet/wallettool.h b/src/wallet/wallettool.h
index 7ee2505631..bd08da42d6 100644
--- a/src/wallet/wallettool.h
+++ b/src/wallet/wallettool.h
@@ -5,7 +5,6 @@
#ifndef BITCOIN_WALLET_WALLETTOOL_H
#define BITCOIN_WALLET_WALLETTOOL_H
-#include <wallet/ismine.h>
#include <wallet/wallet.h>
namespace WalletTool {