-
- // Clean up scid_task
- net_graph_msg_handler.scid_query_tasks.lock().unwrap().clear();
- }
-
- // Test receipt of a sequence of replies with a valid first reply and a second reply that
- // resumes on the same block as the first reply. The spec requires a subsequent
- // first_blocknum to equal the prior first_blocknum plus number_of_blocks, however
- // due to discrepancies in implementation we must loosen this restriction.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle the first reply message
- let reply_1_scids = vec![
- 0x0003e8_000000_0000, // 1000x0x0
- 0x0003e9_000000_0000, // 1001x0x0
- 0x000419_000000_0000, // 1049x0x0
- ];
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 1000,
- number_of_blocks: 50,
- short_channel_ids: reply_1_scids.clone(),
- });
- assert!(result.is_ok());
-
- // Handle the next reply in the sequence, which is non-spec but resumes on the last block
- // of the first message.
- let reply_2_scids = vec![
- 0x000419_000001_0000, // 1049x1x0
- 0x00041a_000000_0000, // 1050x0x0
- 0x000432_000000_0000, // 1074x0x0
- ];
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 1049,
- number_of_blocks: 51,
- short_channel_ids: reply_2_scids.clone(),
- });
- assert!(result.is_ok());
-
- // After the final reply we expect the query task to be removed
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
-
- // We expect to emit a query_short_channel_ids message with the accumulated scids that
- // match the queried channel range
- let events = net_graph_msg_handler.get_and_clear_pending_msg_events();
- assert_eq!(events.len(), 1);
- match &events[0] {
- MessageSendEvent::SendShortIdsQuery { node_id, msg } => {
- assert_eq!(node_id, &node_id_1);
- assert_eq!(msg.chain_hash, chain_hash);
- assert_eq!(msg.short_channel_ids, [reply_1_scids, reply_2_scids].concat());
- },
- _ => panic!("expected MessageSendEvent::SendShortIdsQuery"),
- }
-
- // Clean up scid_task
- net_graph_msg_handler.scid_query_tasks.lock().unwrap().clear();
- }
-
- // Test receipt of reply with a chain_hash that does not match the query. We expect to return
- // an error and to remove the query task.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle the reply with a mismatched chain_hash. We expect IgnoreError result and the
- // task should be removed.
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash: genesis_block(Network::Bitcoin).header.block_hash(),
- full_information: true,
- first_blocknum: 1000,
- number_of_blocks: 1050,
- short_channel_ids: vec![0x0003e8_000000_0000,0x0003e9_000000_0000,0x0003f0_000000_0000],
- });
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Received reply_channel_range with invalid chain_hash");
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
- }
-
- // Test receipt of a reply that indicates the remote node does not maintain up-to-date
- // information for the chain_hash. Because of discrepancies in implementation we use
- // full_information=false and short_channel_ids=[] as the signal. We should expect an error
- // and the task should be removed.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle the reply indicating the peer was unable to fulfill our request.
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: false,
- first_blocknum: 1000,
- number_of_blocks: 100,
- short_channel_ids: vec![],
- });
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Received reply_channel_range with no information available");
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
- }
-
- // Test receipt of a reply that has a first_blocknum that is above the first_blocknum
- // requested in our query. The reply must contain the queried block range. We expect an
- // error result and the task should be removed.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle the reply that has a first_blocknum above the query's first_blocknum
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 1001,
- number_of_blocks: 100,
- short_channel_ids: vec![],
- });
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Failing reply_channel_range with invalid first_blocknum");
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
- }
-
- // Test receipt of a first reply that does not overlap the query range at all. The first message
- // must have some overlap with the query. We expect an error result and the task should
- // be removed.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle a reply that contains a block range that precedes the queried block range
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 0,
- number_of_blocks: 1000,
- short_channel_ids: vec![],
- });
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Failing reply_channel_range with non-overlapping first reply");
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
- }
-
- // Test receipt of a sequence of replies with a valid first reply and a second reply that is
- // non-sequential. The spec requires a subsequent first_blocknum to equal the prior
- // first_blocknum plus number_of_blocks. We expect an IgnoreError result and the task should
- // be removed.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 100);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle the first reply
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 1000,
- number_of_blocks: 50,
- short_channel_ids: vec![0x0003e8_000000_0000,0x0003e9_000000_0000,0x0003f0_000000_0000],
- });
- assert!(result.is_ok());
-
- // Handle the second reply which does not start at the proper first_blocknum. We expect
- // to return an error and remove the task.
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: 1051,
- number_of_blocks: 50,
- short_channel_ids: vec![0x0003f1_000000_0000,0x0003f2_000000_0000],
- });
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Failing reply_channel_range with invalid sequence");
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());
- }
-
- // Test receipt of too many reply messages. We expect an IgnoreError result and the task should
- // be removed.
- {
- // Initiate a channel range query to create a query task
- let result = net_graph_msg_handler.query_channel_range(&node_id_1, chain_hash, 1000, 0xffff_ffff);
- assert!(result.is_ok());
-
- // Clear the SendRangeQuery event
- net_graph_msg_handler.get_and_clear_pending_msg_events();
-
- // Handle a sequence of replies that will fail once the max number of reply has been exceeded.
- for block in 1000..=1000 + super::MAX_REPLY_CHANNEL_RANGE_PER_QUERY + 10 {
- let result = net_graph_msg_handler.handle_reply_channel_range(&node_id_1, &ReplyChannelRange {
- chain_hash,
- full_information: true,
- first_blocknum: block as u32,
- number_of_blocks: 1,
- short_channel_ids: vec![(block as u64) << 40],
- });
- if block <= 1000 + super::MAX_REPLY_CHANNEL_RANGE_PER_QUERY {
- assert!(result.is_ok());
- } else if block == 1001 + super::MAX_REPLY_CHANNEL_RANGE_PER_QUERY {
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Failing reply_channel_range due to excessive messages");
- } else {
- assert!(result.is_err());
- assert_eq!(result.err().unwrap().err, "Received unknown reply_channel_range message");
- }
- }
-
- // Expect the task to be removed
- assert!(net_graph_msg_handler.chan_range_query_tasks.lock().unwrap().is_empty());