mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-19 13:27:35 +02:00
Merge 23c926d859 into merged_master (Bitcoin PR #18699)
This commit is contained in:
commit
d4711bdf91
26 changed files with 278 additions and 239 deletions
|
|
@ -29,6 +29,7 @@
|
|||
#include <util/fees.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/rbf.h>
|
||||
#include <util/string.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <wallet/coincontrol.h>
|
||||
|
|
@ -157,34 +158,34 @@ void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, std::string& error, std::vector<std::string>& warnings)
|
||||
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
try {
|
||||
if (!CWallet::Verify(chain, location, false, error, warnings)) {
|
||||
error = "Wallet file verification failed: " + error;
|
||||
error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, error, warnings);
|
||||
if (!wallet) {
|
||||
error = "Wallet loading failed: " + error;
|
||||
error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
|
||||
return nullptr;
|
||||
}
|
||||
AddWallet(wallet);
|
||||
wallet->postInitProcess();
|
||||
return wallet;
|
||||
} catch (const std::runtime_error& e) {
|
||||
error = e.what();
|
||||
error = Untranslated(e.what());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::vector<std::string>& warnings)
|
||||
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
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::vector<std::string>& warnings, std::shared_ptr<CWallet>& result)
|
||||
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& 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);
|
||||
|
|
@ -197,39 +198,39 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
|
|||
// Check the wallet file location
|
||||
WalletLocation location(name);
|
||||
if (location.Exists()) {
|
||||
error = "Wallet " + location.GetName() + " already exists.";
|
||||
error = strprintf(Untranslated("Wallet %s already exists."), location.GetName());
|
||||
return WalletCreationStatus::CREATION_FAILED;
|
||||
}
|
||||
|
||||
// Wallet::Verify will check if we're trying to create a wallet with a duplicate name.
|
||||
if (!CWallet::Verify(chain, location, false, error, warnings)) {
|
||||
error = "Wallet file verification failed: " + error;
|
||||
error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error;
|
||||
return WalletCreationStatus::CREATION_FAILED;
|
||||
}
|
||||
|
||||
// Do not allow a passphrase when private keys are disabled
|
||||
if (!passphrase.empty() && (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
error = "Passphrase provided but private keys are disabled. A passphrase is only used to encrypt private keys, so cannot be used for wallets with private keys disabled.";
|
||||
error = Untranslated("Passphrase provided but private keys are disabled. A passphrase is only used to encrypt private keys, so cannot be used for wallets with private keys disabled.");
|
||||
return WalletCreationStatus::CREATION_FAILED;
|
||||
}
|
||||
|
||||
// Make the wallet
|
||||
std::shared_ptr<CWallet> wallet = CWallet::CreateWalletFromFile(chain, location, error, warnings, wallet_creation_flags);
|
||||
if (!wallet) {
|
||||
error = "Wallet creation failed: " + error;
|
||||
error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
|
||||
return WalletCreationStatus::CREATION_FAILED;
|
||||
}
|
||||
|
||||
// Encrypt the wallet
|
||||
if (!passphrase.empty() && !(wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
if (!wallet->EncryptWallet(passphrase)) {
|
||||
error = "Error: Wallet created but failed to encrypt.";
|
||||
error = Untranslated("Error: Wallet created but failed to encrypt.");
|
||||
return WalletCreationStatus::ENCRYPTION_FAILED;
|
||||
}
|
||||
if (!create_blank) {
|
||||
// Unlock the wallet
|
||||
if (!wallet->Unlock(passphrase)) {
|
||||
error = "Error: Wallet was encrypted but could not be unlocked";
|
||||
error = Untranslated("Error: Wallet was encrypted but could not be unlocked");
|
||||
return WalletCreationStatus::ENCRYPTION_FAILED;
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +242,7 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
|
|||
} else {
|
||||
for (auto spk_man : wallet->GetActiveScriptPubKeyMans()) {
|
||||
if (!spk_man->SetupGeneration()) {
|
||||
error = "Unable to generate initial keys";
|
||||
error = Untranslated("Unable to generate initial keys");
|
||||
return WalletCreationStatus::CREATION_FAILED;
|
||||
}
|
||||
}
|
||||
|
|
@ -2882,7 +2883,7 @@ SigningResult CWallet::SignMessage(const std::string& message, const PKHash& pkh
|
|||
return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
|
||||
bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
|
||||
{
|
||||
std::vector<CRecipient> vecSend;
|
||||
|
||||
|
|
@ -2892,7 +2893,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
|||
|
||||
// ELEMENTS:
|
||||
if (!txOut.nValue.IsExplicit() || !txOut.nAsset.IsExplicit()) {
|
||||
strFailReason = _("Pre-funded amounts must be non-blinded").translated;
|
||||
error = _("Pre-funded amounts must be non-blinded");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2917,7 +2918,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
|
|||
|
||||
CTransactionRef tx_new;
|
||||
BlindDetails* blind_details = g_con_elementsmode ? new BlindDetails() : NULL;
|
||||
if (!CreateTransaction(vecSend, tx_new, nFeeRet, nChangePosInOut, strFailReason, coinControl, false, blind_details)) {
|
||||
if (!CreateTransaction(vecSend, tx_new, nFeeRet, nChangePosInOut, error, coinControl, false, blind_details)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3057,7 +3058,7 @@ void resetBlindDetails(BlindDetails* det) {
|
|||
det->only_change_pos = -1;
|
||||
}
|
||||
|
||||
bool fillBlindDetails(BlindDetails* det, CWallet* wallet, CMutableTransaction& txNew, std::vector<CInputCoin>& selected_coins, std::string& strFailReason) {
|
||||
bool fillBlindDetails(BlindDetails* det, CWallet* wallet, CMutableTransaction& txNew, std::vector<CInputCoin>& selected_coins, bilingual_str& error) {
|
||||
int num_inputs_blinded = 0;
|
||||
|
||||
// Fill in input blinding details
|
||||
|
|
@ -3110,7 +3111,7 @@ bool fillBlindDetails(BlindDetails* det, CWallet* wallet, CMutableTransaction& t
|
|||
det->o_asset_blinds[det->only_change_pos] = uint256();
|
||||
wallet->WalletLogPrintf("Unblinding change at index %d due to lack of inputs and other outputs being blinded.\n", det->only_change_pos);
|
||||
} else {
|
||||
strFailReason = _("Change output could not be blinded as there are no blinded inputs and no other blinded outputs.").translated;
|
||||
error = _("Change output could not be blinded as there are no blinded inputs and no other blinded outputs.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -3125,7 +3126,7 @@ bool fillBlindDetails(BlindDetails* det, CWallet* wallet, CMutableTransaction& t
|
|||
det->o_asset_blinds[det->only_recipient_blind_index] = uint256();
|
||||
wallet->WalletLogPrintf("Unblinding single blinded output at index %d due to lack of inputs and other outputs being blinded.\n", det->only_recipient_blind_index);
|
||||
} else {
|
||||
strFailReason = _("Transaction output could not be blinded as there are no blinded inputs and no other blinded outputs.").translated;
|
||||
error = _("Transaction output could not be blinded as there are no blinded inputs and no other blinded outputs.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3134,7 +3135,7 @@ bool fillBlindDetails(BlindDetails* det, CWallet* wallet, CMutableTransaction& t
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign, BlindDetails* blind_details, const IssuanceDetails* issuance_details) {
|
||||
bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut, bilingual_str& error, const CCoinControl& coin_control, bool sign, BlindDetails* blind_details, const IssuanceDetails* issuance_details) {
|
||||
if (blind_details || issuance_details) {
|
||||
assert(g_con_elementsmode);
|
||||
}
|
||||
|
|
@ -3164,12 +3165,12 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
}
|
||||
|
||||
if (g_con_elementsmode && recipient.asset.IsNull()) {
|
||||
strFailReason = _("No asset provided for recipient").translated;
|
||||
error = _("No asset provided for recipient");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapValue[recipient.asset] < 0 || recipient.nAmount < 0) {
|
||||
strFailReason = _("Transaction amounts must not be negative").translated;
|
||||
error = _("Transaction amounts must not be negative");
|
||||
return false;
|
||||
}
|
||||
mapValue[recipient.asset] += recipient.nAmount;
|
||||
|
|
@ -3179,7 +3180,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
}
|
||||
if (vecSend.empty())
|
||||
{
|
||||
strFailReason = _("Transaction must have at least one recipient").translated;
|
||||
error = _("Transaction must have at least one recipient");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3225,7 +3226,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
// destination in case we don't need change.
|
||||
CTxDestination dest;
|
||||
if (index >= reservedest.size() || !reservedest[index]->GetReservedDestination(dest, true)) {
|
||||
strFailReason = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.").translated;
|
||||
error = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.");
|
||||
// ELEMENTS: We need to put a dummy destination here. Core uses an empty script
|
||||
// but we can't because empty scripts indicate fees (which trigger assertation
|
||||
// failures in `BlindTransaction`). We also set the index to -1, indicating
|
||||
|
|
@ -3261,7 +3262,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
|
||||
CTxDestination dest;
|
||||
if (index >= reservedest.size() || !reservedest[index]->GetReservedDestination(dest, true)) {
|
||||
strFailReason = _("Keypool ran out, please call keypoolrefill first").translated;
|
||||
error = _("Keypool ran out, please call keypoolrefill first");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3347,7 +3348,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
if (recipient.fSubtractFeeFromAmount)
|
||||
{
|
||||
if (recipient.asset != policyAsset) {
|
||||
strFailReason = strprintf("Wallet does not support more than one type of fee at a time, therefore can not subtract fee from address amount, which is of a different asset id. fee asset: %s recipient asset: %s", policyAsset.GetHex(), recipient.asset.GetHex());
|
||||
error = Untranslated(strprintf("Wallet does not support more than one type of fee at a time, therefore can not subtract fee from address amount, which is of a different asset id. fee asset: %s recipient asset: %s", policyAsset.GetHex(), recipient.asset.GetHex()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3368,12 +3369,12 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
|
||||
{
|
||||
if (txout.nValue.GetAmount() < 0)
|
||||
strFailReason = _("The transaction amount is too small to pay the fee").translated;
|
||||
error = _("The transaction amount is too small to pay the fee");
|
||||
else
|
||||
strFailReason = _("The transaction amount is too small to send after the fee has been deducted").translated;
|
||||
error = _("The transaction amount is too small to send after the fee has been deducted");
|
||||
}
|
||||
else
|
||||
strFailReason = _("Transaction amount too small").translated;
|
||||
error = _("Transaction amount too small");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3415,7 +3416,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
continue;
|
||||
}
|
||||
else {
|
||||
strFailReason = _("Insufficient funds").translated;
|
||||
error = _("Insufficient funds");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3434,7 +3435,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
// Fill a vout to ourself
|
||||
const std::map<CAsset, std::pair<int, CScript>>::const_iterator itScript = mapScriptChange.find(assetChange.first);
|
||||
if (itScript == mapScriptChange.end()) {
|
||||
strFailReason = strprintf("No change destination provided for asset %s", assetChange.first.GetHex());
|
||||
error = Untranslated(strprintf("No change destination provided for asset %s", assetChange.first.GetHex()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3467,7 +3468,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
}
|
||||
else if ((unsigned int)itPos->second > txNew.vout.size())
|
||||
{
|
||||
strFailReason = _("Change index out of range").translated;
|
||||
error = _("Change index out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3600,7 +3601,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
}
|
||||
|
||||
if (blind_details) {
|
||||
if (!fillBlindDetails(blind_details, this, txNew, selected_coins, strFailReason)) {
|
||||
if (!fillBlindDetails(blind_details, this, txNew, selected_coins, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3609,14 +3610,14 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
int ret = BlindTransaction(blind_details->i_amount_blinds, blind_details->i_asset_blinds, blind_details->i_assets, blind_details->i_amounts, blind_details->o_amount_blinds, blind_details->o_asset_blinds, blind_details->o_pubkeys, issuance_asset_keys, issuance_token_keys, txNew);
|
||||
assert(ret != -1);
|
||||
if (ret != blind_details->num_to_blind) {
|
||||
strFailReason = _("Unable to blind the transaction properly. This should not happen.").translated;
|
||||
error = _("Unable to blind the transaction properly. This should not happen.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nBytes = CalculateMaximumSignedTxSize(CTransaction(txNew), this, &coin_control);
|
||||
if (nBytes < 0) {
|
||||
strFailReason = _("Missing solving data for estimating transaction size").translated;
|
||||
error = _("Missing solving data for estimating transaction size");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3628,7 +3629,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
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.").translated;
|
||||
error = _("Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3679,7 +3680,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
int ret = BlindTransaction(blind_details->i_amount_blinds, blind_details->i_asset_blinds, blind_details->i_assets, blind_details->i_amounts, blind_details->o_amount_blinds, blind_details->o_asset_blinds, blind_details->o_pubkeys, issuance_asset_keys, issuance_token_keys, txNew);
|
||||
assert(ret != -1);
|
||||
if (ret != blind_details->num_to_blind) {
|
||||
strFailReason = _("Unable to blind the transaction properly. This should not happen.").translated;
|
||||
error = _("Unable to blind the transaction properly. This should not happen.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -3698,7 +3699,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
// fee to pay for the new output and still meet nFeeNeeded
|
||||
// Or we should have just subtracted fee from recipients and
|
||||
// nFeeNeeded should not have changed
|
||||
strFailReason = _("Transaction fee and change calculation failed").translated;
|
||||
error = _("Transaction fee and change calculation failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3728,7 +3729,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
int ret = BlindTransaction(blind_details->i_amount_blinds, blind_details->i_asset_blinds, blind_details->i_assets, blind_details->i_amounts, blind_details->o_amount_blinds, blind_details->o_asset_blinds, blind_details->o_pubkeys, issuance_asset_keys, issuance_token_keys, txNew);
|
||||
assert(ret != -1);
|
||||
if (ret != blind_details->num_to_blind) {
|
||||
strFailReason = _("Unable to blind the transaction properly. This should not happen.").translated;
|
||||
error = _("Unable to blind the transaction properly. This should not happen.");
|
||||
return false;
|
||||
}
|
||||
break; // Done, able to increase fee from change
|
||||
|
|
@ -3844,7 +3845,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
|
||||
if (sign) {
|
||||
if (!SignTransaction(txNew)) {
|
||||
strFailReason = _("Signing transaction failed").translated;
|
||||
error = _("Signing transaction failed");
|
||||
return false;
|
||||
}
|
||||
} else if (blind_details) {
|
||||
|
|
@ -3864,20 +3865,20 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransac
|
|||
// Limit size
|
||||
if (GetTransactionWeight(*tx) > MAX_STANDARD_TX_WEIGHT)
|
||||
{
|
||||
strFailReason = _("Transaction too large").translated;
|
||||
error = _("Transaction too large");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (nFeeRet > m_default_max_tx_fee) {
|
||||
strFailReason = TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED);
|
||||
error = Untranslated(TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
|
||||
// Lastly, ensure this tx will pass the mempool's chain limits
|
||||
if (!chain().checkChainLimits(tx)) {
|
||||
strFailReason = _("Transaction has too long of a mempool chain").translated;
|
||||
error = _("Transaction has too long of a mempool chain");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -4595,7 +4596,7 @@ std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const
|
|||
return values;
|
||||
}
|
||||
|
||||
bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::vector<std::string>& warnings)
|
||||
bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, bool salvage_wallet, bilingual_str& error_string, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
// Do some checking on wallet path. It should be either a:
|
||||
//
|
||||
|
|
@ -4609,17 +4610,17 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
|
|||
if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
|
||||
(path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
|
||||
(path_type == fs::regular_file && fs::path(location.GetName()).filename() == location.GetName()))) {
|
||||
error_string = strprintf(
|
||||
error_string = Untranslated(strprintf(
|
||||
"Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
|
||||
"database/log.?????????? files can be stored, a location where such a directory could be created, "
|
||||
"or (for backwards compatibility) the name of an existing data file in -walletdir (%s)",
|
||||
location.GetName(), GetWalletDir());
|
||||
location.GetName(), GetWalletDir()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure that the wallet path doesn't clash with an existing wallet path
|
||||
if (IsWalletLoaded(wallet_path)) {
|
||||
error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName());
|
||||
error_string = Untranslated(strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4631,7 +4632,7 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
|
|||
return false;
|
||||
}
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
error_string = strprintf("Error loading wallet %s. %s", location.GetName(), fsbridge::get_filesystem_error_message(e));
|
||||
error_string = Untranslated(strprintf("Error loading wallet %s. %s", location.GetName(), fsbridge::get_filesystem_error_message(e)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -4647,7 +4648,7 @@ bool CWallet::Verify(interfaces::Chain& chain, const WalletLocation& location, b
|
|||
return WalletBatch::VerifyDatabaseFile(wallet_path, warnings, error_string);
|
||||
}
|
||||
|
||||
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)
|
||||
std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain, const WalletLocation& location, bilingual_str& error, std::vector<bilingual_str>& warnings, uint64_t wallet_creation_flags)
|
||||
{
|
||||
const std::string walletFile = WalletDataFilePath(location.GetPath()).string();
|
||||
|
||||
|
|
@ -4660,7 +4661,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) {
|
||||
error = strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile);
|
||||
error = strprintf(_("Error loading %s: Wallet corrupted"), walletFile);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -4675,26 +4676,26 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
||||
if (nLoadWalletRet != DBErrors::LOAD_OK) {
|
||||
if (nLoadWalletRet == DBErrors::CORRUPT) {
|
||||
error = strprintf(_("Error loading %s: Wallet corrupted").translated, walletFile);
|
||||
error = strprintf(_("Error loading %s: Wallet corrupted"), walletFile);
|
||||
return nullptr;
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR)
|
||||
{
|
||||
warnings.push_back(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
|
||||
" or address book entries might be missing or incorrect.").translated,
|
||||
" or address book entries might be missing or incorrect."),
|
||||
walletFile));
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::TOO_NEW) {
|
||||
error = 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"), walletFile, PACKAGE_NAME);
|
||||
return nullptr;
|
||||
}
|
||||
else if (nLoadWalletRet == DBErrors::NEED_REWRITE)
|
||||
{
|
||||
error = strprintf(_("Wallet needed to be rewritten: restart %s to complete").translated, PACKAGE_NAME);
|
||||
error = strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
error = strprintf(_("Error loading %s").translated, walletFile);
|
||||
error = strprintf(_("Error loading %s"), walletFile);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -4720,7 +4721,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
// Legacy wallets need SetupGeneration here.
|
||||
for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
|
||||
if (!spk_man->SetupGeneration()) {
|
||||
error = _("Unable to generate initial keys").translated;
|
||||
error = _("Unable to generate initial keys");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -4730,36 +4731,36 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
walletInstance->chainStateFlushed(chain.getTipLocator());
|
||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||
// Make it impossible to disable private keys after creation
|
||||
error = 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"), walletFile);
|
||||
return NULL;
|
||||
} else if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
|
||||
for (auto spk_man : walletInstance->GetActiveScriptPubKeyMans()) {
|
||||
if (spk_man->HavePrivateKeys()) {
|
||||
warnings.push_back(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"), walletFile));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gArgs.GetArg("-addresstype", "").empty() && !ParseOutputType(gArgs.GetArg("-addresstype", ""), walletInstance->m_default_address_type)) {
|
||||
error = strprintf(_("Unknown address type '%s'").translated, gArgs.GetArg("-addresstype", ""));
|
||||
error = strprintf(_("Unknown address type '%s'"), gArgs.GetArg("-addresstype", ""));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!gArgs.GetArg("-changetype", "").empty() && !ParseOutputType(gArgs.GetArg("-changetype", ""), walletInstance->m_default_change_type)) {
|
||||
error = strprintf(_("Unknown change type '%s'").translated, gArgs.GetArg("-changetype", ""));
|
||||
error = 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) {
|
||||
error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", "")).translated;
|
||||
error = AmountErrMsg("mintxfee", gArgs.GetArg("-mintxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (n > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-mintxfee").translated + " " +
|
||||
_("This is the minimum transaction fee you pay on every transaction.").translated);
|
||||
warnings.push_back(AmountHighWarn("-mintxfee") + Untranslated(" ") +
|
||||
_("This is the minimum transaction fee you pay on every transaction."));
|
||||
}
|
||||
walletInstance->m_min_fee = CFeeRate(n);
|
||||
}
|
||||
|
|
@ -4767,12 +4768,12 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
if (gArgs.IsArgSet("-fallbackfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-fallbackfee", ""), nFeePerK)) {
|
||||
error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'").translated, gArgs.GetArg("-fallbackfee", ""));
|
||||
error = strprintf(_("Invalid amount for -fallbackfee=<amount>: '%s'"), gArgs.GetArg("-fallbackfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-fallbackfee").translated + " " +
|
||||
_("This is the transaction fee you may pay when fee estimates are not available.").translated);
|
||||
warnings.push_back(AmountHighWarn("-fallbackfee") + Untranslated(" ") +
|
||||
_("This is the transaction fee you may pay when fee estimates are not available."));
|
||||
}
|
||||
walletInstance->m_fallback_fee = CFeeRate(nFeePerK);
|
||||
}
|
||||
|
|
@ -4782,28 +4783,28 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
if (gArgs.IsArgSet("-discardfee")) {
|
||||
CAmount nFeePerK = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-discardfee", ""), nFeePerK)) {
|
||||
error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'").translated, gArgs.GetArg("-discardfee", ""));
|
||||
error = strprintf(_("Invalid amount for -discardfee=<amount>: '%s'"), gArgs.GetArg("-discardfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-discardfee").translated + " " +
|
||||
_("This is the transaction fee you may discard if change is smaller than dust at this level").translated);
|
||||
warnings.push_back(AmountHighWarn("-discardfee") + Untranslated(" ") +
|
||||
_("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)) {
|
||||
error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", "")).translated;
|
||||
error = AmountErrMsg("paytxfee", gArgs.GetArg("-paytxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nFeePerK > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-paytxfee").translated + " " +
|
||||
_("This is the transaction fee you will pay if you send a transaction.").translated);
|
||||
warnings.push_back(AmountHighWarn("-paytxfee") + Untranslated(" ") +
|
||||
_("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 < chain.relayMinFee()) {
|
||||
error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)").translated,
|
||||
error = strprintf(_("Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
|
||||
gArgs.GetArg("-paytxfee", ""), chain.relayMinFee().ToString());
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -4812,23 +4813,23 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
if (gArgs.IsArgSet("-maxtxfee")) {
|
||||
CAmount nMaxFee = 0;
|
||||
if (!ParseMoney(gArgs.GetArg("-maxtxfee", ""), nMaxFee)) {
|
||||
error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", "")).translated;
|
||||
error = AmountErrMsg("maxtxfee", gArgs.GetArg("-maxtxfee", ""));
|
||||
return nullptr;
|
||||
}
|
||||
if (nMaxFee > HIGH_MAX_TX_FEE) {
|
||||
warnings.push_back(_("-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."));
|
||||
}
|
||||
if (CFeeRate(nMaxFee, 1000) < chain.relayMinFee()) {
|
||||
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());
|
||||
error = strprintf(_("Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
|
||||
gArgs.GetArg("-maxtxfee", ""), chain.relayMinFee().ToString());
|
||||
return nullptr;
|
||||
}
|
||||
walletInstance->m_default_max_tx_fee = nMaxFee;
|
||||
}
|
||||
|
||||
if (chain.relayMinFee().GetFeePerK() > HIGH_TX_FEE_PER_KB) {
|
||||
warnings.push_back(AmountHighWarn("-minrelaytxfee").translated + " " +
|
||||
_("The wallet will avoid paying less than the minimum relay fee.").translated);
|
||||
warnings.push_back(AmountHighWarn("-minrelaytxfee") + Untranslated(" ") +
|
||||
_("The wallet will avoid paying less than the minimum relay fee."));
|
||||
}
|
||||
|
||||
walletInstance->m_confirm_target = gArgs.GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET);
|
||||
|
|
@ -4888,7 +4889,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
}
|
||||
|
||||
if (rescan_height != block_height) {
|
||||
error = _("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)");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -4913,7 +4914,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
|
|||
{
|
||||
WalletRescanReserver reserver(*walletInstance);
|
||||
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, {} /* max height */, reserver, true /* update */).status)) {
|
||||
error = _("Failed to rescan the wallet during initialization").translated;
|
||||
error = _("Failed to rescan the wallet during initialization");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -4973,7 +4974,7 @@ const CAddressBookData* CWallet::FindAddressBookEntry(const CTxDestination& dest
|
|||
return &address_book_it->second;
|
||||
}
|
||||
|
||||
bool CWallet::UpgradeWallet(int version, std::string& error, std::vector<std::string>& warnings)
|
||||
bool CWallet::UpgradeWallet(int version, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||
{
|
||||
int prev_version = GetVersion();
|
||||
int nMaxVersion = version;
|
||||
|
|
@ -4982,12 +4983,12 @@ bool CWallet::UpgradeWallet(int version, std::string& error, std::vector<std::st
|
|||
WalletLogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
|
||||
nMaxVersion = FEATURE_LATEST;
|
||||
SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
|
||||
}
|
||||
else
|
||||
} else {
|
||||
WalletLogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
|
||||
}
|
||||
if (nMaxVersion < GetVersion())
|
||||
{
|
||||
error = _("Cannot downgrade wallet").translated;
|
||||
error = _("Cannot downgrade wallet");
|
||||
return false;
|
||||
}
|
||||
SetMaxVersion(nMaxVersion);
|
||||
|
|
@ -4997,7 +4998,7 @@ bool CWallet::UpgradeWallet(int version, std::string& error, std::vector<std::st
|
|||
// Do not upgrade versions to any version between HD_SPLIT and FEATURE_PRE_SPLIT_KEYPOOL unless already supporting HD_SPLIT
|
||||
int max_version = GetVersion();
|
||||
if (!CanSupportFeature(FEATURE_HD_SPLIT) && max_version >= FEATURE_HD_SPLIT && max_version < FEATURE_PRE_SPLIT_KEYPOOL) {
|
||||
error = _("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.").translated;
|
||||
error = _("Cannot upgrade a non HD split wallet without upgrading to support pre split keypool. Please use version 169900 or no version specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue