-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
cnct+sweep: cpfp-aware anchor sweeping #4592
cnct+sweep: cpfp-aware anchor sweeping #4592
Conversation
7be0b7e to
442b77d
Compare
input/input.go
Outdated
| @@ -41,6 +42,18 @@ type Input interface { | |||
| // HeightHint returns the minimum height at which a confirmed spending | |||
| // tx can occur. | |||
| HeightHint() uint32 | |||
|
|
|||
| // Cpfp returns information about a possibly unconfirmed parent tx. | |||
| Cpfp() *TxInfo | |||
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.
call this ParentFeeInfo or something? I found having it named CPFP a bit confusing.
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 had that first, but the reason I renamed it is that it isn't just the parent info, but also signals specific cpfp behavior. Like when the input is included in a sweep.
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.
Renamed to UnconfParent(). The comments already says that that is what it is.
| chainfee.SatPerKWeight(parentTx.Weight) | ||
|
|
||
| if parentFeeRate >= feeRate { | ||
| log.Debugf("Skipping cpfp input %v: fee_rate=%v, "+ |
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.
👍
f237fb1 to
2a8b7ef
Compare
73dcfe3 to
d7cf7f6
Compare
7b897a1 to
7a2f8a3
Compare
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.
Great commit structure 😊 On first pass the changes read well. Can do another pass when the TODOs are completed (or are they?)
sweep/weight_estimator.go
Outdated
| weight += w.parentsWeight | ||
|
|
||
| // Subtract fee already paid by parents. | ||
| fee := w.feeRate.FeeForWeight(weight) - w.parentsFee |
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.
it seems possible that this could be negative? or is the theory that this should never do that because of the parentFeeRate >= w.feeRate check? i wonder if that is always true when considering rounding edge cases
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 don't think there is a rounding edge case, because even in the case that the parent almost totally pays for itself, the child tx has a minimum weight too that needs to be covered.
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.
An alternative would be to remove the parentFeeRate >= w.feeRate check, but here instead return the maximum of feeRate.FeeForWeight(weight) and feeRate.FeeForWeight(weight+parentsWeight)-parentsFee
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.
even in the case that the parent almost totally pays for itself, the child tx has a minimum weight too that needs to be covered.
the minimum weight of a transaction is less than the divisor (1000), so it still seems possible to me. would be nice to know for sure tho
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.
An alternative would be to remove the parentFeeRate >= w.feeRate check, but here instead return the maximum of feeRate.FeeForWeight(weight) and feeRate.FeeForWeight(weight+parentsWeight)-parentsFee
I don't think that is possible, because there may be multiple inputs with different parents, some of which can be cpfp'ed and others not.
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.
No, you are right. The floor should be what is required for just the child tx. Added that.
c02727f to
b8d2b91
Compare
|
@cfromknecht Yes, the todos are completed. I forgot to update the PR description. |
b8d2b91 to
3c1bf6b
Compare
Preparation for a cpfp-aware weight estimator. For cpfp, a regular weight estimator isn't sufficient, because it needs to take into account the weight of the parent transaction(s) as well.
6e96ef8 to
8a33ed5
Compare
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.
Nice PR, mostly LGTM 🤠
sweep/weight_estimator.go
Outdated
| weight += w.parentsWeight | ||
|
|
||
| // Subtract fee already paid by parents. | ||
| fee := w.feeRate.FeeForWeight(weight) - w.parentsFee |
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.
An alternative would be to remove the parentFeeRate >= w.feeRate check, but here instead return the maximum of feeRate.FeeForWeight(weight) and feeRate.FeeForWeight(weight+parentsWeight)-parentsFee
| const ( | ||
| // anchorSweepConfTarget is the conf target used when sweeping | ||
| // commitment anchors. | ||
| anchorSweepConfTarget = 6 |
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.
Drive by comment, but perhaps this shouldn't be a constant, and instead should be some factor of the CLTV delay with any incoming HTLCs (if they exist), otherwise falling back to a distinct value.
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'd be worried that if we have plenty of blocks left, we would pick a high conf target. Then if we get closer to the deadline, we don't change our conf target and might miss it. I think it is safer to always use 6 blocks until we have a sweeper that is aware of the deadline. Also the signed commit tx is estimated with a 3 block target, so fees need to go up quite a bit first before the 6 block target sweep can cpfp. (Although I sometimes see that bitcoind estimatesmartfee gives me the same estimate for all targets <= 6).
Extend the fee estimator to take into account parent transactions with their weights and fees. Do not try to cpfp parent transactions that have a higher fee rate than the sweep tx fee rate.
For unconfirmed commit tx anchors, supply the sweeper with cpfp info and a confirmation target fee estimate. The sweeper will try to pay for the parent commit tx as long as the current fee estimate exceeds the pre-signed commit tx fee rate.
8a33ed5 to
29602e8
Compare
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.
LGTM!! 💪
This PR modifies the sweeper to take into account potential unconfirmed parent transactions. This enables tracking of the current fee estimate for anchors of not yet confirmed commitment transactions. Previously an anchor-commitment that wouldn't confirm needed to be bumped manually.
2020-09-08 11:20:19.860 [INF] SWPR: Creating sweep transaction 1b76f06cd667c4d611ce9bd397634e97ac5539e960507c5ad0202965dcae481d for 2 inputs (7d1d2012a7ba95cd8140c47f4688ae0114ae9a88ebfadda107408fd937cfa92b:0 (CommitmentAnchor), ab682225912097d789c33b06b14d1d730869a3869e9b558537085ab2dcef2250:1 (WitnessKeyHash)) using 20000 sat/kw, tx_weight=719, tx_fee=0.0002546 BTC, parents_count=1, parents_fee=0.0001124 BTC, parents_weight=1116