Skip to content
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

ProtocolId re-work #3980

Closed
realbigsean opened this issue Feb 15, 2023 · 10 comments
Closed

ProtocolId re-work #3980

realbigsean opened this issue Feb 15, 2023 · 10 comments

Comments

@realbigsean
Copy link
Member

realbigsean commented Feb 15, 2023

Description

ProtocolId contains a single Version enum for all protocols, this doesn't really make sense though because protocols are versioned independently. Places where this isn't great include #3972 where we want a complete match across protocol + version, but currently this means matching on protocol + version combinations that don't actually exist, e.g. LightClientBootstrap + Version::V2. Also handle_v1_response the handle_v2_response end up being very confusing to work with because some v1 protocols end up having functionality more similar to v2 protocols (e.g. fork-awareness in the blobs by range v1 protocol is almost the same as fork-awareness in blocks by range v2 protocol and very unlike the blocks by range v1 protocol) but have to be handled independently.

Options:

  • Add variants per-version to Protocol. Maximally strict but maybe makes the most sense.
enum Protocol {
    MetadataV1,
    MetadataV2,
...
}
  • Nest version enums inside each protocol. More verbose, but more flexible
enum Protocol {
    Metadata(MetadataVersion),
    BlocksByRange(BlocksByRangeVersion),
...
}
@winksaville
Copy link
Contributor

Is there any interest in solving this on a wider scale. In particular I'd like to be able to uniquely identify items in an agnostic way. The minimum set of groupings I see are:

  • Messages
  • Protocols - a set of messages
  • ProtocolSets - a set of protocols

Each would have a unique identifier and semver. Again, these should be defined in a "language" and "platform" agnostic manner so as to be maximally portable.

@realbigsean
Copy link
Member Author

@divagant-martian @AgeManning what do you guys think?

@divagant-martian
Copy link
Collaborator

Thanks @realbigsean and @winksaville

Is there any interest in solving this on a wider scale. In particular I'd like to be able to uniquely identify items in an agnostic way. The minimum set of groupings I see are:

* Messages

* Protocols - a set of messages

* ProtocolSets - a set of protocols

The ProtocolId is an internal model used for protocol negotiation with other peers, so this issue is more of a code quality one than an API one. In this sense I don't think we will be adding a higher hierarchy (ProtocolSets)

Each would have a unique identifier and semver. Again, these should be defined in a "language" and "platform" agnostic manner so as to be maximally portable.

We already model messages as the individual chunks received per protocol and don't support protocols depending on language or platform

ProtocolId contains a single Version enum for all protocols, this doesn't really make sense

Yeah agree, let's change this

@divagant-martian divagant-martian added the good first issue Good for newcomers label Feb 15, 2023
@winksaville
Copy link
Contributor

winksaville commented Feb 15, 2023

I believe I understand there is one Protocol with a set of messages identified by:

/// Protocol names to be used.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Protocol {
/// The Status protocol name.
Status,
/// The Goodbye protocol name.
Goodbye,
/// The `BlocksByRange` protocol name.
BlocksByRange,
/// The `BlocksByRoot` protocol name.
BlocksByRoot,
/// The `Ping` protocol name.
Ping,
/// The `MetaData` protocol name.
MetaData,
/// The `LightClientBootstrap` protocol name.
LightClientBootstrap,
}

I was thinking there were many protocols and many combinations of messages.

@divagant-martian
Copy link
Collaborator

divagant-martian commented Feb 16, 2023

That's the Protocol enum that we use to identify which of the different 7 protocols is in use. Messages are handled per request, you can check the InboundRequest and OutboundRequest to check what messages are sent in each. We might be referring to "Protocol" to different things

@winksaville
Copy link
Contributor

SG, txs.

I think we have similar models in mind. Your enum Protocol I call a ProtocolSet. It's a set of Protocols like "Status", "Goodbye", ... and then each of those protocols defines a small set of request/response messages. Because I envision many ProtocolSets there will be a semver, but since you have only one ProtocolSet, I too agree semver is not necessary.

@PatStiles
Copy link

I'm interested in taking this on if it hasn't already been taken by @winksaville

@winksaville
Copy link
Contributor

I won't have time, please take it on!

@AgeManning
Copy link
Member

My 2 cents on this topic is:
Libp2p doesn't distinguish between any of the abstract values we've added (i.e protocol, version, encoding, string_prefix). It just cares about matching random bytes. So if our abstraction is causing pain, we should modify the abstraction a little.

At the moment, we only really use one encoding, we removed the support of plain ssz. So currently there is pain matching on just protocol and version, and I assume not for the encoding.

We build a list of supported protocols using the raw abstract types (Protocol, Version, Encoding) which we advertise to our peers. I think it might be nicer then, to create a new abstract enum called SupportedProtocol which contains all the variants that are supported (I know some can be turned off/on at runtime but the matching pattern will no longer have crazy variants as described in this issue).

Then when building the supported protocols here:

let mut supported_protocols = vec![

We could use this enum, i..e SupportedProtocol::currently_supported(info: RPCProtocol) and we could implement something like:

impl ProtocolId {
   fn supported_protocol(&self) -> SupportedProtocol { .. }
   }

So when we are checking the match, we convert the raw ProtocolId into a SupportedProtocol and match on that to avoid any non-existent variant.

bors bot pushed a commit that referenced this issue Jun 14, 2023
## Issue Addressed

Resolves #3980. Builds on work by @GeemoCandama in #4084 

## Proposed Changes

Extends the `SupportedProtocol` abstraction added in Geemo's PR and attempts to fix internal versioning of requests that are mentioned in this comment #4084 (comment) 

Co-authored-by: geemo <geemo@tutanota.com>
@divagant-martian
Copy link
Collaborator

This can be closed now

ghost pushed a commit to oone-world/lighthouse that referenced this issue Jul 13, 2023
## Issue Addressed

Resolves sigp#3980. Builds on work by @GeemoCandama in sigp#4084 

## Proposed Changes

Extends the `SupportedProtocol` abstraction added in Geemo's PR and attempts to fix internal versioning of requests that are mentioned in this comment sigp#4084 (comment) 

Co-authored-by: geemo <geemo@tutanota.com>
Woodpile37 pushed a commit to Woodpile37/lighthouse that referenced this issue Jan 6, 2024
Resolves sigp#3980. Builds on work by @GeemoCandama in sigp#4084

Extends the `SupportedProtocol` abstraction added in Geemo's PR and attempts to fix internal versioning of requests that are mentioned in this comment sigp#4084 (comment)

Co-authored-by: geemo <geemo@tutanota.com>
Woodpile37 pushed a commit to Woodpile37/lighthouse that referenced this issue Jan 6, 2024
Resolves sigp#3980. Builds on work by @GeemoCandama in sigp#4084

Extends the `SupportedProtocol` abstraction added in Geemo's PR and attempts to fix internal versioning of requests that are mentioned in this comment sigp#4084 (comment)

Co-authored-by: geemo <geemo@tutanota.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants