Skip to content

Commit edb1ccf

Browse files
committed
Batch funding for v1 channel establishments
1 parent bbe20c3 commit edb1ccf

File tree

4 files changed

+380
-38
lines changed

4 files changed

+380
-38
lines changed

lightning/src/events/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ pub enum ClosureReason {
199199
/// The counterparty requested a cooperative close of a channel that had not been funded yet.
200200
/// The channel has been immediately closed.
201201
CounterpartyCoopClosedUnfundedChannel,
202+
/// Another channel in the same funding batch closed before the funding transaction
203+
/// was ready to be broadcast.
204+
FundingBatchClosure,
202205
}
203206

204207
impl core::fmt::Display for ClosureReason {
@@ -219,6 +222,7 @@ impl core::fmt::Display for ClosureReason {
219222
ClosureReason::DisconnectedPeer => f.write_str("the peer disconnected prior to the channel being funded"),
220223
ClosureReason::OutdatedChannelManager => f.write_str("the ChannelManager read from disk was stale compared to ChannelMonitor(s)"),
221224
ClosureReason::CounterpartyCoopClosedUnfundedChannel => f.write_str("the peer requested the unfunded channel be closed"),
225+
ClosureReason::FundingBatchClosure => f.write_str("another channel in the same funding batch closed"),
222226
}
223227
}
224228
}
@@ -233,6 +237,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
233237
(10, DisconnectedPeer) => {},
234238
(12, OutdatedChannelManager) => {},
235239
(13, CounterpartyCoopClosedUnfundedChannel) => {},
240+
(15, FundingBatchClosure) => {}
236241
);
237242

238243
/// Intended destination of a failed HTLC as indicated in [`Event::HTLCHandlingFailed`].

lightning/src/ln/channel.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ enum ChannelState {
300300
/// We've successfully negotiated a closing_signed dance. At this point ChannelManager is about
301301
/// to drop us, but we store this anyway.
302302
ShutdownComplete = 4096,
303+
/// Flag which is set on `FundingSent` to indicate this channel is funded in a batch and the
304+
/// broadcasting of the funding transaction is being held until all channels in the batch
305+
/// have received funding_signed and have their monitors persisted.
306+
WaitingForBatch = 1 << 13,
303307
}
304308
const BOTH_SIDES_SHUTDOWN_MASK: u32 = ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32;
305309
const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32;
@@ -1185,9 +1189,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
11851189
did_channel_update
11861190
}
11871191

1188-
/// Returns true if funding_created was sent/received.
1192+
/// Returns true if funding_signed was sent/received and the
1193+
/// funding transaction has been broadcast if necessary.
11891194
pub fn is_funding_initiated(&self) -> bool {
1190-
self.channel_state >= ChannelState::FundingSent as u32
1195+
self.channel_state >= ChannelState::FundingSent as u32 &&
1196+
self.channel_state & ChannelState::WaitingForBatch as u32 == 0
11911197
}
11921198

11931199
/// Transaction nomenclature is somewhat confusing here as there are many different cases - a
@@ -1918,7 +1924,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
19181924

19191925
/// Returns transaction if there is pending funding transaction that is yet to broadcast
19201926
pub fn unbroadcasted_funding(&self) -> Option<Transaction> {
1921-
if self.channel_state & (ChannelState::FundingCreated as u32) != 0 {
1927+
if self.channel_state & ChannelState::FundingCreated as u32 != 0 ||
1928+
self.channel_state & ChannelState::WaitingForBatch as u32 != 0 {
19221929
self.funding_transaction.clone()
19231930
} else {
19241931
None
@@ -2468,7 +2475,7 @@ impl<SP: Deref> Channel<SP> where
24682475
/// Handles a funding_signed message from the remote end.
24692476
/// If this call is successful, broadcast the funding transaction (and not before!)
24702477
pub fn funding_signed<L: Deref>(
2471-
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
2478+
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, is_batch_funding: bool, logger: &L
24722479
) -> Result<ChannelMonitor<<SP::Target as SignerProvider>::Signer>, ChannelError>
24732480
where
24742481
L::Target: Logger
@@ -2543,7 +2550,11 @@ impl<SP: Deref> Channel<SP> where
25432550
counterparty_initial_commitment_tx.to_countersignatory_value_sat(), logger);
25442551

25452552
assert_eq!(self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32), 0); // We have no had any monitor(s) yet to fail update!
2546-
self.context.channel_state = ChannelState::FundingSent as u32;
2553+
if is_batch_funding {
2554+
self.context.channel_state = ChannelState::FundingSent as u32 | ChannelState::WaitingForBatch as u32;
2555+
} else {
2556+
self.context.channel_state = ChannelState::FundingSent as u32;
2557+
}
25472558
self.context.cur_holder_commitment_transaction_number -= 1;
25482559
self.context.cur_counterparty_commitment_transaction_number -= 1;
25492560

@@ -2554,6 +2565,13 @@ impl<SP: Deref> Channel<SP> where
25542565
Ok(channel_monitor)
25552566
}
25562567

2568+
/// Updates the state of the channel to indicate that all channels in the batch
2569+
/// have received funding_signed and persisted their monitors.
2570+
/// The funding transaction is consequently allowed to be broadcast.
2571+
pub fn set_batch_ready(&mut self) {
2572+
self.context.channel_state &= !(ChannelState::WaitingForBatch as u32);
2573+
}
2574+
25572575
/// Handles a channel_ready message from our peer. If we've already sent our channel_ready
25582576
/// and the channel is now usable (and public), this may generate an announcement_signatures to
25592577
/// reply with.
@@ -3671,7 +3689,7 @@ impl<SP: Deref> Channel<SP> where
36713689
// (re-)broadcast the funding transaction as we may have declined to broadcast it when we
36723690
// first received the funding_signed.
36733691
let mut funding_broadcastable =
3674-
if self.context.is_outbound() && self.context.channel_state & !MULTI_STATE_FLAGS >= ChannelState::FundingSent as u32 {
3692+
if self.context.is_outbound() && self.context.channel_state & !MULTI_STATE_FLAGS >= ChannelState::FundingSent as u32 && self.context.channel_state & ChannelState::WaitingForBatch as u32 == 0 {
36753693
self.context.funding_transaction.take()
36763694
} else { None };
36773695
// That said, if the funding transaction is already confirmed (ie we're active with a
@@ -7684,7 +7702,7 @@ mod tests {
76847702
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
76857703

76867704
// Node B --> Node A: funding signed
7687-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7705+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
76887706

76897707
// Put some inbound and outbound HTLCs in A's channel.
76907708
let htlc_amount_msat = 11_092_000; // put an amount below A's effective dust limit but above B's.
@@ -7811,7 +7829,7 @@ mod tests {
78117829
let (mut node_b_chan, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
78127830

78137831
// Node B --> Node A: funding signed
7814-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7832+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
78157833

78167834
// Now disconnect the two nodes and check that the commitment point in
78177835
// Node B's channel_reestablish message is sane.
@@ -7999,7 +8017,7 @@ mod tests {
79998017
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
80008018

80018019
// Node B --> Node A: funding signed
8002-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
8020+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
80038021

80048022
// Make sure that receiving a channel update will update the Channel as expected.
80058023
let update = ChannelUpdate {

0 commit comments

Comments
 (0)