-
Notifications
You must be signed in to change notification settings - Fork 134
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
feat: implement ping extensions #1616
base: master
Are you sure you want to change the base?
Conversation
5febe0e
to
efd0328
Compare
6b46f62
to
d416970
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First pass, mostly thoughts on layout / docstrings. IIUC this is a breaking change, right? If so, what's the rollout plan?
assert_eq!(client_info, decoded); | ||
} | ||
|
||
#[test] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like you could use rstest for these fail cases, and just add inline comments to the individual cases explaining why they should fail
} | ||
} | ||
|
||
impl From<BasicRadius> for CustomPayload { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a fairly simple type, but I still feel like we should have some pass/fail test cases for type_1
& type_2
* type_65535
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a few test cases let me know if you want any specific test I didn't think of
pub mod decode; | ||
pub mod extensions; | ||
|
||
use ssz::Decode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Idk... this is a bit of a nitpick, bc I'm pretty sure we're not consistent with this throughout the codebase, but personally i'm not a fan of having logic/defining types inside the mod.rs
file. Imo, it makes navigation more difficult. eg. when the logic is in a specified module, then I know exactly where to go to see the source.
Same comment applies to your file change -> overlay/service/mod.rs
. I'd rather see that logic in a named module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment applies to your file change -> overlay/service/mod.rs. I'd rather see that logic in a named module
I can move the impl out of mod, but I think the struct must stay in mod or the impl wouldn't be able to access the structs private with doing pub to all them
I think the struct has to go in mod yeah
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to split the impl across files, I think the struct must be in the mod, or it becomes very messy and asks me to make the struct's contents public.
If you have an idea which works where we could cleanly do this let me know
let parts: Vec<&str> = string.split('/').collect(); | ||
|
||
if parts.len() != 4 { | ||
bail!("Invalid client info string: should have 4 /'s {}", string); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would also include how many parts were actually found in the string (parts.len()
)
use ethportal_api::types::ping_extensions::Extensions; | ||
|
||
pub trait PingExtension { | ||
fn is_supported(&self, extension: Extensions) -> bool; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
docstring this and & raw_extensions
|
||
/// Returns the newest extension that is supported by both clients, used for extended ping | ||
/// responses. | ||
fn newest_commonly_supported_base_extension( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick latest_mutually_supported_base_extension
types::node::Node, | ||
}; | ||
|
||
impl< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docstring
Yes
Currently our protocol doesn't have a way to deal with this, hopefully we define something in the specification soon! So I think it is shipping breaking code, and I really want a defined way for shipping breaking change to the network 😭 |
@njgheorghita ready for another review |
596bde7
to
259dcaa
Compare
259dcaa
to
d12c90a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Mostly nits. Though, I'd say this is blocked for merging until we get at least fluffy (and probably ultralight as well, since it sounds like they're not that far away) up to spec, and then we'll coordinate the release together
|
||
fn try_from(value: CustomPayload) -> Result<Self, Self::Error> { | ||
CustomPayloadExtensionsFormat::from_ssz_bytes(&value.payload) | ||
.map_err(|e| anyhow::anyhow!("Failed to decode CustomPayloadExtensionsFormat: {:?}", e)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit use the var inside the string. though, this is the kind of nit I would expect clippy to pick up? seems like the rule is enabled https://github.com/ethereum/trin/blob/master/crates/ethportal-api/src/lib.rs#L5C1-L5C40 ... maybe clippy's structure isn't compatible/needs updating with the new crates/
layout?
also another nit importanyhow::anyhow
at the top rather than importing it here
let capabilities = | ||
ClientInfoRadiusCapabilities::from_ssz_bytes(&ping_custom_payload.payload) | ||
.map_err(|err| { | ||
anyhow::anyhow!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same with the anyhow
import in this file
portal_wire::CustomPayload, | ||
}; | ||
|
||
/// Used to response to pings which the node can't handle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit Used to respond to ...
extensions: &[Extensions], | ||
) -> Option<Extensions>; | ||
|
||
/// Returns the extensions by there u16 type id that are supported by the clients subnetwork. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit Returns the extensions by their u16...
) | ||
.await; | ||
let command_tx = | ||
OverlayService::<TContentKey, TMetric, TValidator, TStore, TPingExtensions>::spawn( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jeez, this probably needs some refactoring at some point
protocol = %self.protocol, | ||
request.source = %source, | ||
request.discv5.id = %request_id, | ||
"Received invalid Ping message, Error's should only be received from pong", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit Errors...
@@ -9,10 +9,10 @@ use discv5::enr::{CombinedKey, Enr, NodeId}; | |||
use ethportal_api::{ | |||
types::network::Network, | |||
utils::bytes::{hex_decode, hex_encode}, | |||
version::APP_NAME, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm. While you're at it... git grep -i '\"trin\"'
reveals quite a few other places in the codebase where we just hardcode "trin"
, it could be a quick / worthwhile refactor to update those as well in a future pr, but it's nothing urgent / important.
types::node::Node, | ||
}; | ||
|
||
/// Implementation of the `OverlayService` for handing Ping and Pong Extension's. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit handling
& Extensions
warn!( | ||
protocol = %self.protocol, | ||
request.dest = %node_id, | ||
"Base extension wasn't implemented: {extension:?}, sending Capabilities instead this is a bug", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... sending Capabilities instead. This is a bug!
let _ = self.command_tx.send(OverlayCommand::Request(request)); | ||
} | ||
|
||
fn handle_capabilities( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I feel like there's some room for improvement in how this file is organized. It just seems a bit spaghetti-y to me. It's not a blocker for this pr, and tbh I don't have any good ideas off the top of my head (our overlay service is so spaghetti-y already that maybe there aren't any great options). But at the very least it seems like the last 3 methods in this file don't use the self
attribute, so maybe they would be better off somewhere else? IDK, leaving it up to you to evaluate.
What was wrong?
implements ethereum/portal-network-specs#348
How was it fixed?
by implementing it