-
Notifications
You must be signed in to change notification settings - Fork 406
Split parsing and transaction management for local transactions between Chanmon/Onchain #559
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
Split parsing and transaction management for local transactions between Chanmon/Onchain #559
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.
I think we maybe got out of sync somewhat on goals - I should have been clearer on my thinking wrt LocalCommitmentTransaction. At a high level I still like this direction, I just think it needs more work on encapsulation of sub-structs within OnchainTxHandler.
ba4e8ee
to
5aeb582
Compare
Updated 5aeb582 with comments addressed. |
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.
Just did an initial pass. I think there's still a bit to go on structure.
lightning/src/ln/chan_utils.rs
Outdated
@@ -530,6 +530,7 @@ impl LocalCommitmentTransaction { | |||
} } | |||
} | |||
|
|||
/// Generate a new LocalCommitmentTransaction based on a raw transaction, both parties funding pubkeys and remote signatures |
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.
This should likely not be public.
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's used in Channel?
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.
Right, sorry, I meant pub(crate), but shouldnt be pub.
lightning/src/ln/chan_utils.rs
Outdated
pub fn without_valid_witness(&self) -> &Transaction { &self.tx } | ||
/// Expose raw transaction with asserting witness is complete |
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.
If this is gonna be pub, probably just return an Option<> instead.
@@ -760,4 +760,12 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> { | |||
self.prev_local_commitment = self.local_commitment.take(); | |||
self.local_commitment = Some(tx); | |||
} | |||
|
|||
pub(super) fn get_fully_signed_local_tx(&mut self, channel_value_satoshis: u64) -> Option<Transaction> { |
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 still don't think this is where it needs to be - this needs to "lock" the channelmonitor, after this is called we should be refusing to update local_commitment (and docs should be updated in conjunction).
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.
Yes, as current ChannelMonitor code is structured, you may need to give back multiples time a signed local commitment transaction, but of course we should enforce signature happens once. That's what the code at this commit is doing, it's enforced in has_local_sig in
add_local_sig`. Or do you further suggestion?
4ebfc00
to
2dbb9a7
Compare
At 2dbb9a7, implement monitor-failure after LocalCommitmentTransaction signature. |
@@ -709,4 +778,47 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> { | |||
self.pending_claim_requests.remove(&req); | |||
} | |||
} | |||
|
|||
pub(super) fn provide_latest_local_tx(&mut self, tx: LocalCommitmentTransaction) -> Result<(), ()> { |
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.
Using a result here is the lazy option - this should be infallible and we should panic on programming errors which are fundamentally unsafe. At a high level, I think the right approach is to
- gate ChannelMonitor requesting such transactions on the channel having been closed,
- have ChannelManager close the channel on would_broadcast_at_height(height + 2),
- then have ChannelMonitor close it at the regular height (allowing itself to "close" the channel).
That way we shouldn't have any races where ChannelMonitor tries to get the latest local transaction but the channel isn't closed.
Then,
- ChannelMonitor::get_latest_local_commitment_transaction should return a Result (since its the public API),
- If a channel is already force-closed, we should allow it to return fine,
- If a channel is still open - we should return an Err and the client should force-close the channel in the manager (or require a ChannelMonitor::channel_was_force_closed() call).
#[cfg(test)] | ||
pub(super) fn get_fully_signed_copy_local_tx(&mut self, channel_value_satoshis: u64) -> Option<Transaction> { | ||
if let Some(ref mut local_commitment) = self.local_commitment { | ||
let mut local_commitment = local_commitment.clone(); |
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 thing that should be enforcing that we only ever sign one version is the enforcing_trait_impls stuff, not here. We need a #[cfg(test)] different version of sign_local_commitment
.
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.
After further analysis, this test-only function doesn't make sense at all, sign_local_commitment
only enforce uniqueness of signature for a commitment transaction version (has_local_sig
). For testing purposes what we want is a) signature of multiple different commitment transactions b) avoid Monitor panic/error after local-commitment-state-lockdown. So modified provide_latest_local_tx
to not return err for test-only.
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.
Right, we don't currently enforce anything, we will do it at the ChannelKeys layer. Thus, we need a test-only version of sign_local_comitment.
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.
Updated version in enforcing_trait_impls, with a TODO in keysinterface
2dbb9a7
to
9f4c44a
Compare
Codecov Report
|
3cfee0d
to
fd364d8
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.
This is starting to look great. A few minor comments and I really think this needs a test of the new logic around channelmonitors failing to update after a force-close or heigh-based broadcast.
lightning/src/ln/channelmonitor.rs
Outdated
@@ -1253,7 +1253,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> { | |||
feerate_per_kw, | |||
htlc_outputs, | |||
}); | |||
self.onchain_tx_handler.provide_latest_local_tx(commitment_tx); | |||
if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx) { | |||
return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed")); |
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.
Shouldnt this occur before we update the local state in the ChannelMonitor itself?
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 moved it, but added a big note than you may use in the loosely future a watchtower with a different implementation monitoring backend, which doesn't reject update in this case and may broadcast the latest local signed commitment received as update (assuming it has key access). And you want this backend to be able to claim outputs. That's really an edge-case so just a comment for now.
lightning/src/ln/onchaintx.rs
Outdated
// commitment transaction view to avoid delivery of revocation secret to counterparty | ||
// for the aformentionned signed transaction. | ||
if let Some(ref local_commitment) = self.local_commitment { | ||
#[cfg(not(test))] //Test framework may need to generate revoked commitment tx, don't generate a monitor error |
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.
Oof, I strongly disagree with this - this is an error condition that we should be writing tests to trigger, not turning off in testing. I really think the previous design of an exposed test-only version is much better.
fd364d8
to
eff2232
Compare
/// TODO: Document the things someone using this interface should enforce before signing. | ||
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and | ||
/// making the callee generate it via some util function we expose)! | ||
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>); |
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 a pattern of returning a Result<Signature, Error>
(rather than mutating the tx) is a cleaner API:
- is a pure function, so easy to see that it doesn't have any unexpected side-effects
- allows return of an error result. for example, see here where an error may happen and we don't want to fail silently. In the future, there may be other failures we want to communicate, related to policy checks.
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.
Agreed. Sadly, this PR has gotten large, and kinda leaves a few of the API bits around signing logic to future PRs. See #567 for the tracking issue.
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.
Thanks for your input, I agree we have room to improve the ChannelKeys API. I would rather do it in follow-up PRs, at first this one was scoped to move generation of local transactions in one place (OnchainTxHandler). Extending ChannelKeys to sign local was just an easy way to avoid breaking signature during the move.
I referenced your comments in #567 to be sure to not forget them.
lightning/src/ln/chan_utils.rs
Outdated
//TODO: modify Channel methods to integrate HTLC material at LocalCommitmentTransaction generation to drop Option here | ||
local_keys: Option<TxCreationKeys>, | ||
feerate_per_kw: Option<u64>, | ||
per_htlc: HashMap<u32, (HTLCOutputInCommitment, Option<Signature>, Option<Transaction>)> |
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.
Oof. Can we skip the HashMap here and just use a Vec<Option<>> - there should only ever be at max two (three with anchor) Nones in the list.
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.
Fixed
/// TODO: Document the things someone using this interface should enforce before signing. | ||
/// TODO: Add more input vars to enable better checking (preferably removing commitment_tx and | ||
/// making the callee generate it via some util function we expose)! | ||
fn sign_local_commitment<T: secp256k1::Signing + secp256k1::Verification>(&self, local_commitment_tx: &mut LocalCommitmentTransaction, funding_redeemscript: &Script, channel_value_satoshis: u64, secp_ctx: &Secp256k1<T>); |
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.
Agreed. Sadly, this PR has gotten large, and kinda leaves a few of the API bits around signing logic to future PRs. See #567 for the tracking issue.
12de2f1
to
b07747a
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.
Got most of the way through and found a number of things that seem to violate clearly-stated precondions :/.
if self.local_keys.is_none() || self.feerate_per_kw.is_none() { return; } | ||
let local_keys = self.local_keys.as_ref().unwrap(); | ||
let txid = self.txid(); | ||
for this_htlc in self.per_htlc.iter_mut() { |
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.
Oof. I didn't mean to scan the whole vec each time we want to sign something, you can keep them in htlc_index order. Again, this will get fixed as a side-effect of a better API so fine to leave it, but that hurts.
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.
That's not a hot path given that's only when we go onchain, so good enough to wait for an API clean up :)
lightning/src/ln/channelmonitor.rs
Outdated
if self.their_to_self_delay.is_none() { | ||
return Err(MonitorUpdateError("Got a local commitment tx info update before we'd set basic information about the channel")); | ||
} | ||
let txid = commitment_tx.txid(); | ||
self.current_local_commitment_number = 0xffff_ffff_ffff - ((((commitment_tx.without_valid_witness().input[0].sequence as u64 & 0xffffff) << 3*8) | (commitment_tx.without_valid_witness().lock_time as u64 & 0xffffff)) ^ self.commitment_transaction_number_obscure_factor); |
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.
Wait, huh. I thought we were doing all the updates after the tx_handler.provide_latest_local_ call. Isn't this a severe bug - if the remote ChannelMonitor is updating we may end up with the wrong current_local_commitment_number set, breaking claiming?
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's not nasty as this, because it would mean we already have a lockdown ChannelMonitor and a local commitment transaction broadcast, as far as I can tell it would just mean an already-closed channel wouldn't be call for force-closure a second time by ChannelManager deserialization. But yes that's clearly a bug so fixed it
for htlc in local_tx.htlc_outputs.iter() { | ||
if let Some(htlc_index) = htlc.0.transaction_output_index { | ||
let preimage = if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(*preimage) } else { None }; | ||
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(txid, htlc_index, preimage) { |
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.
This seems to violate the docs for sign_htlc_transacion, which says "If the transaction is an
/// HTLC-Success transaction (ie htlc.offered is false), preimage must be set!"?
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.
Yes this is currently enforced in OnchainTxHandler::get_fully_signed_htlc_tx. IIRC I doubt a bit between checking in ChannelMonitor or OnchainTxHandler, I think that's the same and only temporary waiting for a further API refactor.
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, I missed that you added a check in add_htlc_sig that didn't exist in sign_htlc_transaction without updating the comment. Its kinda awkward that the LocalCommitmentTransaction layer checks that the caller did something sane, but, for now, OK.
b07747a
to
7f4b668
Compare
Needs rebase. |
7f4b668
to
922b325
Compare
Rebased, but wasn't any conflict |
lightning/src/ln/chan_utils.rs
Outdated
let local_keys = Readable::read(reader)?; | ||
let feerate_per_kw = Readable::read(reader)?; | ||
let htlcs_count: u64 = Readable::read(reader)?; | ||
let mut per_htlc = Vec::with_capacity(cmp::min(htlcs_count as usize, MAX_ALLOC_SIZE / std::mem::size_of::<(HTLCOutputInCommitment, Option<Signature>, Option<Transaction>)>())); |
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.
This doesnt compile on 1.22 - you need ::std::mem
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.
Should be solved at f07505e
f07505e
to
a51477b
Compare
Extend external signer interface to sign local commitment transactions on its behalf without seckey passing. This move will allow us to remove key access from ChannelMonitor hot memory in further work. Local commitment transaction should stay half-signed by remote until we need to broadcast for a channel force-close or a HTLC to timeout onchain. Add an unsafe test-only version of sign_local_commitment to fulfill our test_framework needs.
a51477b
to
68c5522
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.
Just a few trivial things left, Everything else is good to go, I think.
@@ -2346,48 +2346,39 @@ fn claim_htlc_outputs_single_tx() { | |||
} | |||
|
|||
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap(); | |||
assert_eq!(node_txn.len(), 21); | |||
assert_eq!(node_txn.len(), 9); |
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.
Huh? As of the tip of this PR The list of txns appears to be duplicative, and neither adds up to 9.
let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); | ||
assert_eq!(updates.update_fulfill_htlcs.len(), 1); | ||
nodes[0].node.handle_update_fulfill_htlc(&nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]); | ||
if let Some(ref mut channel) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&chan_1.2) { |
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.
Oof, lets not cheat - this is a supported operation, use the public API.
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.
Yeah but I think I need to implement another ManyChannelMonitor for simulating one monitor being out-of-sync and the other fine. I can add a TODO, when we add test stuff for watchtowers ?
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.
You should be able to just add a utility there to track the latest updates and get the update from there. I think it should be a rather trivial change.
lightning/src/ln/functional_tests.rs
Outdated
watchtower.simple_monitor.block_connected(&header, 200, &vec![], &vec![]); | ||
|
||
// Try to update ChannelMonitor | ||
assert!(nodes[1].node.claim_funds(preimage, 9_000_000)); |
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.
Needs rebase, just add a &None for the secret.
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 was good, I just forget to commit on last push...
pending_claim_updates.push((*first_claim_txid, new_timer, new_feerate)); | ||
} | ||
} | ||
for updates in pending_claim_updates { |
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.
This seems to not be needed. At least if I revert most of this hunk at the end it still passes borrowck etc.
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.
Hmmmm? I hit a borrow checker with original hunk, you can't have both pending_claim_requests
as mutable and generate_claim_tx
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.
Hmm, this diff compiles for me?
diff --git a/lightning/src/ln/onchaintx.rs b/lightning/src/ln/onchaintx.rs
index 2f08fe291..3b8238ddc 100644
--- a/lightning/src/ln/onchaintx.rs
+++ b/lightning/src/ln/onchaintx.rs
@@ -713,18 +713,14 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
// Build, bump and rebroadcast tx accordingly
log_trace!(self, "Bumping {} candidates", bump_candidates.len());
- let mut pending_claim_updates = Vec::with_capacity(bump_candidates.len());
for (first_claim_txid, claim_material) in bump_candidates.iter() {
if let Some((new_timer, new_feerate, bump_tx)) = self.generate_claim_tx(height, &claim_material, &*fee_estimator) {
log_trace!(self, "Broadcast onchain {}", log_tx!(bump_tx));
broadcaster.broadcast_transaction(&bump_tx);
- pending_claim_updates.push((*first_claim_txid, new_timer, new_feerate));
- }
- }
- for updates in pending_claim_updates {
- if let Some(claim_material) = self.pending_claim_requests.get_mut(&updates.0) {
- claim_material.height_timer = updates.1;
- claim_material.feerate_previous = updates.2;
+ if let Some(claim_material) = self.pending_claim_requests.get_mut(first_claim_txid) {
+ claim_material.height_timer = new_timer;
+ claim_material.feerate_previous = new_feerate;
+ }
}
}
}
Previously, we would regenerate this class of txn twice due to block-rescan triggered by new watching outputs registered. This commmit doesn't change behavior, it only tweaks TestBroadcaster to ensure we modify cleanly tests anticipating next commit refactor.
As transaction generation and signature is headed to be moved inside OnchainTxHandler, cache any usefule witness element.
As transaction generation and signature is headed to be moved inside OnchainTxHandler, cache local_commitment_tx signed by remote. If access to local commitment transaction is needed, we extend Onchain TxHandler API to do so.
To prevent any unsafe state discrepancy between offchain and onchain, once local commitment transaction has been signed due to an event (either block height for HTLC-timeout or channel force-closure), don't allow any further update of local commitment transaction view to avoid delivery of revocation secret to counterparty for the aformentionned signed transaction.
Local Commitment Transaction can't be bumped without anchor outputs so their generation is one-time for now. We move them in OnchainTxHandler for simplifying ChannelMonitor and to prepare storage of keys material behind one external signer interface. Some tests break due to change in transaction broadcast order but number of transactions broadcast should stay the same.
By caching current local commitment number instead of deciphering it from local commitment tx, we may remove local commitment tx from ChannelMonitor in next commit.
Implementing dynamic fee bumping implied to cache transaction material including its witness, to generate a bumped version if needed. ChannelMonitor is slowly rescoped to its parsing function with ongoing patchset and data duplicata are removed. If signed local commitment tx access is needed, it's done through OnchainTxHandler extended API For test framework purpose, we use the test-only method ChannelMonitor::unsafe_get_latest_local_commitment_txn to intentionally generate unsafe local commitment to exerce revocation logic.
Caching of input material for HTLC transaction was introducted prevently but since then API (InputMaterial) has changed between ChannelMonitor and OnchainTxHandler
Extend external signer interface to sign HTLC transactions on its behalf without seckey passing. This move will allow us to remove key access access from ChannelMonitor hot memory in further work. HTLC transactions should stay half-signed by remote until we need to broadcast them for timing-out/claiming HTLCs onchain.
Splitting further parsing from transaction generation, we cache transaction elements needed for local HTLC transaction inside OnchainTxHandler. Duplicated data will be removed from ChannelMonitor in future commits.
Splitting further parsing from transaction generation, we cache transaction elements needed for local HTLC transaction inside OnchainTxHandler. Duplicated data will be removed from ChannelMonitor in future commits.
csv_local is csv_delay encumbering local revokable_redeemscript for to_local an htlc output on local commitment/HTLC transactions.
In case of channel force-closure, access to local commitment transactions and its dependent HTLCs is needed. Instead of using broadcast_by_local_state which registers outpoint to claim and outputs to watch which are going to be discarded in this case, we simply ask OnchainTxHandler to build and sign HTLC transactions through new API.
HTLC Transaction can't be bumped without sighash changes so their gneeration is one-time for nwo. We move them in OnchainTxHandler for simplifying ChannelMonitor and to prepare storage of keys material behind one external signer interface. Some tests break due to change in transaction broadcaster order. Number of transactions may vary because of temporary anti-duplicata tweak can't dissociate between 2- broadcast from different origins (ChannelMonitor, ChannelManager) and 2-broadcast from same component.
Local commitment transaction broadcast can be triggered by a) a Channel force-close or b) reaching some block height implying a onchain HTLC-timeout. If one of this condition is fulfilled, commitment is signed and from then any state update would be rejected. ChannelMonitor init at Channel creation need to be refactored before to make get_fully_signed_local_tx infaillible to avoid choking in the test framework.
Channel shouldn't send a ChannelForceClosed update followed by a LatestLocalCommitmentTxInfo as it would be a programming error leading to risk of money loss. Force-closing the channel will broadcast the local commitment transaction, if the revocation secret for this one is released after its broadcast, it would allow remote party to claim outputs on this transaction using the revocation path.
This test tries the new lockdown logic in case of a signed-and-broadcast local commitment transaction while a concurrent ChannelMonitorUpdate for a next _local_ commitment is submitted from offchain. Update is rejected as expected with a ChannelMonitorUpdateErr.
68c5522
to
95830ed
Compare
ChannelMonitor is more and more scoped to be reduce to parsing only, which means any outpoint part of a channel on which we should take actions is going to be spend by OnchainTxHandler. Doing so on a high-level, let OnchainTxHandler manage dynamic fees and broadcasting frequency without intertwining with detection.
To achieve this goal, we need to cache more transactions elements in OnchainTxHandler, some of them are static (csv_delay), other per channel update (htlc pubkeys, feerate). Detection should hand only hand over a identifier to OnchainTxHandler from which a fully-fledged transaction should be generated.
Access to Local and HTLC transactions is still maintained as it's needed in for channel force-closure or manual transaction broadcasting (fallen-behind case). Post-anchor output, dynamic bumping of pre-signed transactions means we should also remove ChannelMonitor::broadcast_latest_local_commitment_txn and block asynchronously register outpoint to claim with OnchainTxHandler.
We take benefits of this refactoring to also move local/HTLC transaction signature behind external signer interface.
Replace #540