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

Support multiple all eth protocol versions announced in HelloMessage #1101

Closed
mattsse opened this issue Jan 31, 2023 · 12 comments · Fixed by #1152
Closed

Support multiple all eth protocol versions announced in HelloMessage #1101

mattsse opened this issue Jan 31, 2023 · 12 comments · Fixed by #1152
Assignees
Labels
A-networking Related to networking in general C-enhancement New feature or request D-good-first-issue Nice and easy! A great choice to get started

Comments

@mattsse
Copy link
Collaborator

mattsse commented Jan 31, 2023

Describe the feature

as highlighted here:
https://t.me/paradigm_reth/1611

we're announcing support for eth66/67 by default in Hello but only check for a single version in the eth Status handshake.

if status.version != resp.version {
return Err(EthHandshakeError::MismatchedProtocolVersion {
expected: status.version,
got: resp.version,
}
.into())

the status message should also accept older versions if announced.

TODO

if we add this to Status directly, we can no longer derive Rlp
so perhaps we add a list of versions as a separate parameter to the handshake function

wdyt @Rjected

Additional context

No response

@mattsse mattsse added C-enhancement New feature or request S-needs-triage This issue needs to be labelled A-networking Related to networking in general D-good-first-issue Nice and easy! A great choice to get started and removed S-needs-triage This issue needs to be labelled labels Jan 31, 2023
@Rjected
Copy link
Member

Rjected commented Jan 31, 2023

I think this is because we always use EthVersion::Eth67 in the Default impl of Status:

impl Default for Status {
fn default() -> Self {
Status {
version: EthVersion::Eth67 as u8,
chain: Chain::Named(ethers_core::types::Chain::Mainnet),
total_difficulty: U256::from(17_179_869_184u64),
blockhash: MAINNET.genesis_hash(),

Instead, this should be selected depending on the highest version shared eth capability. Ideally this would be fully solved by #791 in a way that lets us preserve the current behavior, but for now, adding a parameter in handshake seems like the best solution

@mattsse
Copy link
Collaborator Author

mattsse commented Jan 31, 2023

Instead, this should be selected depending on the highest version shared eth capability.

for the handshake this should check that the version of the remote peer's Status message is supported.

@Rjected
Copy link
Member

Rjected commented Jan 31, 2023

for the handshake this should check that the version of the remote peer's Status message is supported.

right, yeah

@jinsankim
Copy link
Contributor

I'd like to take this one.

@jinsankim
Copy link
Contributor

Question: Do we need to send EthMessage per a list of versions? I think we should do but I don't have confidence.

// we need to encode and decode here on our own because we don't have an `EthStream` yet
// The max length for a status with TTD is: <msg id = 1 byte> + <rlp(status) = 88 byte>
let mut our_status_bytes = BytesMut::with_capacity(1 + 88);
ProtocolMessage::from(EthMessage::Status(status)).encode(&mut our_status_bytes);
let our_status_bytes = our_status_bytes.freeze();
self.inner.send(our_status_bytes).await?;

@onbjerg
Copy link
Member

onbjerg commented Feb 1, 2023

Thanks! I've assigned you to the issue. If you feel stuck, open up a draft PR with your questions and someone will help you. If you are prevented from solving the issue, let me know and I will unassign you 😄

As for your question, I will defer to @mattsse and @Rjected

@gakonst
Copy link
Member

gakonst commented Feb 3, 2023

A few questions:

  1. Does Geth announce support for multiple protocol versions too? Looks like yes, incl eth/68.
  2. Their handshake does not seem to take a protocol version, but the peer does have a negotiated version
  3. And it seems like they try to do a handshake for each version

So is the idea that since we don't support multiple protocols yet, we'd just "loosen" the check from "if our version is not the same as theirs" to "if our version is eth/67 and their version is eth/66 or eth/67 we still mark it as an OK handshake"?

(cc @Rjected @mattsse a bit confused)

@Rjected
Copy link
Member

Rjected commented Feb 3, 2023

So is the idea that since we don't support multiple protocols yet, we'd just "loosen" the check from "if our version is not the same as theirs" to "if our version is eth/67 and their version is eth/66 or eth/67 we still mark it as an OK handshake"?

yes, that's the short term fix, and the long term fix is supporting multiple protocol versions, which will look a lot like how geth does it.

@gakonst
Copy link
Member

gakonst commented Feb 3, 2023

But should we be announcing eth/66? We're not responding to GetNodeData for example, so won't that get us penalized?

Should we just not advertise support for eth/66, and properly do the multiple caps? Most of the network is on latest geth anyway, so they all have eth/67, I doubt that we'd lose a lot of peers that way?

@Rjected
Copy link
Member

Rjected commented Feb 3, 2023

Should we just not advertise support for eth/66, and properly do the multiple caps? Most of the network is on latest geth anyway, so they all have eth/67, I doubt that we'd lose a lot of peers that way?

After some research, I'm leaning much more toward implementing support for multiple capabilities, and don't think peers with eth/66, but not eth/67 are a significant share of the network. Looking at ethernodes, the most used version of geth is 1.10.25. The only older version with significant network share, 1.10.23, is at about 6%.

eth/67 was implemented in ethereum/go-ethereum#24093, around June of 2022, for 1.10.19. The PR even notes the following:

(3) OpenEthereum and Erigon stopped serving fast sync data already even at the expense of a protocol violation, eth67 is just catching up with the general direction

So most nodes should support eth/67

@gakonst
Copy link
Member

gakonst commented Feb 3, 2023

Yeah, so I think let's just stop advertising eth/66, and when we can prioritize, go for the multiple caps?

@jinsankim
Copy link
Contributor

Need feedback.

Alternative idea to original issue, passing a list of versions to handshake:

  • Could we overwrite SharedCapability::Eth.version, from UnauthedP2PStream.handshake(), to status.version?

Rationale to my alternative idea:

HDYT?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-networking Related to networking in general C-enhancement New feature or request D-good-first-issue Nice and easy! A great choice to get started
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants