aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSamuel Dobson <dobsonsa68@gmail.com>2020-04-18 21:37:20 +1200
committerSamuel Dobson <dobsonsa68@gmail.com>2020-04-18 22:00:26 +1200
commitbbb1ba1814738d9d641bff69564972083013e130 (patch)
tree07326b3ed124a05b80181837f38dc34aae9a41a4 /src
parent895c71e53557ce0385181191270c660fc6c32ce1 (diff)
parent92bcd70808b9cac56b184903aa6d37baf9641b37 (diff)
downloadbitcoin-bbb1ba1814738d9d641bff69564972083013e130.tar.xz
Merge #17219: wallet: allow transaction without change if keypool is empty
92bcd70808b9cac56b184903aa6d37baf9641b37 [wallet] allow transaction without change if keypool is empty (Sjors Provoost) 709f8685ac37510aa145ac259753583c82280038 [wallet] CreateTransaction: simplify change address check (Sjors Provoost) 5efc25f9638866941028454cfa9bae27f1519cb4 [wallet] translate "Keypool ran out" message (Sjors Provoost) Pull request description: Extracted from #16944 First this PR simplifies the check when generating a change address, by dropping `CanGetAddresses` and just letting `reservedest.GetReservedDestination` do this check. Second, when the keypool is empty, instead of immediately giving up, we create a dummy change address and pass that to coin selection. If we didn't need the change address (e.g. when spending the entire balance), then it's all good. If we did need a change address, we throw the original error. ACKs for top commit: fjahr: Code review ACK 92bcd70808b9cac56b184903aa6d37baf9641b37 jonasschnelli: utACK 92bcd70808b9cac56b184903aa6d37baf9641b37 achow101: ACK 92bcd70808b9cac56b184903aa6d37baf9641b37 meshcollider: Code review ACK 92bcd70808b9cac56b184903aa6d37baf9641b37 Tree-SHA512: 07b8c8251f57061c58a85ebf0359be63583c23bac7a2c4cefdc14820c0cdebcc90a2bb218e5ede0db11d1e204cda149e056dfd18614642070b3d56efe2735006
Diffstat (limited to 'src')
-rw-r--r--src/wallet/scriptpubkeyman.cpp2
-rw-r--r--src/wallet/wallet.cpp23
2 files changed, 12 insertions, 13 deletions
diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp
index aa81ebe2fd..ec75f06e5e 100644
--- a/src/wallet/scriptpubkeyman.cpp
+++ b/src/wallet/scriptpubkeyman.cpp
@@ -20,7 +20,7 @@ bool LegacyScriptPubKeyMan::GetNewDestination(const OutputType type, CTxDestinat
// Generate a new key that is added to wallet
CPubKey new_key;
if (!GetKeyFromPool(new_key, type)) {
- error = "Error: Keypool ran out, please call keypoolrefill first";
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}
LearnRelatedScripts(new_key, type);
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index feb0563409..4ba74f7f92 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2770,20 +2770,14 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
// rediscover unknown transactions that were written with keys of ours to recover
// post-backup change.
- // Reserve a new key pair from key pool
- if (!CanGetAddresses(true)) {
- strFailReason = _("Can't generate a change-address key. No keys in the internal keypool and can't generate any keys.").translated;
- return false;
- }
+ // Reserve a new key pair from key pool. If it fails, provide a dummy
+ // destination in case we don't need change.
CTxDestination dest;
- bool ret = reservedest.GetReservedDestination(dest, true);
- if (!ret)
- {
- strFailReason = "Keypool ran out, please call keypoolrefill first";
- return false;
+ if (!reservedest.GetReservedDestination(dest, true)) {
+ strFailReason = _("Transaction needs a change address, but we can't generate it. Please call keypoolrefill first.").translated;
}
-
scriptChange = GetScriptForDestination(dest);
+ assert(!dest.empty() || scriptChange.empty());
}
CTxOut change_prototype_txout(0, scriptChange);
coin_selection_params.change_output_size = GetSerializeSize(change_prototype_txout);
@@ -2999,6 +2993,11 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
coin_selection_params.use_bnb = false;
continue;
}
+
+ // Give up if change keypool ran out and we failed to find a solution without change:
+ if (scriptChange.empty() && nChangePosInOut != -1) {
+ return false;
+ }
}
// Shuffle selected coins and fill in final vin
@@ -3294,7 +3293,7 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des
ReserveDestination reservedest(this, type);
if (!reservedest.GetReservedDestination(dest, true)) {
- error = "Error: Keypool ran out, please call keypoolrefill first";
+ error = _("Error: Keypool ran out, please call keypoolrefill first").translated;
return false;
}