Skip to content

Commit ba9f4d4

Browse files
committed
Batch funding for v1 channel establishments
1 parent d4ad826 commit ba9f4d4

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
@@ -168,6 +168,9 @@ pub enum ClosureReason {
168168
/// The counterparty requested a cooperative close of a channel that had not been funded yet.
169169
/// The channel has been immediately closed.
170170
CounterpartyCoopClosedUnfundedChannel,
171+
/// Another channel in the same funding batch closed before the funding transaction
172+
/// was ready to be broadcast.
173+
FundingBatchClosure,
171174
}
172175

173176
impl core::fmt::Display for ClosureReason {
@@ -188,6 +191,7 @@ impl core::fmt::Display for ClosureReason {
188191
ClosureReason::DisconnectedPeer => f.write_str("the peer disconnected prior to the channel being funded"),
189192
ClosureReason::OutdatedChannelManager => f.write_str("the ChannelManager read from disk was stale compared to ChannelMonitor(s)"),
190193
ClosureReason::CounterpartyCoopClosedUnfundedChannel => f.write_str("the peer requested the unfunded channel be closed"),
194+
ClosureReason::FundingBatchClosure => f.write_str("another channel in the same funding batch closed"),
191195
}
192196
}
193197
}
@@ -202,6 +206,7 @@ impl_writeable_tlv_based_enum_upgradable!(ClosureReason,
202206
(10, DisconnectedPeer) => {},
203207
(12, OutdatedChannelManager) => {},
204208
(13, CounterpartyCoopClosedUnfundedChannel) => {},
209+
(15, FundingBatchClosure) => {}
205210
);
206211

207212
/// 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
@@ -299,6 +299,10 @@ enum ChannelState {
299299
/// We've successfully negotiated a closing_signed dance. At this point ChannelManager is about
300300
/// to drop us, but we store this anyway.
301301
ShutdownComplete = 4096,
302+
/// Flag which is set on `FundingSent` to indicate this channel is funded in a batch and the
303+
/// broadcasting of the funding transaction is being held until all channels in the batch
304+
/// have received funding_signed and have their monitors persisted.
305+
WaitingForBatch = 1 << 13,
302306
}
303307
const BOTH_SIDES_SHUTDOWN_MASK: u32 = ChannelState::LocalShutdownSent as u32 | ChannelState::RemoteShutdownSent as u32;
304308
const MULTI_STATE_FLAGS: u32 = BOTH_SIDES_SHUTDOWN_MASK | ChannelState::PeerDisconnected as u32 | ChannelState::MonitorUpdateInProgress as u32;
@@ -1184,9 +1188,11 @@ impl<Signer: ChannelSigner> ChannelContext<Signer> {
11841188
did_channel_update
11851189
}
11861190

1187-
/// Returns true if funding_created was sent/received.
1191+
/// Returns true if funding_signed was sent/received and the
1192+
/// funding transaction has been broadcast if necessary.
11881193
pub fn is_funding_initiated(&self) -> bool {
1189-
self.channel_state >= ChannelState::FundingSent as u32
1194+
self.channel_state >= ChannelState::FundingSent as u32 &&
1195+
self.channel_state & ChannelState::WaitingForBatch as u32 == 0
11901196
}
11911197

11921198
/// Transaction nomenclature is somewhat confusing here as there are many different cases - a
@@ -1917,7 +1923,8 @@ impl<Signer: ChannelSigner> ChannelContext<Signer> {
19171923

19181924
/// Returns transaction if there is pending funding transaction that is yet to broadcast
19191925
pub fn unbroadcasted_funding(&self) -> Option<Transaction> {
1920-
if self.channel_state & (ChannelState::FundingCreated as u32) != 0 {
1926+
if self.channel_state & ChannelState::FundingCreated as u32 != 0 ||
1927+
self.channel_state & ChannelState::WaitingForBatch as u32 != 0 {
19211928
self.funding_transaction.clone()
19221929
} else {
19231930
None
@@ -2464,7 +2471,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
24642471
/// Handles a funding_signed message from the remote end.
24652472
/// If this call is successful, broadcast the funding transaction (and not before!)
24662473
pub fn funding_signed<SP: Deref, L: Deref>(
2467-
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
2474+
&mut self, msg: &msgs::FundingSigned, best_block: BestBlock, signer_provider: &SP, is_batch_funding: bool, logger: &L
24682475
) -> Result<ChannelMonitor<Signer>, ChannelError>
24692476
where
24702477
SP::Target: SignerProvider<Signer = Signer>,
@@ -2534,7 +2541,11 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
25342541
channel_monitor.provide_latest_counterparty_commitment_tx(counterparty_initial_bitcoin_tx.txid, Vec::new(), self.context.cur_counterparty_commitment_transaction_number, self.context.counterparty_cur_commitment_point.unwrap(), logger);
25352542

25362543
assert_eq!(self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32), 0); // We have no had any monitor(s) yet to fail update!
2537-
self.context.channel_state = ChannelState::FundingSent as u32;
2544+
if is_batch_funding {
2545+
self.context.channel_state = ChannelState::FundingSent as u32 | ChannelState::WaitingForBatch as u32;
2546+
} else {
2547+
self.context.channel_state = ChannelState::FundingSent as u32;
2548+
}
25382549
self.context.cur_holder_commitment_transaction_number -= 1;
25392550
self.context.cur_counterparty_commitment_transaction_number -= 1;
25402551

@@ -2545,6 +2556,13 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
25452556
Ok(channel_monitor)
25462557
}
25472558

2559+
/// Updates the state of the channel to indicate that all channels in the batch
2560+
/// have received funding_signed and persisted their monitors.
2561+
/// The funding transaction is consequently allowed to be broadcast.
2562+
pub fn set_batch_ready(&mut self) {
2563+
self.context.channel_state &= !(ChannelState::WaitingForBatch as u32);
2564+
}
2565+
25482566
/// Handles a channel_ready message from our peer. If we've already sent our channel_ready
25492567
/// and the channel is now usable (and public), this may generate an announcement_signatures to
25502568
/// reply with.
@@ -3634,7 +3652,7 @@ impl<Signer: WriteableEcdsaChannelSigner> Channel<Signer> {
36343652
// (re-)broadcast the funding transaction as we may have declined to broadcast it when we
36353653
// first received the funding_signed.
36363654
let mut funding_broadcastable =
3637-
if self.context.is_outbound() && self.context.channel_state & !MULTI_STATE_FLAGS >= ChannelState::FundingSent as u32 {
3655+
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 {
36383656
self.context.funding_transaction.take()
36393657
} else { None };
36403658
// That said, if the funding transaction is already confirmed (ie we're active with a
@@ -7601,7 +7619,7 @@ mod tests {
76017619
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
76027620

76037621
// Node B --> Node A: funding signed
7604-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7622+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
76057623

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

77307748
// Node B --> Node A: funding signed
7731-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7749+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
77327750

77337751
// Now disconnect the two nodes and check that the commitment point in
77347752
// Node B's channel_reestablish message is sane.
@@ -7916,7 +7934,7 @@ mod tests {
79167934
let (_, funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&keys_provider, &&logger).map_err(|_| ()).unwrap();
79177935

79187936
// Node B --> Node A: funding signed
7919-
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, &&logger).unwrap();
7937+
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&keys_provider, false, &&logger).unwrap();
79207938

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

0 commit comments

Comments
 (0)