&self.get_counterparty_pubkeys().funding_pubkey
}
- pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>), ChannelError> where L::Target: Logger {
+ pub fn funding_created<L: Deref>(&mut self, msg: &msgs::FundingCreated, best_block: BestBlock, logger: &L) -> Result<(msgs::FundingSigned, ChannelMonitor<Signer>, Option<msgs::FundingLocked>), ChannelError> where L::Target: Logger {
if self.is_outbound() {
return Err(ChannelError::Close("Received funding_created for an outbound channel?".to_owned()));
}
Ok((msgs::FundingSigned {
channel_id: self.channel_id,
signature
- }, channel_monitor))
+ }, channel_monitor, self.check_get_funding_locked(0)))
}
/// Handles a funding_signed message from the remote end.
}]};
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
- let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap();
+ let (funding_signed_msg, _, _) = node_b_chan.funding_created(&funding_created_msg, best_block, &&logger).unwrap();
// Node B --> Node A: funding signed
let _ = node_a_chan.funding_signed(&funding_signed_msg, best_block, &&logger);
action: msgs::ErrorAction::IgnoreError
});
}
+ if chan.get_short_channel_id().is_none() {
+ return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError});
+ }
log_trace!(self.logger, "Attempting to generate broadcast channel update for channel {}", log_bytes!(chan.channel_id()));
self.get_channel_update_for_unicast(chan)
}
/// May be called with channel_state already locked!
fn get_channel_update_for_unicast(&self, chan: &Channel<Signer>) -> Result<msgs::ChannelUpdate, LightningError> {
log_trace!(self.logger, "Attempting to generate channel update for channel {}", log_bytes!(chan.channel_id()));
- let short_channel_id = match chan.get_short_channel_id() {
+ let short_channel_id = match chan.get_short_channel_id().or(chan.latest_inbound_scid_alias()) {
None => return Err(LightningError{err: "Channel not yet established".to_owned(), action: msgs::ErrorAction::IgnoreError}),
Some(id) => id,
};
}
fn internal_funding_created(&self, counterparty_node_id: &PublicKey, msg: &msgs::FundingCreated) -> Result<(), MsgHandleErrInternal> {
- let ((funding_msg, monitor), mut chan) = {
+ let ((funding_msg, monitor, mut funding_locked), mut chan) = {
let best_block = *self.best_block.read().unwrap();
let mut channel_lock = self.channel_state.lock().unwrap();
let channel_state = &mut *channel_lock;
// hasn't persisted to disk yet - we can't lose money on a transaction that we haven't
// accepted payment from yet. We do, however, need to wait to send our funding_locked
// until we have persisted our monitor.
- chan.monitor_update_failed(false, false, false, Vec::new(), Vec::new(), Vec::new());
+ chan.monitor_update_failed(false, false, funding_locked.is_some(), Vec::new(), Vec::new(), Vec::new());
+ funding_locked = None; // Don't send the funding_locked now
},
}
}
node_id: counterparty_node_id.clone(),
msg: funding_msg,
});
+ if let Some(msg) = funding_locked {
+ send_funding_locked!(channel_state.short_to_id, channel_state.pending_msg_events, chan, msg);
+ }
e.insert(chan);
}
}
// If our peer tells us they will accept our channel with 0 confs, and we funded the channel,
// we should trust the funding won't be double-spent (assuming `trust_own_funding_0conf` is
// set)!
+ // Further, if we `accept_inbound_channel_from_trusted_peer_0conf`, funding locked messages
+ // should fly immediately and the channel should be available for use as soon as they are
+ // received.
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
check_added_monitors!(nodes[1], 1);
- let funding_signed = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
-
- nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed);
- check_added_monitors!(nodes[0], 1);
+ let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
+ assert_eq!(bs_signed_locked.len(), 2);
+ let as_funding_locked;
+ match &bs_signed_locked[0] {
+ MessageSendEvent::SendFundingSigned { node_id, msg } => {
+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &msg);
+ check_added_monitors!(nodes[0], 1);
+
+ assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
+ assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0)[0], tx);
+
+ as_funding_locked = get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id());
+ }
+ _ => panic!("Unexpected event"),
+ }
+ match &bs_signed_locked[1] {
+ MessageSendEvent::SendFundingLocked { node_id, msg } => {
+ assert_eq!(*node_id, nodes[0].node.get_our_node_id());
+ nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &msg);
+ }
+ _ => panic!("Unexpected event"),
+ }
- let as_funding_locked = get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id());
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
+
+ let as_channel_update = get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
+ let bs_channel_update = get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
+
+ nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &bs_channel_update);
+ nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &as_channel_update);
+
+ assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
+ assert_eq!(nodes[1].node.list_usable_channels().len(), 1);
}