Skip to content

Commit 609f89d

Browse files
authored
Merge pull request #3588 from wpaulino/quiescence
Implement quiescence protocol
2 parents 6cf270d + 570ddae commit 609f89d

File tree

7 files changed

+1252
-128
lines changed

7 files changed

+1252
-128
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,9 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
978978
lock_fundings!(nodes);
979979

980980
let chan_a = nodes[0].list_usable_channels()[0].short_channel_id.unwrap();
981+
let chan_a_id = nodes[0].list_usable_channels()[0].channel_id;
981982
let chan_b = nodes[2].list_usable_channels()[0].short_channel_id.unwrap();
983+
let chan_b_id = nodes[2].list_usable_channels()[0].channel_id;
982984

983985
let mut p_id: u8 = 0;
984986
let mut p_idx: u64 = 0;
@@ -1039,6 +1041,10 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
10391041
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
10401042
*node_id == a_id
10411043
},
1044+
events::MessageSendEvent::SendStfu { ref node_id, .. } => {
1045+
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
1046+
*node_id == a_id
1047+
},
10421048
events::MessageSendEvent::SendChannelReady { .. } => continue,
10431049
events::MessageSendEvent::SendAnnouncementSignatures { .. } => continue,
10441050
events::MessageSendEvent::SendChannelUpdate { ref node_id, ref msg } => {
@@ -1101,7 +1107,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11011107
for (idx, dest) in nodes.iter().enumerate() {
11021108
if dest.get_our_node_id() == node_id {
11031109
for update_add in update_add_htlcs.iter() {
1104-
out.locked_write(format!("Delivering update_add_htlc to node {}.\n", idx).as_bytes());
1110+
out.locked_write(format!("Delivering update_add_htlc from node {} to node {}.\n", $node, idx).as_bytes());
11051111
if !$corrupt_forward {
11061112
dest.handle_update_add_htlc(nodes[$node].get_our_node_id(), update_add);
11071113
} else {
@@ -1116,19 +1122,19 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11161122
}
11171123
}
11181124
for update_fulfill in update_fulfill_htlcs.iter() {
1119-
out.locked_write(format!("Delivering update_fulfill_htlc to node {}.\n", idx).as_bytes());
1125+
out.locked_write(format!("Delivering update_fulfill_htlc from node {} to node {}.\n", $node, idx).as_bytes());
11201126
dest.handle_update_fulfill_htlc(nodes[$node].get_our_node_id(), update_fulfill);
11211127
}
11221128
for update_fail in update_fail_htlcs.iter() {
1123-
out.locked_write(format!("Delivering update_fail_htlc to node {}.\n", idx).as_bytes());
1129+
out.locked_write(format!("Delivering update_fail_htlc from node {} to node {}.\n", $node, idx).as_bytes());
11241130
dest.handle_update_fail_htlc(nodes[$node].get_our_node_id(), update_fail);
11251131
}
11261132
for update_fail_malformed in update_fail_malformed_htlcs.iter() {
1127-
out.locked_write(format!("Delivering update_fail_malformed_htlc to node {}.\n", idx).as_bytes());
1133+
out.locked_write(format!("Delivering update_fail_malformed_htlc from node {} to node {}.\n", $node, idx).as_bytes());
11281134
dest.handle_update_fail_malformed_htlc(nodes[$node].get_our_node_id(), update_fail_malformed);
11291135
}
11301136
if let Some(msg) = update_fee {
1131-
out.locked_write(format!("Delivering update_fee to node {}.\n", idx).as_bytes());
1137+
out.locked_write(format!("Delivering update_fee from node {} to node {}.\n", $node, idx).as_bytes());
11321138
dest.handle_update_fee(nodes[$node].get_our_node_id(), &msg);
11331139
}
11341140
let processed_change = !update_add_htlcs.is_empty() || !update_fulfill_htlcs.is_empty() ||
@@ -1145,7 +1151,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11451151
} });
11461152
break;
11471153
}
1148-
out.locked_write(format!("Delivering commitment_signed to node {}.\n", idx).as_bytes());
1154+
out.locked_write(format!("Delivering commitment_signed from node {} to node {}.\n", $node, idx).as_bytes());
11491155
dest.handle_commitment_signed(nodes[$node].get_our_node_id(), &commitment_signed);
11501156
break;
11511157
}
@@ -1154,19 +1160,27 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11541160
events::MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
11551161
for (idx, dest) in nodes.iter().enumerate() {
11561162
if dest.get_our_node_id() == *node_id {
1157-
out.locked_write(format!("Delivering revoke_and_ack to node {}.\n", idx).as_bytes());
1163+
out.locked_write(format!("Delivering revoke_and_ack from node {} to node {}.\n", $node, idx).as_bytes());
11581164
dest.handle_revoke_and_ack(nodes[$node].get_our_node_id(), msg);
11591165
}
11601166
}
11611167
},
11621168
events::MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => {
11631169
for (idx, dest) in nodes.iter().enumerate() {
11641170
if dest.get_our_node_id() == *node_id {
1165-
out.locked_write(format!("Delivering channel_reestablish to node {}.\n", idx).as_bytes());
1171+
out.locked_write(format!("Delivering channel_reestablish from node {} to node {}.\n", $node, idx).as_bytes());
11661172
dest.handle_channel_reestablish(nodes[$node].get_our_node_id(), msg);
11671173
}
11681174
}
11691175
},
1176+
events::MessageSendEvent::SendStfu { ref node_id, ref msg } => {
1177+
for (idx, dest) in nodes.iter().enumerate() {
1178+
if dest.get_our_node_id() == *node_id {
1179+
out.locked_write(format!("Delivering stfu from node {} to node {}.\n", $node, idx).as_bytes());
1180+
dest.handle_stfu(nodes[$node].get_our_node_id(), msg);
1181+
}
1182+
}
1183+
}
11701184
events::MessageSendEvent::SendChannelReady { .. } => {
11711185
// Can be generated as a reestablish response
11721186
},
@@ -1219,6 +1233,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12191233
events::MessageSendEvent::UpdateHTLCs { .. } => {},
12201234
events::MessageSendEvent::SendRevokeAndACK { .. } => {},
12211235
events::MessageSendEvent::SendChannelReestablish { .. } => {},
1236+
events::MessageSendEvent::SendStfu { .. } => {},
12221237
events::MessageSendEvent::SendChannelReady { .. } => {},
12231238
events::MessageSendEvent::SendAnnouncementSignatures { .. } => {},
12241239
events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => {
@@ -1245,6 +1260,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
12451260
events::MessageSendEvent::UpdateHTLCs { .. } => {},
12461261
events::MessageSendEvent::SendRevokeAndACK { .. } => {},
12471262
events::MessageSendEvent::SendChannelReestablish { .. } => {},
1263+
events::MessageSendEvent::SendStfu { .. } => {},
12481264
events::MessageSendEvent::SendChannelReady { .. } => {},
12491265
events::MessageSendEvent::SendAnnouncementSignatures { .. } => {},
12501266
events::MessageSendEvent::SendChannelUpdate { ref msg, .. } => {
@@ -1688,6 +1704,19 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
16881704
nodes[2].maybe_update_chan_fees();
16891705
},
16901706

1707+
0xa0 => {
1708+
nodes[0].maybe_propose_quiescence(&nodes[1].get_our_node_id(), &chan_a_id).unwrap()
1709+
},
1710+
0xa1 => {
1711+
nodes[1].maybe_propose_quiescence(&nodes[0].get_our_node_id(), &chan_a_id).unwrap()
1712+
},
1713+
0xa2 => {
1714+
nodes[1].maybe_propose_quiescence(&nodes[2].get_our_node_id(), &chan_b_id).unwrap()
1715+
},
1716+
0xa3 => {
1717+
nodes[2].maybe_propose_quiescence(&nodes[1].get_our_node_id(), &chan_b_id).unwrap()
1718+
},
1719+
16911720
0xf0 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_first),
16921721
0xf1 => complete_monitor_update(&monitor_a, &chan_1_id, &complete_second),
16931722
0xf2 => complete_monitor_update(&monitor_a, &chan_1_id, &Vec::pop),
@@ -1753,34 +1782,49 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
17531782
chan_b_disconnected = false;
17541783
}
17551784

1756-
for i in 0..std::usize::MAX {
1757-
if i == 100 {
1758-
panic!("It may take may iterations to settle the state, but it should not take forever");
1759-
}
1760-
// Then, make sure any current forwards make their way to their destination
1761-
if process_msg_events!(0, false, ProcessMessages::AllMessages) {
1762-
continue;
1763-
}
1764-
if process_msg_events!(1, false, ProcessMessages::AllMessages) {
1765-
continue;
1766-
}
1767-
if process_msg_events!(2, false, ProcessMessages::AllMessages) {
1768-
continue;
1769-
}
1770-
// ...making sure any pending PendingHTLCsForwardable events are handled and
1771-
// payments claimed.
1772-
if process_events!(0, false) {
1773-
continue;
1774-
}
1775-
if process_events!(1, false) {
1776-
continue;
1777-
}
1778-
if process_events!(2, false) {
1779-
continue;
1780-
}
1781-
break;
1785+
macro_rules! process_all_events {
1786+
() => {
1787+
for i in 0..std::usize::MAX {
1788+
if i == 100 {
1789+
panic!("It may take may iterations to settle the state, but it should not take forever");
1790+
}
1791+
// Then, make sure any current forwards make their way to their destination
1792+
if process_msg_events!(0, false, ProcessMessages::AllMessages) {
1793+
continue;
1794+
}
1795+
if process_msg_events!(1, false, ProcessMessages::AllMessages) {
1796+
continue;
1797+
}
1798+
if process_msg_events!(2, false, ProcessMessages::AllMessages) {
1799+
continue;
1800+
}
1801+
// ...making sure any pending PendingHTLCsForwardable events are handled and
1802+
// payments claimed.
1803+
if process_events!(0, false) {
1804+
continue;
1805+
}
1806+
if process_events!(1, false) {
1807+
continue;
1808+
}
1809+
if process_events!(2, false) {
1810+
continue;
1811+
}
1812+
break;
1813+
}
1814+
};
17821815
}
17831816

1817+
// At this point, we may be pending quiescence, so we'll process all messages to
1818+
// ensure we can complete its handshake. We'll then exit quiescence and process all
1819+
// messages again, to resolve any pending HTLCs (only irrevocably committed ones)
1820+
// before attempting to send more payments.
1821+
process_all_events!();
1822+
nodes[0].exit_quiescence(&nodes[1].get_our_node_id(), &chan_a_id).unwrap();
1823+
nodes[1].exit_quiescence(&nodes[0].get_our_node_id(), &chan_a_id).unwrap();
1824+
nodes[1].exit_quiescence(&nodes[2].get_our_node_id(), &chan_b_id).unwrap();
1825+
nodes[2].exit_quiescence(&nodes[1].get_our_node_id(), &chan_b_id).unwrap();
1826+
process_all_events!();
1827+
17841828
// Finally, make sure that at least one end of each channel can make a substantial payment
17851829
assert!(
17861830
send_payment(&nodes[0], &nodes[1], chan_a, 10_000_000, &mut p_id, &mut p_idx)

lightning-types/src/features.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
//! (see [bLIP 32](https://github.com/lightning/blips/blob/master/blip-0032.md) for more information).
7575
//! - `ProvideStorage` - Indicates that we offer the capability to store data of our peers
7676
//! (see https://github.com/lightning/bolts/pull/1110 for more info).
77+
//! - `Quiescence` - protocol to quiesce a channel by indicating that "SomeThing Fundamental is Underway"
78+
//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#channel-quiescence) for more information).
7779
//!
7880
//! LDK knows about the following features, but does not support them:
7981
//! - `AnchorsNonzeroFeeHtlcTx` - the initial version of anchor outputs, which was later found to be
@@ -152,7 +154,7 @@ mod sealed {
152154
// Byte 3
153155
RouteBlinding | ShutdownAnySegwit | DualFund | Taproot,
154156
// Byte 4
155-
OnionMessages,
157+
Quiescence | OnionMessages,
156158
// Byte 5
157159
ProvideStorage | ChannelType | SCIDPrivacy,
158160
// Byte 6
@@ -173,7 +175,7 @@ mod sealed {
173175
// Byte 3
174176
RouteBlinding | ShutdownAnySegwit | DualFund | Taproot,
175177
// Byte 4
176-
OnionMessages,
178+
Quiescence | OnionMessages,
177179
// Byte 5
178180
ProvideStorage | ChannelType | SCIDPrivacy,
179181
// Byte 6
@@ -536,6 +538,16 @@ mod sealed {
536538
supports_taproot,
537539
requires_taproot
538540
);
541+
define_feature!(
542+
35,
543+
Quiescence,
544+
[InitContext, NodeContext],
545+
"Feature flags for `option_quiesce`.",
546+
set_quiescence_optional,
547+
set_quiescence_required,
548+
supports_quiescence,
549+
requires_quiescence
550+
);
539551
define_feature!(
540552
39,
541553
OnionMessages,
@@ -1195,6 +1207,7 @@ mod tests {
11951207
init_features.set_channel_type_optional();
11961208
init_features.set_scid_privacy_optional();
11971209
init_features.set_zero_conf_optional();
1210+
init_features.set_quiescence_optional();
11981211

11991212
assert!(init_features.initial_routing_sync());
12001213
assert!(!init_features.supports_upfront_shutdown_script());
@@ -1215,7 +1228,7 @@ mod tests {
12151228
assert_eq!(node_features.flags[1], 0b01010001);
12161229
assert_eq!(node_features.flags[2], 0b10001010);
12171230
assert_eq!(node_features.flags[3], 0b00001010);
1218-
assert_eq!(node_features.flags[4], 0b10000000);
1231+
assert_eq!(node_features.flags[4], 0b10001000);
12191232
assert_eq!(node_features.flags[5], 0b10100000);
12201233
assert_eq!(node_features.flags[6], 0b00001000);
12211234
}

0 commit comments

Comments
 (0)