Uh oh!
There was an error while loading. Please reload this page.
Expose new BumpChannelClose event for channels with anchor outputs - #1689
Conversation
ab79496 to
0e079cdCompareCodecov ReportBase: 90.79% // Head: 90.49% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@## main #1689 +/- ##
==========================================
- Coverage 90.79% 90.49% -0.30%
==========================================
Files 87 87 Lines 46969 46863 -106 Branches 46969 46863 -106 ==========================================
- Hits 42646 42410 -236 - Misses 4323 4453 +130
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
TheBlueMatt
left a comment
There was a problem hiding this comment.
Didn't really dig into anything, just looking at the high-level.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
0e079cd to
937017eComparewpaulino
commented
Sep 14, 2022
Rebased on latest main and addressed pending comments. |
ariard
left a comment
There was a problem hiding this comment.
I'm Approach ACK on both the BumpTransaction enum, the data scope returned back to the user and the event itself. To be looked more, the callsites where we're triggering the event, to see if there is way to simplify or clean paths.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| log_debug!(logger, "Finalized transaction {} ready to broadcast", bumped_tx.txid()); | ||
| Some(bumped_tx) | ||
| } | ||
| pub(crate) fn finalize_untractable_package<L: Deref, Signer: Sign>( |
There was a problem hiding this comment.
I think "intractable" is the more common form
There was a problem hiding this comment.
"untractable" is already used quite a bit across the codebase, I'd prefer having a separate PR to only do the rename.
Uh oh!
There was an error while loading. Please reload this page.
937017e to
21ad8f4Compare
TheBlueMatt
left a comment
There was a problem hiding this comment.
Some quick comments, will take a further look later.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| let package_feerate = Self::compute_feerate(previous_package_feerate, fee_estimator, conf_target); | ||
| // With the new package feerate obtained, compute the feerate the child transaction must | ||
| // meet such that the package feerate is met. | ||
| (package_feerate as u64).checked_mul(2).map(|f| f.checked_sub(parent_feerate)).flatten() |
There was a problem hiding this comment.
Hmmmm, how do we handle the 1-sat/vb initial fee requirement? If our target ends up being, eg, 1sat/vb can we end up returning something lower here? Also, can we just subtract here? Don't we have to weigh it by the weight of the two transactions?
There was a problem hiding this comment.
The issue here is that we don't know the weight of the child transaction yet as it will be created by the event consumer.
After dwelling on #1689 (comment), it may be better to expose a ConfirmationTarget instead of a feerate to indicate the confirmation urgency. The yet to be developed middleware can then handle mapping it to an appropriate feerate as it will have all the context required to do so properly.
There was a problem hiding this comment.
Hmm, yea....somehow the consumer has to be able to track the specific transaction, though. We generally try to avoid assuming the fee estimator is correct, or that it responds quickly if the mempool is actively filling up (because some explicitly don't). Thus, we really need to make sure it's easy to track what feerate was used on the previous transaction not just what the target is.
I guess we could just expose the target feerate and let the user do the averaging?
There was a problem hiding this comment.
Yeah that should work. We can then expose a helper method that does the averaging for the user.
4aff3e2 to
974c96fCompare| #[derive(PartialEq, Eq, PartialOrd, Ord)] | ||
| pub(crate) enum ClaimEvent { | ||
| BumpCommitment { | ||
| target_feerate_sat_per_1000_weight: u32, |
There was a problem hiding this comment.
nit: Just grepping around and see we have this identifier but with plural sats.
| target_feerate_sat_per_1000_weight:u32, | |
| target_feerate_sats_per_1000_weight:u32, |
There was a problem hiding this comment.
Looks like we just use both interchangeably across the codebase. Would prefer deferring a consistent rename change to a distinct PR.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ariard
left a comment
There was a problem hiding this comment.
Still have to review some of the changes in package.rs, looks good overall.
Thanks for dealing with the rather murky package API, my apologies for the lack of documentation there.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
974c96f to
5748ec9CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
0a0216b to
5478ef6Compare
ariard
left a comment
There was a problem hiding this comment.
I think we're good though I'm blocking a bit as using #[cfg(test)] TODO: remove-on-anchors-release to feature gate anchor output support. I can't remember we have gradually release sophisticated feature in the past, so sounds a first time. While I think it's worthy to do so in the present case I don't know if it's the best approach, see comment.
| let commitment_package = PackageTemplate::build_package( | ||
| self.funding_info.0.txid.clone(), self.funding_info.0.index as u32, | ||
| PackageSolvingData::HolderFundingOutput(funding_output), | ||
| best_block_height, false, best_block_height, |
There was a problem hiding this comment.
For builders/helpers in safety-critical parts, we could start to document the boolean argument at the caller call-site, i.e "/* aggregable */ false". It sounds a code style sophistication, though we already do that on the Core-side. As the codebase keeps growing I think this could be a good practice as a argument misusage could introduce a logical bug. E.g, aggregating a PackageMalleability::Untractable and a PackageMalleability::Malleable together triggering a panic!(). Already seen that type of bug sticking for years in Core.
There was a problem hiding this comment.
Will address this as a separate PR.
Uh oh!
There was an error while loading. Please reload this page.
| // attempt to broadcast the transaction with its current fee rate and hope | ||
| // it confirms. This is essentially the same behavior as a commitment | ||
| // transaction without anchor outputs. | ||
| None => Some((None, 0, OnchainClaim::Tx(tx.clone()))), |
There was a problem hiding this comment.
IIRC, the case where we don't find a second anchor output for the channel is when we have no fund at stakes in the channel (no-htlc, no-balance) output. We could consider the channel early closed and return a OnchainEvent::ChannelClosed, to allow consumer to react in consequence.
There was a problem hiding this comment.
I like the idea, but seems out of scope for this PR.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| @@ -2299,6 +2321,39 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> { | |||
| pub fn get_and_clear_pending_events(&mut self) -> Vec<Event> { | |||
There was a problem hiding this comment.
I think we should update ChainMonitor::process_pending_events in consequence, noticing the user that this call is from now on important for the funds safety and call frequence should at least match every block ?
There was a problem hiding this comment.
Done. I wonder if the ChainMonitor should just do this itself if any anchor channels are present. Would it be considered a violation of the events API?
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
004aedf to
46f35c0Compare46f35c0 to
e159214Comparewpaulino
commented
Oct 11, 2022
Had to rebase on main to address a conflict. The previous push includes changes addressing latest round of feedback. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
e159214 to
c963d3aCompare
TheBlueMatt
left a comment
There was a problem hiding this comment.
LGTM. There's a few followups but ideally let's just land this and we can do them later.
| Some((idx, _)) => { | ||
| // Our target feerate will depend on whether we have any HTLCs present | ||
| // within our commitment. | ||
| let conf_target = if self.holder_commitment.trust().htlcs().is_empty() { |
There was a problem hiding this comment.
We may have a unrevoked counterparty commitment that does contain HTLCs, I think, so we should check for that or just always use highpriority. Happy to see it as a followup so we can land this.
There was a problem hiding this comment.
Since the counterparty commitment isn't exposed to the OnchainTxHandler, I reverted to always using HighPriority and added a todo.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| &Event::BumpTransaction(ref event)=> { | ||
| 27u8.write(writer)?; | ||
| match event { | ||
| // We never write the ChannelClose events as they'll be replayed upon restarting |
There was a problem hiding this comment.
I'm a little dubious of the never-write here. While we should generate a new bump eventually, we may take a few blocks to do so, and dropping the event may waste a few blocks' time, which seems bad?
There was a problem hiding this comment.
I was thinking it would be fine as long as we always use a soonest_conf_deadline of our best known height (which is currently the case). get_height_timer will then force a retry at the next block.
There was a problem hiding this comment.
Yea, we should reconsider that at some point, though, IIUC that will do an RBF bump at every block, which may mean bumping the fee by 25% every block, which seems like a lot? Not something for this PR, though.
TheBlueMatt
commented
Oct 17, 2022
Oops, needs rebase now, sorry about that. Feel free to tackle some of the above when you do so. |
As we integrate the support of anchor outputs, we'll want to know if each input we're working with came from an anchor outputs channel. Instead of threading through a `opt_anchors` boolean across several methods on `PackageSolvingData` and `PackageTemplate`, we decide to store a reference in each `PackageSolvingData` variant instead that features a change in behavior between channels with and without anchor outputs.
This will be useful later on when determining the appropriate fee rate to use on the anchor transaction to bump its commitment transaction.
c963d3a to
abe85a1Compare
This PR introduces a new
BumpChannelCloseevent to be consumed by users indicating that they should craft a proper child anchor transaction with a sufficient feerate to increase the commitment transaction's (its parent) feerate and help get it confirmed.Future work will also feature a similar event to bump the fees of HTLC success and timeout transactions.