Skip to content

Commit 4607d21

Browse files
committed
Enforce compile-time check for flag getters and setters
This ensures that we cannot define or use flag getters/setters on `ChannelState` variants in which said flag is not valid.
1 parent 4c41d95 commit 4607d21

File tree

1 file changed

+63
-36
lines changed

1 file changed

+63
-36
lines changed

lightning/src/ln/channel.rs

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ enum HTLCUpdateAwaitingACK {
262262
}
263263

264264
macro_rules! define_state_flags {
265-
($flag_type_doc: expr, $flag_type: ident, [$(($flag_doc: expr, $flag: ident, $value: expr)),+], $extra_flags: expr) => {
265+
($flag_type_doc: expr, $flag_type: ident, [$(($flag_doc: expr, $flag: ident, $value: expr, $get: ident, $set: ident, $clear: ident)),+], $extra_flags: expr) => {
266266
#[doc = $flag_type_doc]
267267
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq)]
268268
struct $flag_type(u32);
@@ -291,11 +291,18 @@ macro_rules! define_state_flags {
291291

292292
#[allow(unused)]
293293
fn is_empty(&self) -> bool { self.0 == 0 }
294-
295294
#[allow(unused)]
296295
fn is_set(&self, flag: Self) -> bool { *self & flag == flag }
296+
#[allow(unused)]
297+
fn set(&mut self, flag: Self) { *self |= flag }
298+
#[allow(unused)]
299+
fn clear(&mut self, flag: Self) { *self &= !flag }
297300
}
298301

302+
$(
303+
define_state_flags!($flag_type, Self::$flag, $get, $set, $clear);
304+
)*
305+
299306
impl core::ops::Not for $flag_type {
300307
type Output = Self;
301308
fn not(self) -> Self::Output { Self(!self.0) }
@@ -318,8 +325,28 @@ macro_rules! define_state_flags {
318325
($flag_type_doc: expr, $flag_type: ident, $flags: tt) => {
319326
define_state_flags!($flag_type_doc, $flag_type, $flags, 0);
320327
};
328+
($flag_type: ident, $flag: expr, $get: ident, $set: ident, $clear: ident) => {
329+
impl $flag_type {
330+
#[allow(unused)]
331+
fn $get(&self) -> bool { self.is_set($flag_type::new() | $flag) }
332+
#[allow(unused)]
333+
fn $set(&mut self) { self.set($flag_type::new() | $flag) }
334+
#[allow(unused)]
335+
fn $clear(&mut self) { self.clear($flag_type::new() | $flag) }
336+
}
337+
};
321338
($flag_type_doc: expr, FUNDED_STATE, $flag_type: ident, $flags: tt) => {
322339
define_state_flags!($flag_type_doc, $flag_type, $flags, FundedStateFlags::ALL.0);
340+
341+
define_state_flags!($flag_type, FundedStateFlags::PEER_DISCONNECTED,
342+
is_peer_disconnected, set_peer_disconnected, clear_peer_disconnected);
343+
define_state_flags!($flag_type, FundedStateFlags::MONITOR_UPDATE_IN_PROGRESS,
344+
is_monitor_update_in_progress, set_monitor_update_in_progress, clear_monitor_update_in_progress);
345+
define_state_flags!($flag_type, FundedStateFlags::REMOTE_SHUTDOWN_SENT,
346+
is_remote_shutdown_sent, set_remote_shutdown_sent, clear_remote_shutdown_sent);
347+
define_state_flags!($flag_type, FundedStateFlags::LOCAL_SHUTDOWN_SENT,
348+
is_local_shutdown_sent, set_local_shutdown_sent, clear_local_shutdown_sent);
349+
323350
impl core::ops::BitOr<FundedStateFlags> for $flag_type {
324351
type Output = Self;
325352
fn bitor(self, rhs: FundedStateFlags) -> Self::Output { Self(self.0 | rhs.0) }
@@ -366,25 +393,29 @@ define_state_flags!(
366393
"Flags that apply to all [`ChannelState`] variants in which the channel is funded.",
367394
FundedStateFlags, [
368395
("Indicates the remote side is considered \"disconnected\" and no updates are allowed \
369-
until after we've done a `channel_reestablish` dance.", PEER_DISCONNECTED, state_flags::PEER_DISCONNECTED),
396+
until after we've done a `channel_reestablish` dance.", PEER_DISCONNECTED, state_flags::PEER_DISCONNECTED,
397+
is_peer_disconnected, set_peer_disconnected, clear_peer_disconnected),
370398
("Indicates the user has told us a `ChannelMonitor` update is pending async persistence \
371399
somewhere and we should pause sending any outbound messages until they've managed to \
372-
complete it.", MONITOR_UPDATE_IN_PROGRESS, state_flags::MONITOR_UPDATE_IN_PROGRESS),
400+
complete it.", MONITOR_UPDATE_IN_PROGRESS, state_flags::MONITOR_UPDATE_IN_PROGRESS,
401+
is_monitor_update_in_progress, set_monitor_update_in_progress, clear_monitor_update_in_progress),
373402
("Indicates we received a `shutdown` message from the remote end. If set, they may not add \
374403
any new HTLCs to the channel, and we are expected to respond with our own `shutdown` \
375-
message when possible.", REMOTE_SHUTDOWN_SENT, state_flags::REMOTE_SHUTDOWN_SENT),
404+
message when possible.", REMOTE_SHUTDOWN_SENT, state_flags::REMOTE_SHUTDOWN_SENT,
405+
is_remote_shutdown_sent, set_remote_shutdown_sent, clear_remote_shutdown_sent),
376406
("Indicates we sent a `shutdown` message. At this point, we may not add any new HTLCs to \
377-
the channel.", LOCAL_SHUTDOWN_SENT, state_flags::LOCAL_SHUTDOWN_SENT)
407+
the channel.", LOCAL_SHUTDOWN_SENT, state_flags::LOCAL_SHUTDOWN_SENT,
408+
is_local_shutdown_sent, set_local_shutdown_sent, clear_local_shutdown_sent)
378409
]
379410
);
380411

381412
define_state_flags!(
382413
"Flags that only apply to [`ChannelState::NegotiatingFunding`].",
383414
NegotiatingFundingFlags, [
384415
("Indicates we have (or are prepared to) send our `open_channel`/`accept_channel` message.",
385-
OUR_INIT_SENT, state_flags::OUR_INIT_SENT),
416+
OUR_INIT_SENT, state_flags::OUR_INIT_SENT, is_our_init_sent, set_our_init_sent, clear_our_init_sent),
386417
("Indicates we have received their `open_channel`/`accept_channel` message.",
387-
THEIR_INIT_SENT, state_flags::THEIR_INIT_SENT)
418+
THEIR_INIT_SENT, state_flags::THEIR_INIT_SENT, is_their_init_sent, set_their_init_sent, clear_their_init_sent)
388419
]
389420
);
390421

@@ -393,13 +424,16 @@ define_state_flags!(
393424
FUNDED_STATE, AwaitingChannelReadyFlags, [
394425
("Indicates they sent us a `channel_ready` message. Once both `THEIR_CHANNEL_READY` and \
395426
`OUR_CHANNEL_READY` are set, our state moves on to `ChannelReady`.",
396-
THEIR_CHANNEL_READY, state_flags::THEIR_CHANNEL_READY),
427+
THEIR_CHANNEL_READY, state_flags::THEIR_CHANNEL_READY,
428+
is_their_channel_ready, set_their_channel_ready, clear_their_channel_ready),
397429
("Indicates we sent them a `channel_ready` message. Once both `THEIR_CHANNEL_READY` and \
398430
`OUR_CHANNEL_READY` are set, our state moves on to `ChannelReady`.",
399-
OUR_CHANNEL_READY, state_flags::OUR_CHANNEL_READY),
431+
OUR_CHANNEL_READY, state_flags::OUR_CHANNEL_READY,
432+
is_our_channel_ready, set_our_channel_ready, clear_our_channel_ready),
400433
("Indicates the channel was funded in a batch and the broadcast of the funding transaction \
401434
is being held until all channels in the batch have received `funding_signed` and have \
402-
their monitors persisted.", WAITING_FOR_BATCH, state_flags::WAITING_FOR_BATCH)
435+
their monitors persisted.", WAITING_FOR_BATCH, state_flags::WAITING_FOR_BATCH,
436+
is_waiting_for_batch, set_waiting_for_batch, clear_waiting_for_batch)
403437
]
404438
);
405439

@@ -410,7 +444,8 @@ define_state_flags!(
410444
`revoke_and_ack` message. During this period, we can't generate new `commitment_signed` \
411445
messages as we'd be unable to determine which HTLCs they included in their `revoke_and_ack` \
412446
implicit ACK, so instead we have to hold them away temporarily to be sent later.",
413-
AWAITING_REMOTE_REVOKE, state_flags::AWAITING_REMOTE_REVOKE)
447+
AWAITING_REMOTE_REVOKE, state_flags::AWAITING_REMOTE_REVOKE,
448+
is_awaiting_remote_revoke, set_awaiting_remote_revoke, clear_awaiting_remote_revoke)
414449
]
415450
);
416451

@@ -476,12 +511,12 @@ impl PartialOrd for ChannelState {
476511
}
477512

478513
macro_rules! impl_state_flag {
479-
($get: ident, $set: ident, $clear: ident, $state_flag: expr, [$($state: ident),+]) => {
514+
($get: ident, $set: ident, $clear: ident, [$($state: ident),+]) => {
480515
#[allow(unused)]
481516
fn $get(&self) -> bool {
482517
match self {
483518
$(
484-
ChannelState::$state(flags) => flags.is_set($state_flag.into()),
519+
ChannelState::$state(flags) => flags.$get(),
485520
)*
486521
_ => false,
487522
}
@@ -490,7 +525,7 @@ macro_rules! impl_state_flag {
490525
fn $set(&mut self) {
491526
match self {
492527
$(
493-
ChannelState::$state(flags) => *flags |= $state_flag,
528+
ChannelState::$state(flags) => flags.$set(),
494529
)*
495530
_ => debug_assert!(false, "Attempted to set flag on unexpected ChannelState"),
496531
}
@@ -499,17 +534,17 @@ macro_rules! impl_state_flag {
499534
fn $clear(&mut self) {
500535
match self {
501536
$(
502-
ChannelState::$state(flags) => *flags &= !($state_flag),
537+
ChannelState::$state(flags) => flags.$clear(),
503538
)*
504539
_ => debug_assert!(false, "Attempted to clear flag on unexpected ChannelState"),
505540
}
506541
}
507542
};
508-
($get: ident, $set: ident, $clear: ident, $state_flag: expr, FUNDED_STATES) => {
509-
impl_state_flag!($get, $set, $clear, $state_flag, [AwaitingChannelReady, ChannelReady]);
543+
($get: ident, $set: ident, $clear: ident, FUNDED_STATES) => {
544+
impl_state_flag!($get, $set, $clear, [AwaitingChannelReady, ChannelReady]);
510545
};
511-
($get: ident, $set: ident, $clear: ident, $state_flag: expr, $state: ident) => {
512-
impl_state_flag!($get, $set, $clear, $state_flag, [$state]);
546+
($get: ident, $set: ident, $clear: ident, $state: ident) => {
547+
impl_state_flag!($get, $set, $clear, [$state]);
513548
};
514549
}
515550

@@ -573,22 +608,14 @@ impl ChannelState {
573608
}
574609
}
575610

576-
impl_state_flag!(is_peer_disconnected, set_peer_disconnected, clear_peer_disconnected,
577-
FundedStateFlags::PEER_DISCONNECTED, FUNDED_STATES);
578-
impl_state_flag!(is_monitor_update_in_progress, set_monitor_update_in_progress, clear_monitor_update_in_progress,
579-
FundedStateFlags::MONITOR_UPDATE_IN_PROGRESS, FUNDED_STATES);
580-
impl_state_flag!(is_local_shutdown_sent, set_local_shutdown_sent, clear_local_shutdown_sent,
581-
FundedStateFlags::LOCAL_SHUTDOWN_SENT, FUNDED_STATES);
582-
impl_state_flag!(is_remote_shutdown_sent, set_remote_shutdown_sent, clear_remote_shutdown_sent,
583-
FundedStateFlags::REMOTE_SHUTDOWN_SENT, FUNDED_STATES);
584-
impl_state_flag!(is_our_channel_ready, set_our_channel_ready, clear_our_channel_ready,
585-
AwaitingChannelReadyFlags::OUR_CHANNEL_READY, AwaitingChannelReady);
586-
impl_state_flag!(is_their_channel_ready, set_their_channel_ready, clear_their_channel_ready,
587-
AwaitingChannelReadyFlags::THEIR_CHANNEL_READY, AwaitingChannelReady);
588-
impl_state_flag!(is_waiting_for_batch, set_waiting_for_batch, clear_waiting_for_batch,
589-
AwaitingChannelReadyFlags::WAITING_FOR_BATCH, AwaitingChannelReady);
590-
impl_state_flag!(is_awaiting_remote_revoke, set_awaiting_remote_revoke, clear_awaiting_remote_revoke,
591-
ChannelReadyFlags::AWAITING_REMOTE_REVOKE, ChannelReady);
611+
impl_state_flag!(is_peer_disconnected, set_peer_disconnected, clear_peer_disconnected, FUNDED_STATES);
612+
impl_state_flag!(is_monitor_update_in_progress, set_monitor_update_in_progress, clear_monitor_update_in_progress, FUNDED_STATES);
613+
impl_state_flag!(is_local_shutdown_sent, set_local_shutdown_sent, clear_local_shutdown_sent, FUNDED_STATES);
614+
impl_state_flag!(is_remote_shutdown_sent, set_remote_shutdown_sent, clear_remote_shutdown_sent, FUNDED_STATES);
615+
impl_state_flag!(is_our_channel_ready, set_our_channel_ready, clear_our_channel_ready, AwaitingChannelReady);
616+
impl_state_flag!(is_their_channel_ready, set_their_channel_ready, clear_their_channel_ready, AwaitingChannelReady);
617+
impl_state_flag!(is_waiting_for_batch, set_waiting_for_batch, clear_waiting_for_batch, AwaitingChannelReady);
618+
impl_state_flag!(is_awaiting_remote_revoke, set_awaiting_remote_revoke, clear_awaiting_remote_revoke, ChannelReady);
592619
}
593620

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

0 commit comments

Comments
 (0)