msg.clone()
} else { panic!("Wrong event type"); }
};
+ let events = $dest.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ if let events::Event::ChannelPending{ ref counterparty_node_id, .. } = events[0] {
+ assert_eq!(counterparty_node_id, &$source.get_our_node_id());
+ } else { panic!("Wrong event type"); }
+
$source.handle_funding_signed(&$dest.get_our_node_id(), &funding_signed);
+ let events = $source.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ if let events::Event::ChannelPending{ ref counterparty_node_id, .. } = events[0] {
+ assert_eq!(counterparty_node_id, &$dest.get_our_node_id());
+ } else { panic!("Wrong event type"); }
funding_output
} }
use lightning::chain::keysinterface::{InMemorySigner, KeysManager};
use lightning::chain::transaction::OutPoint;
use lightning::events::{Event, PathFailure, MessageSendEventsProvider, MessageSendEvent};
- use lightning::get_event_msg;
+ use lightning::{get_event_msg, get_event};
use lightning::ln::PaymentHash;
use lightning::ln::channelmanager;
use lightning::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChainParameters, MIN_CLTV_EXPIRY_DELTA, PaymentId};
($node_a: expr, $node_b: expr, $temporary_channel_id: expr, $tx: expr) => {{
$node_a.node.funding_transaction_generated(&$temporary_channel_id, &$node_b.node.get_our_node_id(), $tx.clone()).unwrap();
$node_b.node.handle_funding_created(&$node_a.node.get_our_node_id(), &get_event_msg!($node_a, MessageSendEvent::SendFundingCreated, $node_b.node.get_our_node_id()));
+ get_event!($node_b, Event::ChannelPending);
+
$node_a.node.handle_funding_signed(&$node_b.node.get_our_node_id(), &get_event_msg!($node_b, MessageSendEvent::SendFundingSigned, $node_a.node.get_our_node_id()));
+ get_event!($node_a, Event::ChannelPending);
}}
}
use crate::util::string::UntrustedString;
use crate::routing::router::{RouteHop, RouteParameters};
-use bitcoin::{PackedLockTime, Transaction};
+use bitcoin::{PackedLockTime, Transaction, OutPoint};
+#[cfg(anchors)]
+use bitcoin::{Txid, TxIn, TxOut, Witness};
use bitcoin::blockdata::script::Script;
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
/// The caveat described above the `fee_earned_msat` field applies here as well.
outbound_amount_forwarded_msat: Option<u64>,
},
+ /// Used to indicate that a channel with the given `channel_id` is being opened and pending
+ /// confirmation on-chain.
+ ///
+ /// This event is emitted when the funding transaction has been signed and is broadcast to the
+ /// network. For 0conf channels it will be immediately followed by the corresponding
+ /// [`Event::ChannelReady`] event.
+ ChannelPending {
+ /// The `channel_id` of the channel that is pending confirmation.
+ channel_id: [u8; 32],
+ /// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
+ /// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
+ /// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise
+ /// `user_channel_id` will be randomized for an inbound channel.
+ ///
+ /// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel
+ /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
+ /// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
+ user_channel_id: u128,
+ /// The `temporary_channel_id` this channel used to be known by during channel establishment.
+ ///
+ /// Will be `None` for channels created prior to LDK version 0.0.115.
+ former_temporary_channel_id: Option<[u8; 32]>,
+ /// The `node_id` of the channel counterparty.
+ counterparty_node_id: PublicKey,
+ /// The outpoint of the channel's funding transaction.
+ funding_txo: OutPoint,
+ },
/// Used to indicate that a channel with the given `channel_id` is ready to
/// be used. This event is emitted either when the funding transaction has been confirmed
/// on-chain, or, in case of a 0conf channel, when both parties have confirmed the channel
/// establishment.
ChannelReady {
- /// The channel_id of the channel that is ready.
+ /// The `channel_id` of the channel that is ready.
channel_id: [u8; 32],
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels
user_channel_id: u128,
- /// The node_id of the channel counterparty.
+ /// The `node_id` of the channel counterparty.
counterparty_node_id: PublicKey,
/// The features that this channel will operate with.
channel_type: ChannelTypeFeatures,
/// Used to indicate that a previously opened channel with the given `channel_id` is in the
/// process of closure.
ChannelClosed {
- /// The channel_id of the channel which has been closed. Note that on-chain transactions
+ /// The `channel_id` of the channel which has been closed. Note that on-chain transactions
/// resolving the channel are likely still awaiting confirmation.
channel_id: [u8; 32],
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound
(6, channel_type, required),
});
},
+ &Event::ChannelPending { ref channel_id, ref user_channel_id, ref former_temporary_channel_id, ref counterparty_node_id, ref funding_txo } => {
+ 31u8.write(writer)?;
+ write_tlv_fields!(writer, {
+ (0, channel_id, required),
+ (2, user_channel_id, required),
+ (4, former_temporary_channel_id, required),
+ (6, counterparty_node_id, required),
+ (8, funding_txo, required),
+ });
+ },
// Note that, going forward, all new events must only write data inside of
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write
// data via `write_tlv_fields`.
};
f()
},
+ 31u8 => {
+ let f = || {
+ let mut channel_id = [0; 32];
+ let mut user_channel_id: u128 = 0;
+ let mut former_temporary_channel_id = None;
+ let mut counterparty_node_id = RequiredWrapper(None);
+ let mut funding_txo = RequiredWrapper(None);
+ read_tlv_fields!(reader, {
+ (0, channel_id, required),
+ (2, user_channel_id, required),
+ (4, former_temporary_channel_id, required),
+ (6, counterparty_node_id, required),
+ (8, funding_txo, required),
+ });
+
+ Ok(Some(Event::ChannelPending {
+ channel_id,
+ user_channel_id,
+ former_temporary_channel_id,
+ counterparty_node_id: counterparty_node_id.0.unwrap(),
+ funding_txo: funding_txo.0.unwrap()
+ }))
+ };
+ f()
+ },
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue.
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt
// reads.
let (outpoint, latest_update, _) = nodes[0].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&channel_id).unwrap().clone();
nodes[0].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
check_added_monitors!(nodes[0], 0);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 0);
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id());
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id());
reconnect_nodes(&nodes[0], &nodes[1], (false, confirm_a_first), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
+
+ // But we want to re-emit ChannelPending
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
check_added_monitors!(nodes[1], 1);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(bs_signed_locked.len(), if use_0conf { 2 } else { 1 });
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &funding_signed_msg);
check_added_monitors!(nodes[0], 1);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let as_funding_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
if lock_commitment {
user_id: u128,
channel_id: [u8; 32],
+ temporary_channel_id: Option<[u8; 32]>, // Will be `None` for channels created prior to 0.0.115.
channel_state: u32,
// When we reach max(6 blocks, minimum_depth), we need to send an AnnouncementSigs message to
// blinded paths instead of simple scid+node_id aliases.
outbound_scid_alias: u64,
+ // We track whether we already emitted a `ChannelPending` event.
+ channel_pending_event_emitted: bool,
+
// We track whether we already emitted a `ChannelReady` event.
channel_ready_event_emitted: bool,
}
}
+ let temporary_channel_id = entropy_source.get_secure_random_bytes();
+
Ok(Channel {
user_id,
inbound_handshake_limits_override: Some(config.channel_handshake_limits.clone()),
- channel_id: entropy_source.get_secure_random_bytes(),
+ channel_id: temporary_channel_id,
+ temporary_channel_id: Some(temporary_channel_id),
channel_state: ChannelState::OurInitSent as u32,
announcement_sigs_state: AnnouncementSigsState::NotSent,
secp_ctx,
latest_inbound_scid_alias: None,
outbound_scid_alias,
+ channel_pending_event_emitted: false,
channel_ready_event_emitted: false,
#[cfg(any(test, fuzzing))]
inbound_handshake_limits_override: None,
channel_id: msg.temporary_channel_id,
+ temporary_channel_id: Some(msg.temporary_channel_id),
channel_state: (ChannelState::OurInitSent as u32) | (ChannelState::TheirInitSent as u32),
announcement_sigs_state: AnnouncementSigsState::NotSent,
secp_ctx,
latest_inbound_scid_alias: None,
outbound_scid_alias,
+ channel_pending_event_emitted: false,
channel_ready_event_emitted: false,
#[cfg(any(test, fuzzing))]
self.channel_id
}
+ // Return the `temporary_channel_id` used during channel establishment.
+ //
+ // Will return `None` for channels created prior to LDK version 0.0.115.
+ pub fn temporary_channel_id(&self) -> Option<[u8; 32]> {
+ self.temporary_channel_id
+ }
+
pub fn minimum_depth(&self) -> Option<u32> {
self.minimum_depth
}
self.prev_config.map(|prev_config| prev_config.0)
}
+ // Checks whether we should emit a `ChannelPending` event.
+ pub(crate) fn should_emit_channel_pending_event(&mut self) -> bool {
+ self.is_funding_initiated() && !self.channel_pending_event_emitted
+ }
+
+ // Returns whether we already emitted a `ChannelPending` event.
+ pub(crate) fn channel_pending_event_emitted(&self) -> bool {
+ self.channel_pending_event_emitted
+ }
+
+ // Remembers that we already emitted a `ChannelPending` event.
+ pub(crate) fn set_channel_pending_event_emitted(&mut self) {
+ self.channel_pending_event_emitted = true;
+ }
+
// Checks whether we should emit a `ChannelReady` event.
pub(crate) fn should_emit_channel_ready_event(&mut self) -> bool {
self.is_usable() && !self.channel_ready_event_emitted
if self.holder_max_htlc_value_in_flight_msat != Self::get_holder_max_htlc_value_in_flight_msat(self.channel_value_satoshis, &old_max_in_flight_percent_config)
{ Some(self.holder_max_htlc_value_in_flight_msat) } else { None };
+ let channel_pending_event_emitted = Some(self.channel_pending_event_emitted);
let channel_ready_event_emitted = Some(self.channel_ready_event_emitted);
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
(23, channel_ready_event_emitted, option),
(25, user_id_high_opt, option),
(27, self.channel_keys_id, required),
+ (29, self.temporary_channel_id, option),
+ (31, channel_pending_event_emitted, option),
});
Ok(())
let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
let mut latest_inbound_scid_alias = None;
let mut outbound_scid_alias = None;
+ let mut channel_pending_event_emitted = None;
let mut channel_ready_event_emitted = None;
let mut user_id_high_opt: Option<u64> = None;
let mut channel_keys_id: Option<[u8; 32]> = None;
+ let mut temporary_channel_id: Option<[u8; 32]> = None;
read_tlv_fields!(reader, {
(0, announcement_sigs, option),
(23, channel_ready_event_emitted, option),
(25, user_id_high_opt, option),
(27, channel_keys_id, option),
+ (29, temporary_channel_id, option),
+ (31, channel_pending_event_emitted, option),
});
let (channel_keys_id, holder_signer) = if let Some(channel_keys_id) = channel_keys_id {
inbound_handshake_limits_override: None,
channel_id,
+ temporary_channel_id,
channel_state,
announcement_sigs_state: announcement_sigs_state.unwrap(),
secp_ctx,
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
outbound_scid_alias: outbound_scid_alias.unwrap_or(0),
+ channel_pending_event_emitted: channel_pending_event_emitted.unwrap_or(true),
channel_ready_event_emitted: channel_ready_event_emitted.unwrap_or(true),
#[cfg(any(test, fuzzing))]
}}
}
+macro_rules! emit_channel_pending_event {
+ ($locked_events: expr, $channel: expr) => {
+ if $channel.should_emit_channel_pending_event() {
+ $locked_events.push(events::Event::ChannelPending {
+ channel_id: $channel.channel_id(),
+ former_temporary_channel_id: $channel.temporary_channel_id(),
+ counterparty_node_id: $channel.get_counterparty_node_id(),
+ user_channel_id: $channel.get_user_id(),
+ funding_txo: $channel.get_funding_txo().unwrap().into_bitcoin_outpoint(),
+ });
+ $channel.set_channel_pending_event_emitted();
+ }
+ }
+}
+
macro_rules! emit_channel_ready_event {
- ($self: expr, $channel: expr) => {
+ ($locked_events: expr, $channel: expr) => {
if $channel.should_emit_channel_ready_event() {
- {
- let mut pending_events = $self.pending_events.lock().unwrap();
- pending_events.push(events::Event::ChannelReady {
- channel_id: $channel.channel_id(),
- user_channel_id: $channel.get_user_id(),
- counterparty_node_id: $channel.get_counterparty_node_id(),
- channel_type: $channel.get_channel_type().clone(),
- });
- }
+ debug_assert!($channel.channel_pending_event_emitted());
+ $locked_events.push(events::Event::ChannelReady {
+ channel_id: $channel.channel_id(),
+ user_channel_id: $channel.get_user_id(),
+ counterparty_node_id: $channel.get_counterparty_node_id(),
+ channel_type: $channel.get_channel_type().clone(),
+ });
$channel.set_channel_ready_event_emitted();
}
}
});
}
- emit_channel_ready_event!(self, channel);
-
macro_rules! handle_cs { () => {
if let Some(update) = commitment_update {
pending_msg_events.push(events::MessageSendEvent::UpdateHTLCs {
self.tx_broadcaster.broadcast_transaction(&tx);
}
+ {
+ let mut pending_events = self.pending_events.lock().unwrap();
+ emit_channel_pending_event!(pending_events, channel);
+ emit_channel_ready_event!(pending_events, channel);
+ }
+
htlc_forwards
}
}
}
- emit_channel_ready_event!(self, chan.get_mut());
+ {
+ let mut pending_events = self.pending_events.lock().unwrap();
+ emit_channel_ready_event!(pending_events, chan.get_mut());
+ }
Ok(())
},
}
}
- emit_channel_ready_event!(self, channel);
+ {
+ let mut pending_events = self.pending_events.lock().unwrap();
+ emit_channel_ready_event!(pending_events, channel);
+ }
if let Some(announcement_sigs) = announcement_sigs {
log_trace!(self.logger, "Sending announcement_signatures for channel {}", log_bytes!(channel.channel_id()));
assert_eq!(nodes_0_lock.len(), 1);
assert!(nodes_0_lock.contains_key(channel_id));
}
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
{
// Assert that `nodes[1]`'s `id_to_peer` map is populated with the channel as soon as
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);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let (channel_ready, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
let (announcement, nodes_0_update, nodes_1_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &nodes_0_update, &nodes_1_update);
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created_msg);
check_added_monitors!(nodes[1], 1);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
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);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
}
open_channel_msg.temporary_channel_id = nodes[0].keys_manager.get_secure_random_bytes();
}
use crate::chain::chainmonitor::{ChainMonitor, Persist};
use crate::chain::keysinterface::{EntropySource, KeysManager, InMemorySigner};
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
- use crate::ln::channelmanager::{self, BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId};
+ use crate::ln::channelmanager::{BestBlock, ChainParameters, ChannelManager, PaymentHash, PaymentPreimage, PaymentId};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{ChannelMessageHandler, Init};
use crate::routing::gossip::NetworkGraph;
} else { panic!(); }
node_b.handle_funding_created(&node_a.get_our_node_id(), &get_event_msg!(node_a_holder, MessageSendEvent::SendFundingCreated, node_b.get_our_node_id()));
+ let events_b = node_b.get_and_clear_pending_events();
+ assert_eq!(events_b.len(), 1);
+ match events_b[0] {
+ Event::ChannelPending{ ref counterparty_node_id, .. } => {
+ assert_eq!(*counterparty_node_id, node_a.get_our_node_id());
+ },
+ _ => panic!("Unexpected event"),
+ }
+
node_a.handle_funding_signed(&node_b.get_our_node_id(), &get_event_msg!(node_b_holder, MessageSendEvent::SendFundingSigned, node_a.get_our_node_id()));
+ let events_a = node_a.get_and_clear_pending_events();
+ assert_eq!(events_a.len(), 1);
+ match events_a[0] {
+ Event::ChannelPending{ ref counterparty_node_id, .. } => {
+ assert_eq!(*counterparty_node_id, node_b.get_our_node_id());
+ },
+ _ => panic!("Unexpected event"),
+ }
assert_eq!(&tx_broadcaster.txn_broadcasted.lock().unwrap()[..], &[tx.clone()]);
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&node_b, &node_a.node.get_our_node_id());
node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id()));
{
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&node_a, &node_b.node.get_our_node_id());
let events_4 = node_a.node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 0);
MessageSendEvent::SendFundingSigned { node_id, msg } => {
assert_eq!(*node_id, initiator.node.get_our_node_id());
initiator.node.handle_funding_signed(&receiver.node.get_our_node_id(), &msg);
+ expect_channel_pending_event(&initiator, &receiver.node.get_our_node_id());
+ expect_channel_pending_event(&receiver, &initiator.node.get_our_node_id());
check_added_monitors!(initiator, 1);
assert_eq!(initiator.tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
MessageSendEvent::SendChannelReady { node_id, msg } => {
assert_eq!(*node_id, initiator.node.get_our_node_id());
initiator.node.handle_channel_ready(&receiver.node.get_our_node_id(), &msg);
+ expect_channel_ready_event(&initiator, &receiver.node.get_our_node_id());
}
_ => panic!("Unexpected event"),
}
receiver.node.handle_channel_ready(&initiator.node.get_our_node_id(), &as_channel_ready);
+ expect_channel_ready_event(&receiver, &initiator.node.get_our_node_id());
let as_channel_update = get_event_msg!(initiator, MessageSendEvent::SendChannelUpdate, receiver.node.get_our_node_id());
let bs_channel_update = get_event_msg!(receiver, MessageSendEvent::SendChannelUpdate, initiator.node.get_our_node_id());
assert_eq!(initiator.node.list_usable_channels().len(), initiator_channels + 1);
assert_eq!(receiver.node.list_usable_channels().len(), receiver_channels + 1);
- expect_channel_ready_event(&initiator, &receiver.node.get_our_node_id());
- expect_channel_ready_event(&receiver, &initiator.node.get_our_node_id());
-
(tx, as_channel_ready.channel_id)
}
check_added_monitors!(nodes[b], 1);
let cs_funding_signed = get_event_msg!(nodes[b], MessageSendEvent::SendFundingSigned, nodes[a].node.get_our_node_id());
+ expect_channel_pending_event(&nodes[b], &nodes[a].node.get_our_node_id());
+
nodes[a].node.handle_funding_signed(&nodes[b].node.get_our_node_id(), &cs_funding_signed);
+ expect_channel_pending_event(&nodes[a], &nodes[b].node.get_our_node_id());
check_added_monitors!(nodes[a], 1);
assert_eq!(nodes[a].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
}
}
+#[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
+pub fn expect_channel_pending_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
+ let events = node.node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 1);
+ match events[0] {
+ crate::events::Event::ChannelPending { ref counterparty_node_id, .. } => {
+ assert_eq!(*expected_counterparty_node_id, *counterparty_node_id);
+ },
+ _ => panic!("Unexpected event"),
+ }
+}
+
#[cfg(any(test, feature = "_bench_unstable", feature = "_test_utils"))]
pub fn expect_channel_ready_event<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, expected_counterparty_node_id: &PublicKey) {
let events = node.node.get_and_clear_pending_events();
}
}
-
pub struct PaymentFailedConditions<'a> {
pub(crate) expected_htlc_error_data: Option<(u16, &'a [u8])>,
pub(crate) expected_blamed_scid: Option<u64>,
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
let funding_signed = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
if steps & 0x0f == 5 { return; }
added_monitors.clear();
}
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let events_4 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 0);
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
+
let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
let funding_outpoint = crate::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index };
assert_eq!(added_monitors[0].0, funding_output);
added_monitors.clear();
}
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let events_4 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_4.len(), 0);
nodes[0].node.funding_transaction_generated_unchecked(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone(), 0).unwrap();
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()));
check_added_monitors!(nodes[1], 1);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id()));
check_added_monitors!(nodes[0], 1);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let events_1 = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events_1.len(), 0);
nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap();
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()));
check_added_monitors!(nodes[1], 1);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id()));
check_added_monitors!(nodes[0], 1);
+ expect_channel_pending_event(&nodes[0], &nodes[1].node.get_our_node_id());
let (channel_ready, channel_id) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
check_added_monitors!(nodes[2], 1);
let cs_funding_signed = get_event_msg!(nodes[2], MessageSendEvent::SendFundingSigned, nodes[1].node.get_our_node_id());
+ expect_channel_pending_event(&nodes[2], &nodes[1].node.get_our_node_id());
+
nodes[1].node.handle_funding_signed(&nodes[2].node.get_our_node_id(), &cs_funding_signed);
+ expect_channel_pending_event(&nodes[1], &nodes[2].node.get_our_node_id());
check_added_monitors!(nodes[1], 1);
let conf_height = core::cmp::max(nodes[1].best_block_info().1 + 1, nodes[2].best_block_info().1 + 1);
let channel_id = funding_output.to_channel_id();
nodes[1].chain_monitor.complete_sole_pending_chan_update(&channel_id);
+ expect_channel_pending_event(&nodes[1], &nodes[0].node.get_our_node_id());
let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(bs_signed_locked.len(), 2);
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
nodes[0].chain_monitor.complete_sole_pending_chan_update(&channel_id);
+
+ let events = nodes[0].node.get_and_clear_pending_events();
+ assert_eq!(events.len(), 2);
+ match events[0] {
+ crate::events::Event::ChannelPending { ref counterparty_node_id, .. } => {
+ assert_eq!(nodes[1].node.get_our_node_id(), *counterparty_node_id);
+ },
+ _ => panic!("Unexpected event"),
+ }
+ match events[1] {
+ crate::events::Event::ChannelReady { ref counterparty_node_id, .. } => {
+ assert_eq!(nodes[1].node.get_our_node_id(), *counterparty_node_id);
+ },
+ _ => panic!("Unexpected event"),
+ }
+
let as_locked_update = nodes[0].node.get_and_clear_pending_msg_events();
// Note that the funding transaction is actually released when
}
_ => panic!("Unexpected event"),
}
- expect_channel_ready_event(&nodes[0], &nodes[1].node.get_our_node_id());
expect_channel_ready_event(&nodes[1], &nodes[0].node.get_our_node_id());
let bs_channel_update = get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
}
// Normally, this is where node_a would broadcast the funding transaction, but the test de/serializes first instead
+ expect_channel_pending_event(&node_a, &node_b.node.get_our_node_id());
+ expect_channel_pending_event(&node_b, &node_a.node.get_our_node_id());
+
nodes.push(node_a);
nodes.push(node_b);