Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 3,063 Lines • ▼ Show 20 Lines | CMutableTransaction txNew; | ||||
// which side is the change. | // which side is the change. | ||||
// The drawback is that by not reusing a previous key, the | // The drawback is that by not reusing a previous key, the | ||||
// change may be lost if a backup is restored, if the backup | // change may be lost if a backup is restored, if the backup | ||||
// doesn't have the new private key for the change. If we | // doesn't have the new private key for the change. If we | ||||
// reused the old key, it would be possible to add code to look | // reused the old key, it would be possible to add code to look | ||||
// for and rediscover unknown transactions that were written | // for and rediscover unknown transactions that were written | ||||
// with keys of ours to recover post-backup change. | // with keys of ours to recover post-backup change. | ||||
// Reserve a new key pair from key pool | // Reserve a new key pair from key pool. If it fails, provide a | ||||
if (!CanGetAddresses(true)) { | // dummy destination in case we don't need change. | ||||
error = _("Can't generate a change-address key. No keys in the " | |||||
"internal keypool and can't generate any keys."); | |||||
return false; | |||||
} | |||||
CTxDestination dest; | CTxDestination dest; | ||||
bool ret = reservedest.GetReservedDestination(dest, true); | if (!reservedest.GetReservedDestination(dest, true)) { | ||||
if (!ret) { | error = _("Transaction needs a change address, but we can't " | ||||
error = _("Keypool ran out, please call keypoolrefill first"); | "generate it. Please call keypoolrefill first."); | ||||
return false; | |||||
} | } | ||||
scriptChange = GetScriptForDestination(dest); | scriptChange = GetScriptForDestination(dest); | ||||
assert(!dest.empty() || scriptChange.empty()); | |||||
} | } | ||||
CTxOut change_prototype_txout(Amount::zero(), scriptChange); | CTxOut change_prototype_txout(Amount::zero(), scriptChange); | ||||
coin_selection_params.change_output_size = | coin_selection_params.change_output_size = | ||||
GetSerializeSize(change_prototype_txout); | GetSerializeSize(change_prototype_txout); | ||||
// Get the fee rate to use effective values in coin selection | // Get the fee rate to use effective values in coin selection | ||||
CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control); | CFeeRate nFeeRateNeeded = GetMinimumFeeRate(*this, coin_control); | ||||
▲ Show 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | CMutableTransaction txNew; | ||||
} | } | ||||
// Include more fee and try again. | // Include more fee and try again. | ||||
nFeeRet = nFeeNeeded; | nFeeRet = nFeeNeeded; | ||||
coin_selection_params.use_bnb = false; | coin_selection_params.use_bnb = false; | ||||
continue; | 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 | // Shuffle selected coins and fill in final vin | ||||
txNew.vin.clear(); | txNew.vin.clear(); | ||||
std::vector<CInputCoin> selected_coins(setCoins.begin(), | std::vector<CInputCoin> selected_coins(setCoins.begin(), | ||||
setCoins.end()); | setCoins.end()); | ||||
Shuffle(selected_coins.begin(), selected_coins.end(), | Shuffle(selected_coins.begin(), selected_coins.end(), | ||||
FastRandomContext()); | FastRandomContext()); | ||||
// Note how the sequence number is set to non-maxint so that | // Note how the sequence number is set to non-maxint so that | ||||
▲ Show 20 Lines • Show All 318 Lines • ▼ Show 20 Lines | |||||
bool CWallet::GetNewChangeDestination(const OutputType type, | bool CWallet::GetNewChangeDestination(const OutputType type, | ||||
CTxDestination &dest, | CTxDestination &dest, | ||||
std::string &error) { | std::string &error) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
error.clear(); | error.clear(); | ||||
ReserveDestination reservedest(this, type); | ReserveDestination reservedest(this, type); | ||||
if (!reservedest.GetReservedDestination(dest, true)) { | 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; | return false; | ||||
} | } | ||||
reservedest.KeepDestination(); | reservedest.KeepDestination(); | ||||
return true; | return true; | ||||
} | } | ||||
int64_t CWallet::GetOldestKeyPoolTime() const { | int64_t CWallet::GetOldestKeyPoolTime() const { | ||||
▲ Show 20 Lines • Show All 1,387 Lines • Show Last 20 Lines |