-#[test]
-fn test_no_txn_manager_serialize_deserialize() {
- let chanmon_cfgs = create_chanmon_cfgs(2);
- let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
- let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
- let logger: test_utils::TestLogger;
- let fee_estimator: test_utils::TestFeeEstimator;
- let persister: test_utils::TestPersister;
- let new_chain_monitor: test_utils::TestChainMonitor;
- let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
- let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-
- let tx = create_chan_between_nodes_with_value_init(&nodes[0], &nodes[1], 100000, 10001, InitFeatures::known(), InitFeatures::known());
-
- nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-
- let nodes_0_serialized = nodes[0].node.encode();
- let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- get_monitor!(nodes[0], OutPoint { txid: tx.txid(), index: 0 }.to_channel_id())
- .write(&mut chan_0_monitor_serialized).unwrap();
-
- logger = test_utils::TestLogger::new();
- fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
- persister = test_utils::TestPersister::new();
- let keys_manager = &chanmon_cfgs[0].keys_manager;
- new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
- nodes[0].chain_monitor = &new_chain_monitor;
- let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
- &mut chan_0_monitor_read, keys_manager).unwrap();
- assert!(chan_0_monitor_read.is_empty());
-
- let mut nodes_0_read = &nodes_0_serialized[..];
- let config = UserConfig::default();
- let (_, nodes_0_deserialized_tmp) = {
- let mut channel_monitors = HashMap::new();
- channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
- <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
- default_config: config,
- keys_manager,
- fee_estimator: &fee_estimator,
- chain_monitor: nodes[0].chain_monitor,
- tx_broadcaster: nodes[0].tx_broadcaster.clone(),
- logger: &logger,
- channel_monitors,
- }).unwrap()
- };
- nodes_0_deserialized = nodes_0_deserialized_tmp;
- assert!(nodes_0_read.is_empty());
-
- assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
- nodes[0].node = &nodes_0_deserialized;
- assert_eq!(nodes[0].node.list_channels().len(), 1);
- check_added_monitors!(nodes[0], 1);
-
- nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
- nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
-
- nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
- assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]);
- assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
-
- let (funding_locked, _) = 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], &funding_locked);
- for node in nodes.iter() {
- assert!(node.net_graph_msg_handler.handle_channel_announcement(&announcement).unwrap());
- node.net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
- node.net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
- }
-
- send_payment(&nodes[0], &[&nodes[1]], 1000000);
-}
-
-#[test]
-fn test_manager_serialize_deserialize_events() {
- // This test makes sure the events field in ChannelManager survives de/serialization
- let chanmon_cfgs = create_chanmon_cfgs(2);
- let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
- let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
- let fee_estimator: test_utils::TestFeeEstimator;
- let persister: test_utils::TestPersister;
- let logger: test_utils::TestLogger;
- let new_chain_monitor: test_utils::TestChainMonitor;
- let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
- let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
-
- // Start creating a channel, but stop right before broadcasting the funding transaction
- let channel_value = 100000;
- let push_msat = 10001;
- let a_flags = InitFeatures::known();
- let b_flags = InitFeatures::known();
- let node_a = nodes.remove(0);
- let node_b = nodes.remove(0);
- node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap();
- node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id()));
- node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id()));
-
- let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, channel_value, 42);
-
- node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap();
- check_added_monitors!(node_a, 0);
-
- 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()));
- {
- let mut added_monitors = node_b.chain_monitor.added_monitors.lock().unwrap();
- assert_eq!(added_monitors.len(), 1);
- assert_eq!(added_monitors[0].0, funding_output);
- added_monitors.clear();
- }
-
- let bs_funding_signed = get_event_msg!(node_b, MessageSendEvent::SendFundingSigned, node_a.node.get_our_node_id());
- node_a.node.handle_funding_signed(&node_b.node.get_our_node_id(), &bs_funding_signed);
- {
- let mut added_monitors = node_a.chain_monitor.added_monitors.lock().unwrap();
- assert_eq!(added_monitors.len(), 1);
- assert_eq!(added_monitors[0].0, funding_output);
- added_monitors.clear();
- }
- // Normally, this is where node_a would broadcast the funding transaction, but the test de/serializes first instead
-
- nodes.push(node_a);
- nodes.push(node_b);
-
- // Start the de/seriailization process mid-channel creation to check that the channel manager will hold onto events that are serialized
- let nodes_0_serialized = nodes[0].node.encode();
- let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- get_monitor!(nodes[0], bs_funding_signed.channel_id).write(&mut chan_0_monitor_serialized).unwrap();
-
- fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
- logger = test_utils::TestLogger::new();
- persister = test_utils::TestPersister::new();
- let keys_manager = &chanmon_cfgs[0].keys_manager;
- new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
- nodes[0].chain_monitor = &new_chain_monitor;
- let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
- &mut chan_0_monitor_read, keys_manager).unwrap();
- assert!(chan_0_monitor_read.is_empty());
-
- let mut nodes_0_read = &nodes_0_serialized[..];
- let config = UserConfig::default();
- let (_, nodes_0_deserialized_tmp) = {
- let mut channel_monitors = HashMap::new();
- channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
- <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
- default_config: config,
- keys_manager,
- fee_estimator: &fee_estimator,
- chain_monitor: nodes[0].chain_monitor,
- tx_broadcaster: nodes[0].tx_broadcaster.clone(),
- logger: &logger,
- channel_monitors,
- }).unwrap()
- };
- nodes_0_deserialized = nodes_0_deserialized_tmp;
- assert!(nodes_0_read.is_empty());
-
- nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-
- assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
- nodes[0].node = &nodes_0_deserialized;
-
- // After deserializing, make sure the funding_transaction is still held by the channel manager
- let events_4 = nodes[0].node.get_and_clear_pending_events();
- assert_eq!(events_4.len(), 0);
- assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
- assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].txid(), funding_output.txid);
-
- // Make sure the channel is functioning as though the de/serialization never happened
- assert_eq!(nodes[0].node.list_channels().len(), 1);
- check_added_monitors!(nodes[0], 1);
-
- nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
- nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
-
- nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
- assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
- nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]);
- assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
-
- let (funding_locked, _) = 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], &funding_locked);
- for node in nodes.iter() {
- assert!(node.net_graph_msg_handler.handle_channel_announcement(&announcement).unwrap());
- node.net_graph_msg_handler.handle_channel_update(&as_update).unwrap();
- node.net_graph_msg_handler.handle_channel_update(&bs_update).unwrap();
- }
-
- send_payment(&nodes[0], &[&nodes[1]], 1000000);
-}
-
-#[test]
-fn test_simple_manager_serialize_deserialize() {
- let chanmon_cfgs = create_chanmon_cfgs(2);
- let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
- let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
- let logger: test_utils::TestLogger;
- let fee_estimator: test_utils::TestFeeEstimator;
- let persister: test_utils::TestPersister;
- let new_chain_monitor: test_utils::TestChainMonitor;
- let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
- let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
- let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
-
- let (our_payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
- let (_, our_payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
-
- nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-
- let nodes_0_serialized = nodes[0].node.encode();
- let mut chan_0_monitor_serialized = test_utils::TestVecWriter(Vec::new());
- get_monitor!(nodes[0], chan_id).write(&mut chan_0_monitor_serialized).unwrap();
-
- logger = test_utils::TestLogger::new();
- fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
- persister = test_utils::TestPersister::new();
- let keys_manager = &chanmon_cfgs[0].keys_manager;
- new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
- nodes[0].chain_monitor = &new_chain_monitor;
- let mut chan_0_monitor_read = &chan_0_monitor_serialized.0[..];
- let (_, mut chan_0_monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(
- &mut chan_0_monitor_read, keys_manager).unwrap();
- assert!(chan_0_monitor_read.is_empty());
-
- let mut nodes_0_read = &nodes_0_serialized[..];
- let (_, nodes_0_deserialized_tmp) = {
- let mut channel_monitors = HashMap::new();
- channel_monitors.insert(chan_0_monitor.get_funding_txo().0, &mut chan_0_monitor);
- <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
- default_config: UserConfig::default(),
- keys_manager,
- fee_estimator: &fee_estimator,
- chain_monitor: nodes[0].chain_monitor,
- tx_broadcaster: nodes[0].tx_broadcaster.clone(),
- logger: &logger,
- channel_monitors,
- }).unwrap()
- };
- nodes_0_deserialized = nodes_0_deserialized_tmp;
- assert!(nodes_0_read.is_empty());
-
- assert!(nodes[0].chain_monitor.watch_channel(chan_0_monitor.get_funding_txo().0, chan_0_monitor).is_ok());
- nodes[0].node = &nodes_0_deserialized;
- check_added_monitors!(nodes[0], 1);
-
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
-
- fail_payment(&nodes[0], &[&nodes[1]], our_payment_hash);
- claim_payment(&nodes[0], &[&nodes[1]], our_payment_preimage);
-}
-
-#[test]
-fn test_manager_serialize_deserialize_inconsistent_monitor() {
- // Test deserializing a ChannelManager with an out-of-date ChannelMonitor
- let chanmon_cfgs = create_chanmon_cfgs(4);
- let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
- let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
- let logger: test_utils::TestLogger;
- let fee_estimator: test_utils::TestFeeEstimator;
- let persister: test_utils::TestPersister;
- let new_chain_monitor: test_utils::TestChainMonitor;
- let nodes_0_deserialized: ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>;
- let mut nodes = create_network(4, &node_cfgs, &node_chanmgrs);
- let chan_id_1 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
- let chan_id_2 = create_announced_chan_between_nodes(&nodes, 2, 0, InitFeatures::known(), InitFeatures::known()).2;
- let (_, _, channel_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 3, InitFeatures::known(), InitFeatures::known());
-
- let mut node_0_stale_monitors_serialized = Vec::new();
- for chan_id_iter in &[chan_id_1, chan_id_2, channel_id] {
- let mut writer = test_utils::TestVecWriter(Vec::new());
- get_monitor!(nodes[0], chan_id_iter).write(&mut writer).unwrap();
- node_0_stale_monitors_serialized.push(writer.0);
- }
-
- let (our_payment_preimage, _, _) = route_payment(&nodes[2], &[&nodes[0], &nodes[1]], 1000000);
-
- // Serialize the ChannelManager here, but the monitor we keep up-to-date
- let nodes_0_serialized = nodes[0].node.encode();
-
- route_payment(&nodes[0], &[&nodes[3]], 1000000);
- nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
- nodes[2].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
- nodes[3].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-
- // Now the ChannelMonitor (which is now out-of-sync with ChannelManager for channel w/
- // nodes[3])
- let mut node_0_monitors_serialized = Vec::new();
- for chan_id_iter in &[chan_id_1, chan_id_2, channel_id] {
- let mut writer = test_utils::TestVecWriter(Vec::new());
- get_monitor!(nodes[0], chan_id_iter).write(&mut writer).unwrap();
- node_0_monitors_serialized.push(writer.0);
- }
-
- logger = test_utils::TestLogger::new();
- fee_estimator = test_utils::TestFeeEstimator { sat_per_kw: Mutex::new(253) };
- persister = test_utils::TestPersister::new();
- let keys_manager = &chanmon_cfgs[0].keys_manager;
- new_chain_monitor = test_utils::TestChainMonitor::new(Some(nodes[0].chain_source), nodes[0].tx_broadcaster.clone(), &logger, &fee_estimator, &persister, keys_manager);
- nodes[0].chain_monitor = &new_chain_monitor;
-
-
- let mut node_0_stale_monitors = Vec::new();
- for serialized in node_0_stale_monitors_serialized.iter() {
- let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
- assert!(read.is_empty());
- node_0_stale_monitors.push(monitor);
- }
-
- let mut node_0_monitors = Vec::new();
- for serialized in node_0_monitors_serialized.iter() {
- let mut read = &serialized[..];
- let (_, monitor) = <(BlockHash, ChannelMonitor<EnforcingSigner>)>::read(&mut read, keys_manager).unwrap();
- assert!(read.is_empty());
- node_0_monitors.push(monitor);
- }
-
- let mut nodes_0_read = &nodes_0_serialized[..];
- if let Err(msgs::DecodeError::InvalidValue) =
- <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
- default_config: UserConfig::default(),
- keys_manager,
- fee_estimator: &fee_estimator,
- chain_monitor: nodes[0].chain_monitor,
- tx_broadcaster: nodes[0].tx_broadcaster.clone(),
- logger: &logger,
- channel_monitors: node_0_stale_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect(),
- }) { } else {
- panic!("If the monitor(s) are stale, this indicates a bug and we should get an Err return");
- };
-
- let mut nodes_0_read = &nodes_0_serialized[..];
- let (_, nodes_0_deserialized_tmp) =
- <(BlockHash, ChannelManager<EnforcingSigner, &test_utils::TestChainMonitor, &test_utils::TestBroadcaster, &test_utils::TestKeysInterface, &test_utils::TestFeeEstimator, &test_utils::TestLogger>)>::read(&mut nodes_0_read, ChannelManagerReadArgs {
- default_config: UserConfig::default(),
- keys_manager,
- fee_estimator: &fee_estimator,
- chain_monitor: nodes[0].chain_monitor,
- tx_broadcaster: nodes[0].tx_broadcaster.clone(),
- logger: &logger,
- channel_monitors: node_0_monitors.iter_mut().map(|monitor| { (monitor.get_funding_txo().0, monitor) }).collect(),
- }).unwrap();
- nodes_0_deserialized = nodes_0_deserialized_tmp;
- assert!(nodes_0_read.is_empty());
-
- { // Channel close should result in a commitment tx
- let txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap();
- assert_eq!(txn.len(), 1);
- check_spends!(txn[0], funding_tx);
- assert_eq!(txn[0].input[0].previous_output.txid, funding_tx.txid());
- }
-
- for monitor in node_0_monitors.drain(..) {
- assert!(nodes[0].chain_monitor.watch_channel(monitor.get_funding_txo().0, monitor).is_ok());
- check_added_monitors!(nodes[0], 1);
- }
- nodes[0].node = &nodes_0_deserialized;
- check_closed_event!(nodes[0], 1, ClosureReason::OutdatedChannelManager);
-
- // nodes[1] and nodes[2] have no lost state with nodes[0]...
- reconnect_nodes(&nodes[0], &nodes[1], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
- reconnect_nodes(&nodes[0], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
- //... and we can even still claim the payment!
- claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
-
- nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- let reestablish = get_event_msg!(nodes[3], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
- nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
- nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish);
- let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
- assert_eq!(msg_events.len(), 1);
- if let MessageSendEvent::HandleError { ref action, .. } = msg_events[0] {
- match action {
- &ErrorAction::SendErrorMessage { ref msg } => {
- assert_eq!(msg.channel_id, channel_id);
- },
- _ => panic!("Unexpected event!"),
- }
- }
-}
-