Skip to content

Commit 3ca10f4

Browse files
committed
channel state check
1 parent c9d03d4 commit 3ca10f4

File tree

4 files changed

+103
-7
lines changed

4 files changed

+103
-7
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use crate::ln::chan_utils::{
5050
self, ChannelTransactionParameters, CommitmentTransaction, CounterpartyCommitmentSecrets,
5151
HTLCClaim, HTLCOutputInCommitment, HolderCommitmentTransaction,
5252
};
53-
use crate::ln::channel::INITIAL_COMMITMENT_NUMBER;
53+
use crate::ln::channel::{read_check_data, INITIAL_COMMITMENT_NUMBER};
5454
use crate::ln::channel_keys::{
5555
DelayedPaymentBasepoint, DelayedPaymentKey, HtlcBasepoint, HtlcKey, RevocationBasepoint,
5656
RevocationKey,
@@ -1535,6 +1535,9 @@ const MIN_SERIALIZATION_VERSION: u8 = 1;
15351535
pub(crate) fn write_chanmon_internal<Signer: EcdsaChannelSigner, W: Writer>(
15361536
channel_monitor: &ChannelMonitorImpl<Signer>, _is_stub: bool, writer: &mut W,
15371537
) -> Result<(), Error> {
1538+
if let Some(ref encoded_channel) = channel_monitor.encoded_channel {
1539+
channel_monitor.check_encoded_channel_consistency(encoded_channel);
1540+
}
15381541
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
15391542

15401543
channel_monitor.latest_update_id.write(writer)?;
@@ -2160,9 +2163,10 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
21602163
self.inner.lock().unwrap().encoded_channel.clone()
21612164
}
21622165

2163-
/// Updates the encoded channel data associated with this ChannelMonitor.
2166+
/// Updates the encoded channel data associated with this ChannelMonitor. To clear the encoded channel data (for
2167+
/// example after shut down of a channel), pass an empty vector.
21642168
pub fn update_encoded_channel(&self, encoded: Vec<u8>) {
2165-
self.inner.lock().unwrap().encoded_channel = Some(encoded);
2169+
self.inner.lock().unwrap().update_encoded_channel(encoded);
21662170
}
21672171

21682172
/// Gets the update_id from the latest ChannelMonitorUpdate which was applied to this
@@ -2770,6 +2774,34 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitor<Signer> {
27702774
}
27712775

27722776
impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
2777+
fn check_encoded_channel_consistency(&self, encoded: &[u8]) {
2778+
let encoded_channel_reader = &mut &encoded[..];
2779+
let check_data = read_check_data(encoded_channel_reader).unwrap();
2780+
2781+
assert!(
2782+
check_data.cur_holder_commitment_transaction_number
2783+
<= self.get_cur_holder_commitment_number()
2784+
);
2785+
assert!(
2786+
check_data.revoked_counterparty_commitment_transaction_number
2787+
<= self.get_min_seen_secret()
2788+
);
2789+
assert!(
2790+
check_data.cur_counterparty_commitment_transaction_number
2791+
<= self.get_cur_counterparty_commitment_number()
2792+
);
2793+
assert!(check_data.latest_monitor_update_id >= self.get_latest_update_id());
2794+
}
2795+
2796+
fn update_encoded_channel(&mut self, encoded: Vec<u8>) {
2797+
if encoded.len() > 0 {
2798+
self.check_encoded_channel_consistency(&encoded);
2799+
self.encoded_channel = Some(encoded);
2800+
} else {
2801+
self.encoded_channel = None;
2802+
}
2803+
}
2804+
27732805
/// Helper for get_claimable_balances which does the work for an individual HTLC, generating up
27742806
/// to one `Balance` for the HTLC.
27752807
#[rustfmt::skip]
@@ -4464,7 +4496,7 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> {
44644496
// Assume that if the updates contains no encoded channel, that the channel remained unchanged. We
44654497
// therefore do not update the monitor.
44664498
if let Some(encoded_channel) = updates.encoded_channel.as_ref() {
4467-
self.encoded_channel = Some(encoded_channel.clone());
4499+
self.update_encoded_channel(encoded_channel.clone());
44684500
}
44694501
Ok(())
44704502
}
@@ -7079,6 +7111,7 @@ mod tests {
70797111
check_added_monitors(&nodes[1], 1);
70807112
}
70817113

7114+
#[cfg(not(feature = "safe_channels"))]
70827115
#[test]
70837116
fn test_funding_spend_refuses_updates() {
70847117
do_test_funding_spend_refuses_updates(true);

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,6 +3581,7 @@ fn do_test_blocked_chan_preimage_release(completion_mode: BlockedUpdateComplMode
35813581
expect_payment_sent(&nodes[2], payment_preimage_2, None, true, true);
35823582
}
35833583

3584+
#[cfg(not(feature = "safe_channels"))]
35843585
#[test]
35853586
fn test_blocked_chan_preimage_release() {
35863587
do_test_blocked_chan_preimage_release(BlockedUpdateComplMode::AtReload);

lightning/src/ln/channel.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6045,7 +6045,7 @@ where
60456045
should_broadcast: broadcast,
60466046
}],
60476047
channel_id: Some(self.channel_id()),
6048-
encoded_channel: None,
6048+
encoded_channel: Some(Vec::new()), // Clear channel on shut down.
60496049
};
60506050
Some((self.get_counterparty_node_id(), funding_txo, self.channel_id(), update))
60516051
} else {
@@ -8195,6 +8195,7 @@ where
81958195
}
81968196
log_debug!(logger, "Received valid commitment_signed from peer in channel {}, updated HTLC state but awaiting a monitor update resolution to reply.",
81978197
&self.context.channel_id);
8198+
monitor_update.encoded_channel = Some(self.encode());
81988199
return Ok(self.push_ret_blockable_mon_update(monitor_update));
81998200
}
82008201

@@ -12724,13 +12725,13 @@ where
1272412725
}
1272512726

1272612727
self.context.latest_monitor_update_id += 1;
12728+
self.context.channel_state.set_awaiting_remote_revoke();
1272712729
let monitor_update = ChannelMonitorUpdate {
1272812730
update_id: self.context.latest_monitor_update_id,
1272912731
updates: vec![update],
1273012732
channel_id: Some(self.context.channel_id()),
1273112733
encoded_channel: Some(self.encode()),
1273212734
};
12733-
self.context.channel_state.set_awaiting_remote_revoke();
1273412735
monitor_update
1273512736
}
1273612737

@@ -15601,6 +15602,62 @@ where
1560115602
}
1560215603
}
1560315604

15605+
pub struct ChannelStateCheckData {
15606+
pub cur_holder_commitment_transaction_number: u64,
15607+
pub revoked_counterparty_commitment_transaction_number: u64,
15608+
pub cur_counterparty_commitment_transaction_number: u64,
15609+
pub latest_monitor_update_id: u64,
15610+
}
15611+
15612+
pub fn read_check_data<R: io::Read>(reader: &mut R) -> Result<ChannelStateCheckData, DecodeError> {
15613+
let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
15614+
if ver <= 2 {
15615+
return Err(DecodeError::UnknownVersion);
15616+
}
15617+
15618+
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
15619+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We read
15620+
// the low bytes now and the high bytes later.
15621+
let user_id_low: u64 = Readable::read(reader)?;
15622+
15623+
let mut config = LegacyChannelConfig::default();
15624+
{
15625+
// Read the 8 bytes of backwards-compatibility ChannelConfig data.
15626+
let mut _val: u64 = Readable::read(reader)?;
15627+
}
15628+
15629+
let channel_id: ChannelId = Readable::read(reader)?;
15630+
let channel_state =
15631+
ChannelState::from_u32(Readable::read(reader)?).map_err(|_| DecodeError::InvalidValue)?;
15632+
let channel_value_satoshis: u64 = Readable::read(reader)?;
15633+
15634+
let latest_monitor_update_id = Readable::read(reader)?;
15635+
15636+
// Read the old serialization for shutdown_pubkey, preferring the TLV field later if set.
15637+
let mut shutdown_scriptpubkey = match <PublicKey as Readable>::read(reader) {
15638+
Ok(pubkey) => Some(ShutdownScript::new_p2wpkh_from_pubkey(pubkey)),
15639+
Err(_) => None,
15640+
};
15641+
let destination_script: ScriptBuf = Readable::read(reader)?;
15642+
15643+
let holder_commitment_next_transaction_number: u64 = Readable::read(reader)?;
15644+
let counterparty_next_commitment_transaction_number: u64 = Readable::read(reader)?;
15645+
15646+
let cur_holder_commitment_transaction_number = holder_commitment_next_transaction_number + 1;
15647+
let revoked_counterparty_commitment_transaction_number =
15648+
counterparty_next_commitment_transaction_number + 2;
15649+
let cur_counterparty_commitment_transaction_number =
15650+
counterparty_next_commitment_transaction_number
15651+
+ if channel_state.is_awaiting_remote_revoke() { 0 } else { 1 };
15652+
15653+
Ok(ChannelStateCheckData {
15654+
cur_holder_commitment_transaction_number,
15655+
revoked_counterparty_commitment_transaction_number,
15656+
cur_counterparty_commitment_transaction_number,
15657+
latest_monitor_update_id,
15658+
})
15659+
}
15660+
1560415661
fn duration_since_epoch() -> Option<Duration> {
1560515662
#[cfg(not(feature = "std"))]
1560615663
let now = None;

lightning/src/ln/channelmanager.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16787,7 +16787,12 @@ where
1678716787
let mut channel_closures = VecDeque::new();
1678816788
let mut close_background_events = Vec::new();
1678916789
for (_, monitor) in args.channel_monitors.iter() {
16790-
let encoded_channel = monitor.get_encoded_channel().unwrap();
16790+
let opt_encoded_channel = monitor.get_encoded_channel();
16791+
if opt_encoded_channel.is_none() {
16792+
// Monitor still exists, but there is no more channel state. This can happen after channel shut down.
16793+
continue;
16794+
}
16795+
let encoded_channel = opt_encoded_channel.unwrap();
1679116796
let encoded_channel_reader = &mut &encoded_channel[..];
1679216797
let mut channel: FundedChannel<SP> = FundedChannel::read(
1679316798
encoded_channel_reader,

0 commit comments

Comments
 (0)