mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 10:12:28 +02:00
Merge #17219: wallet: allow transaction without change if keypool is empty
92bcd70808[wallet] allow transaction without change if keypool is empty (Sjors Provoost)709f8685ac[wallet] CreateTransaction: simplify change address check (Sjors Provoost)5efc25f963[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 ACK92bcd70808jonasschnelli: utACK92bcd70808achow101: ACK92bcd70808meshcollider: Code review ACK92bcd70808Tree-SHA512: 07b8c8251f57061c58a85ebf0359be63583c23bac7a2c4cefdc14820c0cdebcc90a2bb218e5ede0db11d1e204cda149e056dfd18614642070b3d56efe2735006
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user