-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
commands: require change for self-send #832
commands: require change for self-send #832
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about making this error:
Lines 556 to 578 in ed35a79
// If necessary, add a change output. | |
if change_amount.to_sat() > 0 { | |
// Don't forget to update our next change index! | |
let next_index = change_index | |
.increment() | |
.expect("Must not get into hardened territory"); | |
db_conn.set_change_index(next_index, &self.secp); | |
check_output_value(change_amount)?; | |
// TODO: shuffle once we have Taproot | |
change_txo.value = change_amount.to_sat(); | |
tx.output.push(change_txo); | |
psbt_outs.push(PsbtOut { | |
bip32_derivation: change_desc.bip32_derivations(), | |
..PsbtOut::default() | |
}); | |
} else if is_self_send { | |
return Err(CommandError::InsufficientFunds( | |
selected_coins.iter().map(|c| c.amount).sum(), | |
None, | |
feerate_vb, | |
)); | |
} |
A sanity check failure instead? It should never happen now: we would always fail the coin selection above before.
src/commands/utils.rs
Outdated
// Select more coins until target is met and change condition satisfied. | ||
loop { | ||
let drain = change_policy(&selector, target); | ||
if selector.is_target_met(target, drain) && (drain.is_some() | !must_have_change) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to use a binary or here?
if selector.is_target_met(target, drain) && (drain.is_some() | !must_have_change) { | |
if selector.is_target_met(target, drain) && (drain.is_some() || !must_have_change) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, thanks for spotting. That should be a logical or. I'll change it.
Ah yes, that's true. I think in that case the sanity check would already catch it, as it checks for |
2444b13
to
7a188f2
Compare
I've now made the suggested changes, and also made a small fix to the documentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 7a188f2
Looks good to me, but since more concepts from create_spend
are bleeding into select_coins_for_spend
(the self-send) we should either document it or tweak its interface a bit.
@@ -569,12 +569,6 @@ impl DaemonControl { | |||
bip32_derivation: change_desc.bip32_derivations(), | |||
..PsbtOut::default() | |||
}); | |||
} else if is_self_send { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would have been nice to have a comment above about how change_amount
must be positive in case of a self send, and how if this doesn't hold the sanity checks will catch this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes, I'll do that.
src/commands/utils.rs
Outdated
long_term_feerate, | ||
change_policy: &change_policy, | ||
}; | ||
let must_have_change = base_tx.output.is_empty(); // must have change if it is a self-send |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doc-comment of the function should be updated to document this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think even better would be to pass it as a parameter, so this function does not have any notion of self-send: it just exposes an interface to select coins such as there is always a change. And we set this in create_spend
where we already have this notion of self-spend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new parameter sounds good, will add that.
This adds a new `LowestFeeChangeCondition` metric for use in coin selection. It's the same as `LowestFee` with the option to only find solutions with change. This option is then used for self-sends to ensure only a solution with change will be returned.
7a188f2
to
6123b87
Compare
I've made the suggested changes and also fixed, in a separate commit, an unrelated part of documentation for |
ACK 6123b87 |
This adds a new
LowestFeeChangeCondition
metric for use in coin selection. It's the same asLowestFee
with the option to only find solutions with change.This option is then used for self-sends to ensure only a solution with change will be returned.