Skip to content

Commit e0986de

Browse files
authored
Merge pull request #916 from TheBlueMatt/2021-05-fix-disabled-announcements
Avoid persisting a ChannelManager after each timer tick and send update_channel re-enable messages
2 parents eeabac8 + ee36d64 commit e0986de

File tree

3 files changed

+184
-100
lines changed

3 files changed

+184
-100
lines changed

lightning/src/ln/channel.rs

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -248,18 +248,21 @@ const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisc
248248

249249
pub const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
250250

251-
/// Liveness is called to fluctuate given peer disconnecton/monitor failures/closing.
252-
/// If channel is public, network should have a liveness view announced by us on a
253-
/// best-effort, which means we may filter out some status transitions to avoid spam.
254-
/// See further timer_tick_occurred.
255-
#[derive(PartialEq)]
256-
enum UpdateStatus {
257-
/// Status has been gossiped.
258-
Fresh,
259-
/// Status has been changed.
260-
DisabledMarked,
261-
/// Status has been marked to be gossiped at next flush
251+
/// The "channel disabled" bit in channel_update must be set based on whether we are connected to
252+
/// our counterparty or not. However, we don't want to announce updates right away to avoid
253+
/// spamming the network with updates if the connection is flapping. Instead, we "stage" updates to
254+
/// our channel_update message and track the current state here.
255+
/// See implementation at [`super::channelmanager::ChannelManager::timer_tick_occurred`].
256+
#[derive(Clone, Copy, PartialEq)]
257+
pub(super) enum ChannelUpdateStatus {
258+
/// We've announced the channel as enabled and are connected to our peer.
259+
Enabled,
260+
/// Our channel is no longer live, but we haven't announced the channel as disabled yet.
262261
DisabledStaged,
262+
/// Our channel is live again, but we haven't announced the channel as enabled yet.
263+
EnabledStaged,
264+
/// We've announced the channel as disabled.
265+
Disabled,
263266
}
264267

265268
/// An enum indicating whether the local or remote side offered a given HTLC.
@@ -416,7 +419,7 @@ pub(super) struct Channel<Signer: Sign> {
416419

417420
commitment_secrets: CounterpartyCommitmentSecrets,
418421

419-
network_sync: UpdateStatus,
422+
channel_update_status: ChannelUpdateStatus,
420423

421424
// We save these values so we can make sure `next_local_commit_tx_fee_msat` and
422425
// `next_remote_commit_tx_fee_msat` properly predict what the next commitment transaction fee will
@@ -617,7 +620,7 @@ impl<Signer: Sign> Channel<Signer> {
617620

618621
commitment_secrets: CounterpartyCommitmentSecrets::new(),
619622

620-
network_sync: UpdateStatus::Fresh,
623+
channel_update_status: ChannelUpdateStatus::Enabled,
621624

622625
#[cfg(any(test, feature = "fuzztarget"))]
623626
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
@@ -858,7 +861,7 @@ impl<Signer: Sign> Channel<Signer> {
858861

859862
commitment_secrets: CounterpartyCommitmentSecrets::new(),
860863

861-
network_sync: UpdateStatus::Fresh,
864+
channel_update_status: ChannelUpdateStatus::Enabled,
862865

863866
#[cfg(any(test, feature = "fuzztarget"))]
864867
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
@@ -3495,24 +3498,12 @@ impl<Signer: Sign> Channel<Signer> {
34953498
} else { false }
34963499
}
34973500

3498-
pub fn to_disabled_staged(&mut self) {
3499-
self.network_sync = UpdateStatus::DisabledStaged;
3501+
pub fn channel_update_status(&self) -> ChannelUpdateStatus {
3502+
self.channel_update_status
35003503
}
35013504

3502-
pub fn to_disabled_marked(&mut self) {
3503-
self.network_sync = UpdateStatus::DisabledMarked;
3504-
}
3505-
3506-
pub fn to_fresh(&mut self) {
3507-
self.network_sync = UpdateStatus::Fresh;
3508-
}
3509-
3510-
pub fn is_disabled_staged(&self) -> bool {
3511-
self.network_sync == UpdateStatus::DisabledStaged
3512-
}
3513-
3514-
pub fn is_disabled_marked(&self) -> bool {
3515-
self.network_sync == UpdateStatus::DisabledMarked
3505+
pub fn set_channel_update_status(&mut self, status: ChannelUpdateStatus) {
3506+
self.channel_update_status = status;
35163507
}
35173508

35183509
fn check_get_funding_locked(&mut self, height: u32) -> Option<msgs::FundingLocked> {
@@ -4375,6 +4366,31 @@ impl Readable for InboundHTLCRemovalReason {
43754366
}
43764367
}
43774368

4369+
impl Writeable for ChannelUpdateStatus {
4370+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
4371+
// We only care about writing out the current state as it was announced, ie only either
4372+
// Enabled or Disabled. In the case of DisabledStaged, we most recently announced the
4373+
// channel as enabled, so we write 0. For EnabledStaged, we similarly write a 1.
4374+
match self {
4375+
ChannelUpdateStatus::Enabled => 0u8.write(writer)?,
4376+
ChannelUpdateStatus::DisabledStaged => 0u8.write(writer)?,
4377+
ChannelUpdateStatus::EnabledStaged => 1u8.write(writer)?,
4378+
ChannelUpdateStatus::Disabled => 1u8.write(writer)?,
4379+
}
4380+
Ok(())
4381+
}
4382+
}
4383+
4384+
impl Readable for ChannelUpdateStatus {
4385+
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
4386+
Ok(match <u8 as Readable>::read(reader)? {
4387+
0 => ChannelUpdateStatus::Enabled,
4388+
1 => ChannelUpdateStatus::Disabled,
4389+
_ => return Err(DecodeError::InvalidValue),
4390+
})
4391+
}
4392+
}
4393+
43784394
impl<Signer: Sign> Writeable for Channel<Signer> {
43794395
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
43804396
// Note that we write out as if remove_uncommitted_htlcs_and_mark_paused had just been
@@ -4568,6 +4584,8 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
45684584
self.counterparty_shutdown_scriptpubkey.write(writer)?;
45694585

45704586
self.commitment_secrets.write(writer)?;
4587+
4588+
self.channel_update_status.write(writer)?;
45714589
Ok(())
45724590
}
45734591
}
@@ -4740,6 +4758,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
47404758
let counterparty_shutdown_scriptpubkey = Readable::read(reader)?;
47414759
let commitment_secrets = Readable::read(reader)?;
47424760

4761+
let channel_update_status = Readable::read(reader)?;
4762+
47434763
let mut secp_ctx = Secp256k1::new();
47444764
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
47454765

@@ -4814,7 +4834,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
48144834

48154835
commitment_secrets,
48164836

4817-
network_sync: UpdateStatus::Fresh,
4837+
channel_update_status,
48184838

48194839
#[cfg(any(test, feature = "fuzztarget"))]
48204840
next_local_commitment_tx_fee_info_cached: Mutex::new(None),

0 commit comments

Comments
 (0)