Skip to content

Commit a0d913b

Browse files
author
Antoine Riard
committed
Access signed local commitment through OnchainTxHandler
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
1 parent aa9de66 commit a0d913b

File tree

2 files changed

+31
-27
lines changed

2 files changed

+31
-27
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
16801680
(claimable_outpoints, Some((htlc_txid, tx.output.clone())))
16811681
}
16821682

1683-
fn broadcast_by_local_state(&self, local_tx: &LocalSignedTx) -> (Vec<Transaction>, Vec<TxOut>, Option<(Script, SecretKey, Script)>) {
1683+
fn broadcast_by_local_state(&self, commitment_tx: &Transaction, local_tx: &LocalSignedTx) -> (Vec<Transaction>, Vec<TxOut>, Option<(Script, SecretKey, Script)>) {
16841684
let mut res = Vec::with_capacity(local_tx.htlc_outputs.len());
16851685
let mut watch_outputs = Vec::with_capacity(local_tx.htlc_outputs.len());
16861686

@@ -1723,7 +1723,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17231723
res.push(htlc_success_tx);
17241724
}
17251725
}
1726-
watch_outputs.push(local_tx.tx.without_valid_witness().output[transaction_output_index as usize].clone());
1726+
watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone());
17271727
} else { panic!("Should have sigs for non-dust local tx outputs!") }
17281728
}
17291729
}
@@ -1777,16 +1777,15 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17771777
if local_tx.txid == commitment_txid {
17781778
is_local_tx = true;
17791779
log_trace!(self, "Got latest local commitment tx broadcast, searching for available HTLCs to claim");
1780-
let mut res = self.broadcast_by_local_state(local_tx);
1780+
let mut res = self.broadcast_by_local_state(tx, local_tx);
17811781
append_onchain_update!(res);
17821782
}
17831783
}
17841784
if let &Some(ref local_tx) = &self.prev_local_signed_commitment_tx {
17851785
if local_tx.txid == commitment_txid {
17861786
is_local_tx = true;
17871787
log_trace!(self, "Got previous local commitment tx broadcast, searching for available HTLCs to claim");
1788-
assert!(local_tx.tx.has_local_sig());
1789-
let mut res = self.broadcast_by_local_state(local_tx);
1788+
let mut res = self.broadcast_by_local_state(tx, local_tx);
17901789
append_onchain_update!(res);
17911790
}
17921791
}
@@ -1825,22 +1824,18 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
18251824
/// out-of-band the other node operator to coordinate with him if option is available to you.
18261825
/// In any-case, choice is up to the user.
18271826
pub fn get_latest_local_commitment_txn(&mut self) -> Vec<Transaction> {
1828-
// TODO: We should likely move all of the logic in here into OnChainTxHandler and unify it
1829-
// to ensure add_local_sig is only ever called once no matter what. This likely includes
1830-
// tracking state and panic!()ing if we get an update after force-closure/local-tx signing.
18311827
log_trace!(self, "Getting signed latest local commitment transaction!");
1832-
if let &mut Some(ref mut local_tx) = &mut self.current_local_signed_commitment_tx {
1833-
self.onchain_detection.keys.sign_local_commitment(&mut local_tx.tx, self.funding_redeemscript.as_ref().unwrap(), self.channel_value_satoshis.unwrap(), &self.secp_ctx);
1834-
}
1835-
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
1836-
let mut res = vec![local_tx.tx.with_valid_witness().clone()];
1837-
res.append(&mut self.broadcast_by_local_state(local_tx).0);
1838-
// We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
1839-
// The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation.
1840-
res
1841-
} else {
1842-
Vec::new()
1828+
if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(self.channel_value_satoshis.unwrap()) {
1829+
let mut res = vec![commitment_tx];
1830+
if let &Some(ref local_tx) = &self.current_local_signed_commitment_tx {
1831+
let mut htlc_txn = self.broadcast_by_local_state(res.get(0).unwrap(), local_tx).0;
1832+
res.append(&mut htlc_txn);
1833+
// We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
1834+
// The data will be re-generated and tracked in check_spend_local_transaction if we get a confirmation.
1835+
}
1836+
return res
18431837
}
1838+
Vec::new()
18441839
}
18451840

18461841
/// Called by SimpleManyChannelMonitor::block_connected, which implements
@@ -1915,13 +1910,15 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
19151910
}
19161911
if let Some(ref cur_local_tx) = self.current_local_signed_commitment_tx {
19171912
if should_broadcast {
1918-
let (txs, new_outputs, _) = self.broadcast_by_local_state(&cur_local_tx);
1919-
if !new_outputs.is_empty() {
1920-
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1921-
}
1922-
for tx in txs {
1923-
log_trace!(self, "Broadcast onchain {}", log_tx!(tx));
1924-
broadcaster.broadcast_transaction(&tx);
1913+
if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(self.channel_value_satoshis.unwrap()) {
1914+
let (txs, new_outputs, _) = self.broadcast_by_local_state(&commitment_tx, cur_local_tx);
1915+
if !new_outputs.is_empty() {
1916+
watch_outputs.push((cur_local_tx.txid.clone(), new_outputs));
1917+
}
1918+
for tx in txs {
1919+
log_trace!(self, "Broadcast onchain {}", log_tx!(tx));
1920+
broadcaster.broadcast_transaction(&tx);
1921+
}
19251922
}
19261923
}
19271924
}
@@ -2394,7 +2391,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for (Sha256dH
23942391

23952392
LocalSignedTx {
23962393
txid: tx.txid(),
2397-
tx, revocation_key, a_htlc_key, b_htlc_key, delayed_payment_key, per_commitment_point, feerate_per_kw,
2394+
tx,
2395+
revocation_key, a_htlc_key, b_htlc_key, delayed_payment_key, per_commitment_point, feerate_per_kw,
23982396
htlc_outputs: htlcs
23992397
}
24002398
}

lightning/src/ln/onchaintx.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,4 +760,10 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
760760
self.prev_local_commitment = self.local_commitment.take();
761761
self.local_commitment = Some(tx);
762762
}
763+
764+
pub(super) fn get_fully_signed_local_tx(&mut self, channel_value_satoshis: u64) -> Option<Transaction> {
765+
let mut local_commitment = self.local_commitment.as_mut().unwrap();
766+
self.key_storage.sign_local_commitment(&mut local_commitment, &self.funding_redeemscript, channel_value_satoshis, &self.secp_ctx);
767+
return Some(local_commitment.with_valid_witness().clone());
768+
}
763769
}

0 commit comments

Comments
 (0)