Skip to content

Commit 234b7d8

Browse files
committed
Re-derive signers upon deserializing Channel
To do so, we introduce a new serialization version that doesn't store a channel's signer, and instead stores its signer's `channel_keys_id`. This is a unique identifier that can be provided to our `KeysInterface` to re-derive all private key material for said channel. We choose to not upgrade the minimum compatible serialization version until a later time, which will also remove any signer serialization logic on implementations of `KeysInterface` and `Sign`.
1 parent 4aa662b commit 234b7d8

File tree

1 file changed

+47
-19
lines changed

1 file changed

+47
-19
lines changed

lightning/src/ln/channel.rs

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ use crate::chain::BestBlock;
3434
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, LowerBoundedFeeEstimator};
3535
use crate::chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
3636
use crate::chain::transaction::{OutPoint, TransactionData};
37-
use crate::chain::keysinterface::{Sign, KeysInterface};
37+
use crate::chain::keysinterface::{Sign, KeysInterface, BaseSign};
3838
use crate::util::events::ClosureReason;
39-
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
39+
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer};
4040
use crate::util::logger::Logger;
4141
use crate::util::errors::APIError;
4242
use crate::util::config::{UserConfig, ChannelConfig, LegacyChannelConfig, ChannelHandshakeConfig, ChannelHandshakeLimits};
@@ -739,6 +739,10 @@ pub(super) struct Channel<Signer: Sign> {
739739

740740
// We track whether we already emitted a `ChannelReady` event.
741741
channel_ready_event_emitted: bool,
742+
743+
/// The unique identifier used to re-derive the private key material for the channel through
744+
/// [`KeysInterface::derive_channel_signer`].
745+
_channel_keys_id: [u8; 32],
742746
}
743747

744748
#[cfg(any(test, fuzzing))]
@@ -912,6 +916,7 @@ impl<Signer: Sign> Channel<Signer> {
912916

913917
let holder_selected_contest_delay = config.channel_handshake_config.our_to_self_delay;
914918
let holder_signer = keys_provider.get_channel_signer(false, channel_value_satoshis);
919+
let channel_keys_id = holder_signer.channel_keys_id();
915920
let pubkeys = holder_signer.pubkeys().clone();
916921

917922
if !their_features.supports_wumbo() && channel_value_satoshis > MAX_FUNDING_SATOSHIS_NO_WUMBO {
@@ -1072,6 +1077,7 @@ impl<Signer: Sign> Channel<Signer> {
10721077
historical_inbound_htlc_fulfills: HashSet::new(),
10731078

10741079
channel_type: Self::get_initial_channel_type(&config),
1080+
_channel_keys_id: channel_keys_id,
10751081
})
10761082
}
10771083

@@ -1155,6 +1161,7 @@ impl<Signer: Sign> Channel<Signer> {
11551161
}
11561162

11571163
let holder_signer = keys_provider.get_channel_signer(true, msg.funding_satoshis);
1164+
let channel_keys_id = holder_signer.channel_keys_id();
11581165
let pubkeys = holder_signer.pubkeys().clone();
11591166
let counterparty_pubkeys = ChannelPublicKeys {
11601167
funding_pubkey: msg.funding_pubkey,
@@ -1417,6 +1424,7 @@ impl<Signer: Sign> Channel<Signer> {
14171424
historical_inbound_htlc_fulfills: HashSet::new(),
14181425

14191426
channel_type,
1427+
_channel_keys_id: channel_keys_id,
14201428
};
14211429

14221430
Ok(chan)
@@ -5963,7 +5971,7 @@ impl<Signer: Sign> Channel<Signer> {
59635971
}
59645972
}
59655973

5966-
const SERIALIZATION_VERSION: u8 = 2;
5974+
const SERIALIZATION_VERSION: u8 = 3;
59675975
const MIN_SERIALIZATION_VERSION: u8 = 2;
59685976

59695977
impl_writeable_tlv_based_enum!(InboundHTLCRemovalReason,;
@@ -6044,13 +6052,6 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
60446052

60456053
self.latest_monitor_update_id.write(writer)?;
60466054

6047-
let mut key_data = VecWriter(Vec::new());
6048-
self.holder_signer.write(&mut key_data)?;
6049-
assert!(key_data.0.len() < core::usize::MAX);
6050-
assert!(key_data.0.len() < core::u32::MAX as usize);
6051-
(key_data.0.len() as u32).write(writer)?;
6052-
writer.write_all(&key_data.0[..])?;
6053-
60546055
// Write out the old serialization for shutdown_pubkey for backwards compatibility, if
60556056
// deserialized from that format.
60566057
match self.shutdown_scriptpubkey.as_ref().and_then(|script| script.as_legacy_pubkey()) {
@@ -6283,6 +6284,10 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62836284
// we write the high bytes as an option here.
62846285
let user_id_high_opt = Some((self.user_id >> 64) as u64);
62856286

6287+
// `channel_keys_id` is serialized as an option to remain backwards compatible until we bump
6288+
// `MIN_SERIALIZATION_VERSION` to 3.
6289+
let channel_keys_id = Some(self._channel_keys_id);
6290+
62866291
write_tlv_fields!(writer, {
62876292
(0, self.announcement_sigs, option),
62886293
// minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -6298,6 +6303,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62986303
(5, self.config, required),
62996304
(6, serialized_holder_htlc_max_in_flight, option),
63006305
(7, self.shutdown_scriptpubkey, option),
6306+
(8, channel_keys_id, option),
63016307
(9, self.target_closing_feerate_sats_per_kw, option),
63026308
(11, self.monitor_pending_finalized_fulfills, vec_type),
63036309
(13, self.channel_creation_height, required),
@@ -6343,16 +6349,19 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
63436349

63446350
let latest_monitor_update_id = Readable::read(reader)?;
63456351

6346-
let keys_len: u32 = Readable::read(reader)?;
6347-
let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
6348-
while keys_data.len() != keys_len as usize {
6349-
// Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
6350-
let mut data = [0; 1024];
6351-
let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
6352-
reader.read_exact(read_slice)?;
6353-
keys_data.extend_from_slice(read_slice);
6352+
let mut holder_signer = None;
6353+
if ver <= 2 {
6354+
let keys_len: u32 = Readable::read(reader)?;
6355+
let mut keys_data = Vec::with_capacity(cmp::min(keys_len as usize, MAX_ALLOC_SIZE));
6356+
while keys_data.len() != keys_len as usize {
6357+
// Read 1KB at a time to avoid accidentally allocating 4GB on corrupted channel keys
6358+
let mut data = [0; 1024];
6359+
let read_slice = &mut data[0..cmp::min(1024, keys_len as usize - keys_data.len())];
6360+
reader.read_exact(read_slice)?;
6361+
keys_data.extend_from_slice(read_slice);
6362+
}
6363+
holder_signer = Some(keys_source.read_chan_signer(&keys_data)?);
63546364
}
6355-
let holder_signer = keys_source.read_chan_signer(&keys_data)?;
63566365

63576366
// Read the old serialization for shutdown_pubkey, preferring the TLV field later if set.
63586367
let mut shutdown_scriptpubkey = match <PublicKey as Readable>::read(reader) {
@@ -6570,6 +6579,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65706579
let mut channel_ready_event_emitted = None;
65716580

65726581
let mut user_id_high_opt: Option<u64> = None;
6582+
let mut channel_keys_id: Option<[u8; 32]> = None;
65736583

65746584
read_tlv_fields!(reader, {
65756585
(0, announcement_sigs, option),
@@ -6580,6 +6590,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65806590
(5, config, option), // Note that if none is provided we will *not* overwrite the existing one.
65816591
(6, holder_max_htlc_value_in_flight_msat, option),
65826592
(7, shutdown_scriptpubkey, option),
6593+
(8, channel_keys_id, option),
65836594
(9, target_closing_feerate_sats_per_kw, option),
65846595
(11, monitor_pending_finalized_fulfills, vec_type),
65856596
(13, channel_creation_height, option),
@@ -6591,6 +6602,22 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65916602
(25, user_id_high_opt, option),
65926603
});
65936604

6605+
let (channel_keys_id, mut holder_signer) = if ver <= 2 {
6606+
assert!(holder_signer.is_some() && channel_keys_id.is_none());
6607+
let holder_signer = holder_signer.unwrap();
6608+
(holder_signer.channel_keys_id(), holder_signer)
6609+
} else {
6610+
assert!(holder_signer.is_none() && channel_keys_id.is_some());
6611+
let channel_keys_id = channel_keys_id.unwrap();
6612+
(channel_keys_id, keys_source.derive_channel_signer(channel_value_satoshis, channel_keys_id))
6613+
};
6614+
// If we've gotten to the funding stage of the channel, populate the signer with its
6615+
// required channel parameters.
6616+
let non_shutdown_state = channel_state & (!MULTI_STATE_FLAGS);
6617+
if non_shutdown_state >= (ChannelState::FundingCreated as u32) {
6618+
holder_signer.ready_channel(&channel_parameters);
6619+
}
6620+
65946621
if let Some(preimages) = preimages_opt {
65956622
let mut iter = preimages.into_iter();
65966623
for htlc in pending_outbound_htlcs.iter_mut() {
@@ -6740,6 +6767,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
67406767
historical_inbound_htlc_fulfills,
67416768

67426769
channel_type: channel_type.unwrap(),
6770+
_channel_keys_id: channel_keys_id,
67436771
})
67446772
}
67456773
}

0 commit comments

Comments
 (0)