Skip to content

Commit 034bd5f

Browse files
author
Antoine Riard
committed
Cache HTLC transaction material inside OnchainTxHandler
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.
1 parent d253ce6 commit 034bd5f

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
12701270
// reject update as we do, you MAY have the latest local valid commitment tx onchain
12711271
// for which you want to spend outputs. We're NOT robust again this scenario right
12721272
// now but we should consider it later.
1273-
if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx.clone()) {
1273+
if let Err(_) = self.onchain_tx_handler.provide_latest_local_tx(commitment_tx.clone(), local_keys.clone(), feerate_per_kw) {
12741274
return Err(MonitorUpdateError("Local commitment signed has already been signed, no further update of LOCAL commitment transaction is allowed"));
12751275
}
12761276
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);

lightning/src/ln/onchaintx.rs

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use secp256k1;
1515

1616
use ln::msgs::DecodeError;
1717
use ln::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER, InputMaterial, ClaimRequest};
18-
use ln::chan_utils::{HTLCType, LocalCommitmentTransaction};
18+
use ln::chan_utils;
19+
use ln::chan_utils::{HTLCType, LocalCommitmentTransaction, TxCreationKeys};
1920
use chain::chaininterface::{FeeEstimator, BroadcasterInterface, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
2021
use chain::keysinterface::ChannelKeys;
2122
use util::logger::Logger;
@@ -47,6 +48,14 @@ enum OnchainEvent {
4748
}
4849
}
4950

51+
/// Cache public keys and feerate used to compute any HTLC transaction.
52+
/// We only keep state for latest 2 commitment transactions as we should
53+
/// never have to generate HTLC txn for revoked local commitment
54+
struct HTLCTxCache {
55+
local_keys: TxCreationKeys,
56+
feerate_per_kw: u64,
57+
}
58+
5059
/// Higher-level cache structure needed to re-generate bumped claim txn if needed
5160
#[derive(Clone, PartialEq)]
5261
pub struct ClaimTxBumpMaterial {
@@ -144,6 +153,8 @@ pub struct OnchainTxHandler<ChanSigner: ChannelKeys> {
144153
funding_redeemscript: Script,
145154
local_commitment: Option<LocalCommitmentTransaction>,
146155
prev_local_commitment: Option<LocalCommitmentTransaction>,
156+
current_htlc_cache: Option<HTLCTxCache>,
157+
prev_htlc_cache: Option<HTLCTxCache>,
147158

148159
key_storage: ChanSigner,
149160

@@ -187,6 +198,27 @@ impl<ChanSigner: ChannelKeys + Writeable> OnchainTxHandler<ChanSigner> {
187198
self.local_commitment.write(writer)?;
188199
self.prev_local_commitment.write(writer)?;
189200

201+
macro_rules! serialize_htlc_cache {
202+
($cache: expr) => {
203+
$cache.local_keys.write(writer)?;
204+
$cache.feerate_per_kw.write(writer)?;
205+
}
206+
}
207+
208+
if let Some(ref current) = self.current_htlc_cache {
209+
writer.write_all(&[1; 1])?;
210+
serialize_htlc_cache!(current);
211+
} else {
212+
writer.write_all(&[0; 1])?;
213+
}
214+
215+
if let Some(ref prev) = self.prev_htlc_cache {
216+
writer.write_all(&[1; 1])?;
217+
serialize_htlc_cache!(prev);
218+
} else {
219+
writer.write_all(&[0; 1])?;
220+
}
221+
190222
self.key_storage.write(writer)?;
191223

192224
writer.write_all(&byte_utils::be64_to_array(self.pending_claim_requests.len() as u64))?;
@@ -231,6 +263,35 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for OnchainTx
231263
let local_commitment = Readable::read(reader)?;
232264
let prev_local_commitment = Readable::read(reader)?;
233265

266+
macro_rules! read_htlc_cache {
267+
() => {
268+
{
269+
let local_keys = Readable::read(reader)?;
270+
let feerate_per_kw = Readable::read(reader)?;
271+
HTLCTxCache {
272+
local_keys,
273+
feerate_per_kw,
274+
}
275+
}
276+
}
277+
}
278+
279+
let current_htlc_cache = match <u8 as Readable>::read(reader)? {
280+
0 => None,
281+
1 => {
282+
Some(read_htlc_cache!())
283+
}
284+
_ => return Err(DecodeError::InvalidValue),
285+
};
286+
287+
let prev_htlc_cache = match <u8 as Readable>::read(reader)? {
288+
0 => None,
289+
1 => {
290+
Some(read_htlc_cache!())
291+
}
292+
_ => return Err(DecodeError::InvalidValue),
293+
};
294+
234295
let key_storage = Readable::read(reader)?;
235296

236297
let pending_claim_requests_len: u64 = Readable::read(reader)?;
@@ -281,6 +342,8 @@ impl<ChanSigner: ChannelKeys + Readable> ReadableArgs<Arc<Logger>> for OnchainTx
281342
funding_redeemscript,
282343
local_commitment,
283344
prev_local_commitment,
345+
current_htlc_cache,
346+
prev_htlc_cache,
284347
key_storage,
285348
claimable_outpoints,
286349
pending_claim_requests,
@@ -301,6 +364,8 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
301364
funding_redeemscript,
302365
local_commitment: None,
303366
prev_local_commitment: None,
367+
current_htlc_cache: None,
368+
prev_htlc_cache: None,
304369
key_storage,
305370
pending_claim_requests: HashMap::new(),
306371
claimable_outpoints: HashMap::new(),
@@ -756,7 +821,7 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
756821
}
757822
}
758823

759-
pub(super) fn provide_latest_local_tx(&mut self, tx: LocalCommitmentTransaction) -> Result<(), ()> {
824+
pub(super) fn provide_latest_local_tx(&mut self, tx: LocalCommitmentTransaction, local_keys: chan_utils::TxCreationKeys, feerate_per_kw: u64) -> Result<(), ()> {
760825
// To prevent any unsafe state discrepancy between offchain and onchain, once local
761826
// commitment transaction has been signed due to an event (either block height for
762827
// HTLC-timeout or channel force-closure), don't allow any further update of local
@@ -767,6 +832,11 @@ impl<ChanSigner: ChannelKeys> OnchainTxHandler<ChanSigner> {
767832
}
768833
self.prev_local_commitment = self.local_commitment.take();
769834
self.local_commitment = Some(tx);
835+
self.prev_htlc_cache = self.current_htlc_cache.take();
836+
self.current_htlc_cache = Some(HTLCTxCache {
837+
local_keys,
838+
feerate_per_kw,
839+
});
770840
Ok(())
771841
}
772842

0 commit comments

Comments
 (0)