Skip to content

Commit 0df247d

Browse files
authored
Merge pull request #1281 from ViktorTigerstrom/2022-01-accept-or-reject-channels
Add option accept or reject channel requests
2 parents f138d78 + 1891b37 commit 0df247d

File tree

5 files changed

+356
-10
lines changed

5 files changed

+356
-10
lines changed

lightning/src/ln/channel.rs

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,19 @@ pub(super) struct Channel<Signer: Sign> {
584584
#[cfg(not(test))]
585585
closing_fee_limits: Option<(u64, u64)>,
586586

587+
/// Flag that ensures that `accept_inbound_channel` must be called before `funding_created`
588+
/// is executed successfully. The reason for this flag is that when the
589+
/// `UserConfig::manually_accept_inbound_channels` config flag is set to true, inbound channels
590+
/// are required to be manually accepted by the node operator before the `msgs::AcceptChannel`
591+
/// message is created and sent out. During the manual accept process, `accept_inbound_channel`
592+
/// is called by `ChannelManager::accept_inbound_channel`.
593+
///
594+
/// The flag counteracts that a counterparty node could theoretically send a
595+
/// `msgs::FundingCreated` message before the node operator has manually accepted an inbound
596+
/// channel request made by the counterparty node. That would execute `funding_created` before
597+
/// `accept_inbound_channel`, and `funding_created` should therefore not execute successfully.
598+
inbound_awaiting_accept: bool,
599+
587600
/// The hash of the block in which the funding transaction was included.
588601
funding_tx_confirmed_in: Option<BlockHash>,
589602
funding_tx_confirmation_height: u32,
@@ -883,6 +896,8 @@ impl<Signer: Sign> Channel<Signer> {
883896
closing_fee_limits: None,
884897
target_closing_feerate_sats_per_kw: None,
885898

899+
inbound_awaiting_accept: false,
900+
886901
funding_tx_confirmed_in: None,
887902
funding_tx_confirmation_height: 0,
888903
short_channel_id: None,
@@ -1182,6 +1197,8 @@ impl<Signer: Sign> Channel<Signer> {
11821197
closing_fee_limits: None,
11831198
target_closing_feerate_sats_per_kw: None,
11841199

1200+
inbound_awaiting_accept: true,
1201+
11851202
funding_tx_confirmed_in: None,
11861203
funding_tx_confirmation_height: 0,
11871204
short_channel_id: None,
@@ -1973,6 +1990,9 @@ impl<Signer: Sign> Channel<Signer> {
19731990
// channel.
19741991
return Err(ChannelError::Close("Received funding_created after we got the channel!".to_owned()));
19751992
}
1993+
if self.inbound_awaiting_accept {
1994+
return Err(ChannelError::Close("FundingCreated message received before the channel was accepted".to_owned()));
1995+
}
19761996
if self.commitment_secrets.get_min_seen_secret() != (1 << 48) ||
19771997
self.cur_counterparty_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER ||
19781998
self.cur_holder_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
@@ -4645,7 +4665,15 @@ impl<Signer: Sign> Channel<Signer> {
46454665
}
46464666
}
46474667

4648-
pub fn get_accept_channel(&self) -> msgs::AcceptChannel {
4668+
pub fn inbound_is_awaiting_accept(&self) -> bool {
4669+
self.inbound_awaiting_accept
4670+
}
4671+
4672+
/// Marks an inbound channel as accepted and generates a [`msgs::AcceptChannel`] message which
4673+
/// should be sent back to the counterparty node.
4674+
///
4675+
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
4676+
pub fn accept_inbound_channel(&mut self) -> msgs::AcceptChannel {
46494677
if self.is_outbound() {
46504678
panic!("Tried to send accept_channel for an outbound channel?");
46514679
}
@@ -4655,7 +4683,21 @@ impl<Signer: Sign> Channel<Signer> {
46554683
if self.cur_holder_commitment_transaction_number != INITIAL_COMMITMENT_NUMBER {
46564684
panic!("Tried to send an accept_channel for a channel that has already advanced");
46574685
}
4686+
if !self.inbound_awaiting_accept {
4687+
panic!("The inbound channel has already been accepted");
4688+
}
4689+
4690+
self.inbound_awaiting_accept = false;
46584691

4692+
self.generate_accept_channel_message()
4693+
}
4694+
4695+
/// This function is used to explicitly generate a [`msgs::AcceptChannel`] message for an
4696+
/// inbound channel. If the intention is to accept an inbound channel, use
4697+
/// [`Channel::accept_inbound_channel`] instead.
4698+
///
4699+
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
4700+
fn generate_accept_channel_message(&self) -> msgs::AcceptChannel {
46594701
let first_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
46604702
let keys = self.get_holder_pubkeys();
46614703

@@ -4681,6 +4723,15 @@ impl<Signer: Sign> Channel<Signer> {
46814723
}
46824724
}
46834725

4726+
/// Enables the possibility for tests to extract a [`msgs::AcceptChannel`] message for an
4727+
/// inbound channel without accepting it.
4728+
///
4729+
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
4730+
#[cfg(test)]
4731+
pub fn get_accept_channel_message(&self) -> msgs::AcceptChannel {
4732+
self.generate_accept_channel_message()
4733+
}
4734+
46844735
/// If an Err is returned, it is a ChannelError::Close (for get_outbound_funding_created)
46854736
fn get_outbound_funding_created_signature<L: Deref>(&mut self, logger: &L) -> Result<Signature, ChannelError> where L::Target: Logger {
46864737
let counterparty_keys = self.build_remote_transaction_keys()?;
@@ -6064,6 +6115,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60646115
closing_fee_limits: None,
60656116
target_closing_feerate_sats_per_kw,
60666117

6118+
inbound_awaiting_accept: false,
6119+
60676120
funding_tx_confirmed_in,
60686121
funding_tx_confirmation_height,
60696122
short_channel_id,
@@ -6281,10 +6334,10 @@ mod tests {
62816334
// Make sure A's dust limit is as we expect.
62826335
let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
62836336
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
6284-
let node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger).unwrap();
6337+
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger).unwrap();
62856338

62866339
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
6287-
let mut accept_channel_msg = node_b_chan.get_accept_channel();
6340+
let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
62886341
accept_channel_msg.dust_limit_satoshis = 546;
62896342
node_a_chan.accept_channel(&accept_channel_msg, &config.peer_channel_config_limits, &InitFeatures::known()).unwrap();
62906343
node_a_chan.holder_dust_limit_satoshis = 1560;
@@ -6402,7 +6455,7 @@ mod tests {
64026455
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger).unwrap();
64036456

64046457
// Node B --> Node A: accept channel
6405-
let accept_channel_msg = node_b_chan.get_accept_channel();
6458+
let accept_channel_msg = node_b_chan.accept_inbound_channel();
64066459
node_a_chan.accept_channel(&accept_channel_msg, &config.peer_channel_config_limits, &InitFeatures::known()).unwrap();
64076460

64086461
// Node A --> Node B: funding created

lightning/src/ln/channelmanager.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4081,6 +4081,34 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
40814081
}
40824082
}
40834083

4084+
/// Called to accept a request to open a channel after [`Event::OpenChannelRequest`] has been
4085+
/// triggered.
4086+
///
4087+
/// The `temporary_channel_id` parameter indicates which inbound channel should be accepted.
4088+
///
4089+
/// [`Event::OpenChannelRequest`]: crate::util::events::Event::OpenChannelRequest
4090+
pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32]) -> Result<(), APIError> {
4091+
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
4092+
4093+
let mut channel_state_lock = self.channel_state.lock().unwrap();
4094+
let channel_state = &mut *channel_state_lock;
4095+
match channel_state.by_id.entry(temporary_channel_id.clone()) {
4096+
hash_map::Entry::Occupied(mut channel) => {
4097+
if !channel.get().inbound_is_awaiting_accept() {
4098+
return Err(APIError::APIMisuseError { err: "The channel isn't currently awaiting to be accepted.".to_owned() });
4099+
}
4100+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
4101+
node_id: channel.get().get_counterparty_node_id(),
4102+
msg: channel.get_mut().accept_inbound_channel(),
4103+
});
4104+
}
4105+
hash_map::Entry::Vacant(_) => {
4106+
return Err(APIError::ChannelUnavailable { err: "Can't accept a channel that doesn't exist".to_owned() });
4107+
}
4108+
}
4109+
Ok(())
4110+
}
4111+
40844112
fn internal_open_channel(&self, counterparty_node_id: &PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel) -> Result<(), MsgHandleErrInternal> {
40854113
if msg.chain_hash != self.genesis_hash {
40864114
return Err(MsgHandleErrInternal::send_err_msg_no_close("Unknown genesis block hash".to_owned(), msg.temporary_channel_id.clone()));
@@ -4090,18 +4118,31 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
40904118
return Err(MsgHandleErrInternal::send_err_msg_no_close("No inbound channels accepted".to_owned(), msg.temporary_channel_id.clone()));
40914119
}
40924120

4093-
let channel = Channel::new_from_req(&self.fee_estimator, &self.keys_manager, counterparty_node_id.clone(),
4121+
let mut channel = Channel::new_from_req(&self.fee_estimator, &self.keys_manager, counterparty_node_id.clone(),
40944122
&their_features, msg, 0, &self.default_configuration, self.best_block.read().unwrap().height(), &self.logger)
40954123
.map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.temporary_channel_id))?;
40964124
let mut channel_state_lock = self.channel_state.lock().unwrap();
40974125
let channel_state = &mut *channel_state_lock;
40984126
match channel_state.by_id.entry(channel.channel_id()) {
40994127
hash_map::Entry::Occupied(_) => return Err(MsgHandleErrInternal::send_err_msg_no_close("temporary_channel_id collision!".to_owned(), msg.temporary_channel_id.clone())),
41004128
hash_map::Entry::Vacant(entry) => {
4101-
channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
4102-
node_id: counterparty_node_id.clone(),
4103-
msg: channel.get_accept_channel(),
4104-
});
4129+
if !self.default_configuration.manually_accept_inbound_channels {
4130+
channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel {
4131+
node_id: counterparty_node_id.clone(),
4132+
msg: channel.accept_inbound_channel(),
4133+
});
4134+
} else {
4135+
let mut pending_events = self.pending_events.lock().unwrap();
4136+
pending_events.push(
4137+
events::Event::OpenChannelRequest {
4138+
temporary_channel_id: msg.temporary_channel_id.clone(),
4139+
counterparty_node_id: counterparty_node_id.clone(),
4140+
funding_satoshis: msg.funding_satoshis,
4141+
push_msat: msg.push_msat,
4142+
}
4143+
);
4144+
}
4145+
41054146
entry.insert(channel);
41064147
}
41074148
}

0 commit comments

Comments
 (0)