mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
move-only: refactor CreateTransactionInternal
Move the output serialization size and dust calculation into the loop where the outputs are iterated over to calculate the total sum. Move the code for adding the the txoutputs to the transaction to after coin selection. While this code structure generally follows a more logical flow, the primary motivation for moving the code for adding outputs to the transaction sets us up nicely for silent payments (in a future PR): we need to know the input set before generating the final output scriptPubKeys.
This commit is contained in:
parent
adc6ab25bb
commit
a9c7300135
@ -1008,12 +1008,20 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||
|
||||
// Set the long term feerate estimate to the wallet's consolidate feerate
|
||||
coin_selection_params.m_long_term_feerate = wallet.m_consolidate_feerate;
|
||||
// Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
|
||||
coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize(vecSend.size()); // bytes for output count
|
||||
|
||||
CAmount recipients_sum = 0;
|
||||
const OutputType change_type = wallet.TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : wallet.m_default_change_type, vecSend);
|
||||
ReserveDestination reservedest(&wallet, change_type);
|
||||
unsigned int outputs_to_subtract_fee_from = 0; // The number of outputs which we are subtracting the fee from
|
||||
for (const auto& recipient : vecSend) {
|
||||
if (IsDust(recipient, wallet.chain().relayDustFee())) {
|
||||
return util::Error{_("Transaction amount too small")};
|
||||
}
|
||||
|
||||
// Include the fee cost for outputs.
|
||||
coin_selection_params.tx_noinputs_size += GetSerializeSizeForRecipient(recipient);
|
||||
recipients_sum += recipient.nAmount;
|
||||
|
||||
if (recipient.fSubtractFeeFromAmount) {
|
||||
@ -1098,23 +1106,6 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||
const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
|
||||
coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
|
||||
|
||||
// Static vsize overhead + outputs vsize. 4 version, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
|
||||
coin_selection_params.tx_noinputs_size = 10 + GetSizeOfCompactSize(vecSend.size()); // bytes for output count
|
||||
|
||||
// vouts to the payees
|
||||
for (const auto& recipient : vecSend)
|
||||
{
|
||||
CTxOut txout(recipient.nAmount, GetScriptForDestination(recipient.dest));
|
||||
|
||||
// Include the fee cost for outputs.
|
||||
coin_selection_params.tx_noinputs_size += GetSerializeSizeForRecipient(recipient);
|
||||
|
||||
if (IsDust(recipient, wallet.chain().relayDustFee())) {
|
||||
return util::Error{_("Transaction amount too small")};
|
||||
}
|
||||
txNew.vout.push_back(txout);
|
||||
}
|
||||
|
||||
// Include the fees for things that aren't inputs, excluding the change output
|
||||
const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.m_subtract_fee_outputs ? 0 : coin_selection_params.tx_noinputs_size);
|
||||
CAmount selection_target = recipients_sum + not_input_fees;
|
||||
@ -1155,6 +1146,11 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
|
||||
result.GetWaste(),
|
||||
result.GetSelectedValue());
|
||||
|
||||
// vouts to the payees
|
||||
for (const auto& recipient : vecSend)
|
||||
{
|
||||
txNew.vout.emplace_back(recipient.nAmount, GetScriptForDestination(recipient.dest));
|
||||
}
|
||||
const CAmount change_amount = result.GetChange(coin_selection_params.min_viable_change, coin_selection_params.m_change_fee);
|
||||
if (change_amount > 0) {
|
||||
CTxOut newTxOut(change_amount, scriptChange);
|
||||
|
Loading…
Reference in New Issue
Block a user