WIP: make sweeper deadline aware#7549
Conversation
There was a problem hiding this comment.
nit: could use switch statement?
There was a problem hiding this comment.
I think we need to watch for underflow here which would make target very large
There was a problem hiding this comment.
If target = 1, then we're not technically behind the deadline as there is still 1 more block to go before the timelock expires.
Also, why is 2 the minimal value?
There was a problem hiding this comment.
This returns a conf target, but in low-fee environments I believe the conf target can give the same feerate. We want to change the feerate up to some maximum % of the HTLC value here. I think instead this should only use a feerate rather than a conf-target. This would mean passing in a fee-rate from the timeout resolver.
There was a problem hiding this comment.
Does this also need to be called up above when the input already exists in the sweeper?
There was a problem hiding this comment.
I think the deadline should be its own parameter because I think the current usage is that call-sites usually have a deadline but pass a conf target that is unrelated to the deadline. So adding the conf target to the current height might be too aggressive in some cases
There was a problem hiding this comment.
I think this will block?
There was a problem hiding this comment.
missing the strategy field?
There was a problem hiding this comment.
think we can get rid of Force, if it's uneconomical it's ok to give up
There was a problem hiding this comment.
IMO this should only be for the deadline-aware inputs. The logic is a bit weird, but I think we can improve that later. We need to make sure that deadline-aware inputs don't stop after MaxSweepAttempts since they are going to be fee-bumping more since they are being re-submitted more in this function
0be3133 to
30b61da
Compare
This commit adds a new service, `feeBumper` along with its interface `Bumper`, to perform fee bumping over time sensitive inputs. This commit focuses on building the framework for the bumper, and the following commits will implement the actual strategies.
This commit adds a new strategy, `StrategyLinear`, to linearly increase the fee rate used for a given input when the deadline approaches.
30b61da to
1308f3a
Compare
Roasbeef
left a comment
There was a problem hiding this comment.
Nice work porting this over from that other codebase! Left some inline comments, more specific to the lnd context. Main thing is that I think we can break up the new abstract strategies into an interface to further encapsulate the logic and allow for composition/re-use.
| log btclog.Logger | ||
|
|
||
| // feeLog is used by the fee bumper. | ||
| feeLog btclog.Logger |
There was a problem hiding this comment.
Could make this a sub-package to have it get its own distinct logger, and also be useable as a dep-minimized sub-module.
|
|
||
| // Generate a pkScript to be used by the fee bumper for weight | ||
| // calculation. | ||
| pkScript, err := s.cfg.GenSweepScript() |
There was a problem hiding this comment.
Can we alternatively just make something that's P2TR sized? This way we don't need to extend the look ahead gap each time we restart.
| } | ||
|
|
||
| // Add the input. | ||
| if err := weightEstimate.add(m.Input); err != nil { |
There was a problem hiding this comment.
This doesn't seem to factor in the additional overhead of the type of inputs added to bump the transaction.
|
|
||
| // Check if the request has already been processed. | ||
| // | ||
| // TODO(yy): allow overwrite? |
There was a problem hiding this comment.
Or return a nil error unless we expect the caller to properly handle the returned ErrAlreadyMonitored.
| feeRateUsed = feeRate | ||
| } | ||
|
|
||
| // If the requst doesn't specify a broadcast height, use the manager's |
| var deadlineHeight uint32 | ||
|
|
||
| // Calculate the deadline height if the conf target is set. | ||
| if req.ConfTarget != NoHeightInfo { |
There was a problem hiding this comment.
Shouldn't this be ==? Since in this case, no conf target was specified, so we need to enforce a default conf target.
| f.monitoredInputs.Range(func(_ *wire.OutPoint, | ||
| r *monitoredInput) bool { | ||
|
|
||
| f.wg.Add(1) |
There was a problem hiding this comment.
I wonder if this should actually be done serially 🤔
Though with the way the sweeper works, all the goroutines will be serialized anyway, so it's nice to not have to block here so we can proceed other blocks/requests.
| } | ||
|
|
||
| // Strategy specifies how the fee bump is performed. | ||
| type Strategy uint8 |
There was a problem hiding this comment.
A slightly different way to represent this would be to have Strategy itself be an interface with methods for: seeing it things need to be bumped, and suggesting the proper fee rate. This would allow us to further encapsulate the logic of each strategy, and each strategy can also maintain its own state to make better decisions.
| } | ||
|
|
||
| // TODO(yy): cache the results? | ||
| func (f *feeBumper) feeRateForStrategyLinear( |
There was a problem hiding this comment.
If we make this part of the strategy interface, then we can easily add caching there (though seems to be a premature optimization at this point imo).
|
Superseded by #8667 |
This is a very raw PoC PR to make the sweeper deadline-aware and fixes #4215.
Depends on:
Aggregatorinterface #8148In this PR, we extend the current sweeper to perform a fee bump if the input specifies it's deadline-aware. The sweeper will then continuously fee bump the sweeping tx in every new block if it's not confirmed.
An alternative approach would be fee bumping at the callsite, similar to how anchor sweeping is handled here. This approach IMO is not as good as the current one as a) the current approach has a deeper interface on sweeper and b) we can pre-define a set of fee bumping strategies so they can be easily applied based on specific conditions.
TODO: