-
Notifications
You must be signed in to change notification settings - Fork 64
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
Support configuring a different protocol id #154
Comments
Hey, I have no issues helping support waku. As you probably know, the I have a preference to avoid having configurations that allow users to become non-spec compliant. Also some users may tamper with the config and end up sending invalid packets. As far as I know, this is the only request to change the protocol-id and would therefore be the only use-case for this config. If more people require it, I think maybe we should consider adding the config as you've suggested. In the meantime, how do you feel about a compile-time feature? We could add a "waku" feature, which when set, sets the protocol-id to "d5waku". Let me know what you think |
This feature-flag could then also be used for various ad-hoc modifications you may need to make to the specification and code logic that may fall outside the regular user config |
Absolutely. Makes sense. If we change the
It is a possibility that I had in mind. We are doing it with compile-time defines in the Nim implementation of Discv5 (here). Cargo does not have "compile-time defines", so AFAIK the alternative is to use a compile-time feature. And set it to the I think it feels hackish just to tune the |
When you talk about users, are you thinking about the Lighthouse client users? Or projects that use this crate as a dependency?
With my suggestion to add a Discv5 configuration parameter, you could always use the default configuration of the rust-discv5 crate (with the
I understand that you don't want to add additional debug headaches. Me neither 😁 I see that packets are just dropped/marked as invalid if the //...
// Check the protocol id
if &static_header[..6] != PROTOCOL_ID.as_bytes() {
return Err(PacketError::HeaderDecryptionFailed);
}
// ... Keeping that logic, you should not see any interference. And you can continue assuming, what you said:
|
In my opinion, it should be the application (in your case, the lighthouse client, in my case rust_waku's node) responsible for configuring the |
I was thinking about this:
I think it happens the same with rust-libp2p's gossipsub, but they allow configuring a different protocol id via the Changing the protocol_id makes the protocol "diverge" from the Gossipsub spec, but enables other use cases (e.g., extend the protocol by wrapping the current implementation). What do you think? 🤔 |
There's a few things here. Let me try and be thorough in my current thought process. Firstly. My terminology of users was referring to applications that use this crate, i.e Lighthouse, Waku, Portal etc, not the end user. So I fully agree that final end-users shouldn't be messing with the protocol-id, my argument was more that potentially projects also shouldn't be messing with the protocol-id, let me give some reasons in this reply. Firstly let me address some things you've raised:
Yeah a feature flag would look like that, and you could import discv5 with this feature.
Yep, this is the logic that causes some headaches. The messages are encrypted initially with the node-id you are sending a packet to. So when we receive a packet, it looks like junk, then we decrypt it, assuming it was sent to our node-id. Once decrypted, we can check to see if the decryption worked, we do this by looking for the magic bytes which are the protocol-id. If the protocol-id is not what we expect, then either the message is junk, there is an error in the packet format being sent, or it was encrypted with some other node-id and not meant for us. In the current implementation we can't tell the difference between these cases. Modifying the protocol-id is one way to segregate nodes from communicating with each other. You brought up libp2p-gossipsub. So this protocol is entirely different and the protocol-id there is used in libp2p's multistream select, which is more-or-less designed to be configurable to identify capabilities of a node. The libp2p gossipsub specs are very quite light: https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.0.md and do not specify the protocol-id. It has been known amongst implementors that the true specification is the go implementation of gossipsub. Another important difference with gossipsub, is that its not desired to have multiple applications using the one gossipsub network. For this reason, I had added a configurable parameter in the gossipsub configuration called the protocol-id prefix, which prefixed the "meshsub" protocol-id allowing applications to segregate themselves on the gossipsub network. There were some issues about this amongst implementors and it was agreed as a reasonable thing to do in libp2p to customise the protocol-id. So because the specification there is more based on the implementation, and as far as I know there is no specification that fixes it to a specific value, it's apart of the specification to customize it. Recently, another user wanted to customise the entire protocol-id, which will break the protocol in some weird ways (as we need to identify different versions of gossipsub nodes on the network). I highlight the issues here: libp2p/rust-libp2p#2718 (review) but in the end decided it would be fine if that user wanted to keep the nodes on the same version across the network. Going back to discv5. The wire-protocol specifications explicitly state the bytes that the protocol-id should be (unlike the gossipsub "specs"). I'm not the author of the discv5 specs, but as I understand the reason for this, is that it is desired use of discv5 is to build a giant DHT of many many nodes from all applications. For kad-like protocols, the larger the network, the more secure. Therefore, I think the goal of discv5 is for all applications to use the one DHT, which is probably why modifying the I understand the initial desire to form your own DHT as it can be faster to find nodes that advertise a particular capability (i.e waku nodes). There has been a bunch of research of how best to do this over a very large DHT with many applications. A paper has been written on how to implement "topics" for faster searches of this kind: https://github.com/harnen/service-discovery-paper . We have made some initial implementations of this here: #126 Another way to segregate DHTs is to use this: https://github.com/sigp/discv5/blob/master/src/config.rs#L61. I originally added this for Ethereum, but decided against its use due to the security risks of a decreased DHT size. In ethereum we add an In the end, I think the general idea is that all applications should use the one DHT and therefore keep everything "to-spec". Making the I'd be curious to here @fjl thoughts on this (being the primary author of discv5). |
@LNSD - You can ignore the essay above ^ :p. I had a quick chat with @fjl. As I understand the go-implementation now allows the protocol-id to be customized and most of my concerns about the intention of the spec are probably exaggerated. If other nodes are customising this, then makes sense that we should too. So lets make the config 🎉 |
I agree with the spirit of @AgeManning's post. Customizing the protocol-id is not intended by the spec. However, I decided to accept the feature in go-ethereum because it can be useful during development or for experiments. |
Thanks for such an elaborate answer. It was very helpful to understand your concerns.
Great! In the following days, I will go through the discv5's P.S. I was aware of the libp2p's Gossipsub |
Initially, my idea was to extract the serialization logic into a codec. But with the current code layout, it gets too complicated. So I opted for a "surgical" change, consisting of passing the protocol id down the call stack until reaching the Please, check PR #157, and let me know your thoughts. |
Closing this issue as #158 got merged |
Background
I am working on rust-waku and, more precisely, on the 33/WAKU2-DISCV5 RFC implementation.
The reference implementation, the Nim implementation (nwaku), of the Waku discv5 node discovery mechanism uses a different protocol ID for convenience. This is
d5waku
.Description
Right now, in v0.1.0, the
PROTOCOL_ID
is hardcoded:https://github.com/sigp/discv5/blob/v0.1.0/src/packet/mod.rs#L32-L33
To make rust-waku compatible with the Waku reference implementation, I would like to add support to configure the protocol ID (similar to what rust-libp2p does with the Gossipsub protocol).
Acceptance criteria
protocol_id
field toDiscv5Config
. The default value must be"discv5"
protocol_id
function to theDiscv5ConfigBuilder
.protocol_id
field topacket::{Packet, PacketHeader}
.packet::Packet
codec logic to support checking the message validity against non-constant (non-static) values.The text was updated successfully, but these errors were encountered: