Skip to content

Adding gossip_queries messages and serializations #684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 14, 2020

Conversation

bmancini55
Copy link
Contributor

WIP for #615. This currently includes the first of several commits for adding gossip_queries.

The first commit adds structs for gossip_queries. I was playing around with a more robust de/ser implementation for encoded_short_ids, but figured I would just implement a straightforward version as a first pass.

Currently have the following in-progress:

  • adding new types to the wire module and stubbing peer_handler for handling inbound messages of for the new types
  • adding gossip_queries to features

I'm thinking I will create a new GossipQueriesMessageHandler to be used by the PeerManager for managing the querying process. I'm still working out the details on this part though.

If there's anything glaringly off about this first commit please let me know! Thanks!

@bmancini55 bmancini55 changed the title Adding support for gossip_queries WIP: Adding support for gossip_queries Sep 7, 2020
@codecov
Copy link

codecov bot commented Sep 7, 2020

Codecov Report

Merging #684 into master will decrease coverage by 16.58%.
The diff coverage is 89.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master     #684       +/-   ##
===========================================
- Coverage   91.38%   74.79%   -16.59%     
===========================================
  Files          35       55       +20     
  Lines       21724    24668     +2944     
===========================================
- Hits        19852    18451     -1401     
- Misses       1872     6217     +4345     
Impacted Files Coverage Δ
lightning/src/ln/msgs.rs 86.96% <89.00%> (-3.36%) ⬇️
lightning/src/util/errors.rs 25.58% <0.00%> (-55.82%) ⬇️
lightning/src/util/byte_utils.rs 57.69% <0.00%> (-42.31%) ⬇️
lightning/src/util/macro_logger.rs 70.96% <0.00%> (-18.32%) ⬇️
lightning/src/util/ser_macros.rs 78.65% <0.00%> (-17.95%) ⬇️
lightning/src/util/config.rs 52.38% <0.00%> (-16.67%) ⬇️
lightning/src/util/chacha20.rs 79.51% <0.00%> (-11.88%) ⬇️
lightning/src/ln/features.rs 87.26% <0.00%> (-11.46%) ⬇️
lightning/src/util/logger.rs 48.33% <0.00%> (-11.35%) ⬇️
lightning/src/routing/router.rs 87.79% <0.00%> (-8.89%) ⬇️
... and 45 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3defcc8...10e818a. Read the comment docs.

Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall pretty clean, only minors. What's your approach do you prefer keeping building on this PR or land already messages/serializations ?

I'm thinking I will create a new GossipQueriesMessageHandler to be used by the PeerManager for managing the querying process. I'm still working out the details on this part though.

Right, as a new struct or as new trait implemented by default on the current NetGraphMsgHandler ? I would favor the second one as it's where NetworkGraph is currently living.

And welcome on the repo :)

pub struct QueryChannelRange {
/// The genesis hash of the blockchain being queried
pub chain_hash: BlockHash,
/// The height of the first block to be queried
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For gossip newcomers, precise we don't fetch a block but channel utxos included in those one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to clarify that first_blocknum is for the channel utxos being queried

pub first_blocknum: u32,
/// The number of blocks included in for the range of the reply
pub number_of_blocks: u32,
/// Indicates if the query was able to be served
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should document that QueryChannelRange receiver just have a best-effort requirement to send back network view. So we could document it's full local information, not perfect information of network history.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I the comment on ReplyChannelRange to indicate the recipient replies with a best effort based on their local network view. I also updated full_information with text from the spec on whether the recipient maintains up-to-date information the chain_hash`. Happy to change this around if you think it can be clarified better.

@bmancini55
Copy link
Contributor Author

Thanks for taking a look!

What's your approach do you prefer keeping building on this PR or land already messages/serializations ?

I'll clean this up and mark this part ready since its fairly isolated and I don't think there will be much iteration on it. I can open another WIP PR for the remainder of the work then.

Right, as a new struct or as new trait implemented by default on the current NetGraphMsgHandler ? I would favor the second one as it's where NetworkGraph is currently living.

I was thinking a new trait. NetGraphMsgHandler makes sense to me as well. I was thinking about using the MessageSendEvent pipeline to wire up handling replies (eg: ReplyQueryRange SCIDs get sent in m number of QueryShortChannelIds messages). I haven't had a chance to dig into how that all works yet other than reviewing process_events in PeerManager. So hopefully I'm not totally off base there.

And welcome on the repo :)

Thanks! Glad to be able to assist!

@TheBlueMatt
Copy link
Collaborator

This needs new fuzzers for the new messages - add them to fuzz/src/msg_targets/gen_target.sh and run it to auto-generate new fuzzers.

@bmancini55 bmancini55 force-pushed the gossip_queries branch 2 times, most recently from d2ca2d0 to a3973d4 Compare September 10, 2020 23:23
@bmancini55 bmancini55 changed the title WIP: Adding support for gossip_queries Adding gossip_queries messages and serializations Sep 11, 2020
@bmancini55
Copy link
Contributor Author

I'm not sure why code coverage is not picking up the message structs. I would have thought the tests in ln::msgs::tests would have them covered. Any ideas?

@bmancini55 bmancini55 marked this pull request as ready for review September 11, 2020 00:10
Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just left few more minors.

I was thinking a new trait. NetGraphMsgHandler makes sense to me as well. I was thinking about using the MessageSendEvent pipeline to wire up handling replies (eg: ReplyQueryRange SCIDs get sent in m number of QueryShortChannelIds messages). I haven't had a chance to dig into how that all works yet other than reviewing process_events in PeerManager. So hopefully I'm not totally off base there.

Sounds good to me, MessageSendEvent can be used to reply from local node to requesting peers. Feel free to open a draft PR as soon as you want more concrete feedback.

}

let encoding_type: u8 = Readable::read(r)?;
if encoding_type != EncodingType::Uncompressed as u8 {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe comment we expect 1-byte length short_channel_id. Also that queries/replies must be uncompressed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean 8-byte length short_channel_id?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, you're right !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries! Just wanted to make sure I wasn't misunderstanding how things worked haha

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments about encoding_len, encoding_type, and reading the short_channel_ids

/// Multiple reply_channel_range messages can be sent in reply to a single
/// query_channel_range message. The query recipient makes a best effort
/// to respond based on their local network view which may not be
/// a perfect view of the network.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mark we don't support zlib serialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment about zlib

}

/// Encoding type for data compression of collections in gossip queries
enum EncodingType {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe mark explicitly somewhere we don't support spec encoding-type of 1 for zlib serialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment about not supporting zlib

pub number_of_blocks: u32,
}

/// A reply_channel_range message that can be sent or received from a peer.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every p2p messages can be sent or received, that doesn't add that much information. I realized we do this for every other message, you can drop it IMO.

@@ -570,6 +570,77 @@ pub struct ChannelUpdate {
pub contents: UnsignedChannelUpdate,
}

/// A query_channel_range message that can be sent or received from a peer
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can explain shortly purpose of this message, what response you aim to provoke sending it to your peer to fulfill which need.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated comments for remove the old standard message and added general description of what the message does, what the reply should be, and any notes on serialization limitations. Please let me know if it's too verbose now or if there is anything that is unclear, thanks!

@ariard
Copy link

ariard commented Sep 11, 2020

I'm not sure why code coverage is not picking up the message structs. I would have thought the tests in ln::msgs::tests would have them covered. Any ideas?

Doesn't mind for now, AFAICT codecov isn't perfect.

@ariard
Copy link

ariard commented Sep 14, 2020

Code Review ACK 9db02ef

Thanks for the extended comments, they do provide value as the BOLT7 gossip specs is quite blurred.

Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks. Four trivial one-line changes to avoid needless allocation/nits, but happy to take after those.


// Read short_channel_ids (8-bytes each), for the encoding_len
// less the 1-byte encoding_type
let mut short_channel_ids = vec![];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a Vec::with_capacity(cmp::max(ln::peer_channel_encryptor::LN_MAX_MSG_LEN / 8, (encoding_len - 1)/8))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good call on allocations!

Do you think we should move the upper-bound range check up to where we validate encoding_length? I'm thinking that if we get an encoding_length that causes an LN_MAX_MSG_LEN overflow we're receiving a malformed message and should reject it outright instead of limiting the allocation length.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd be totally fine too, yea.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

encoding_len is a u16 so the range check or limiting of allocation against LN_MAX_MSG_LEN seems superfluous. You ok with just doing: Vec::with_capacity(((encoding_len - 1) / 8) as usize);?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! Right indeed. Sure, that works too, maybe with a comment noting its a u16.

// less the 1-byte encoding_type
let mut short_channel_ids = vec![];
let mut read_remaining = encoding_len - 1;
while read_remaining > 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not for _ in 0..(encoding_len - 1)/8?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! I'm still getting used to replacing c-style for loops with for in range haha


// Read short_channel_ids (8-bytes each), for the encoding_len
// less the 1-byte encoding_type
let mut short_channel_ids = vec![];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same two comments as above here and two lines down.

This adds the message structs and implements Readable and Writeable
traits for the standard gossip_queries messages.
This commit adds ser/deser fuzzers for five new structs in ln::msgs used
for gossip_queries.
@TheBlueMatt TheBlueMatt merged commit 343aacc into lightningdevkit:master Sep 14, 2020
@bmancini55 bmancini55 deleted the gossip_queries branch September 14, 2020 20:54
TheBlueMatt added a commit that referenced this pull request Sep 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants