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

Add discv5 #72

Merged
merged 24 commits into from
Jan 2, 2025
Merged

Add discv5 #72

merged 24 commits into from
Jan 2, 2025

Conversation

diegomrsantos
Copy link

@diegomrsantos diegomrsantos commented Dec 13, 2024

Issue Addressed

Add discv5 and partially implement #35.

Proposed Changes

  • Updated the discv5 dependency from version 0.8.0 to 0.9.0.
  • Added a new CLI argument boot_nodes_enr for specifying base64-encoded ENRs to bootstrap the p2p network.
  • Enhanced the configuration handling to include the new boot_nodes_enr argument and parse it correctly.
  • Introduced the Discovery module to handle peer discovery using the discv5 protocol.
  • Modified the network behavior to integrate the Discovery module, enabling peer discovery and connection management.
  • Added a configuration option disable_discovery to control the activation of the discovery protocol.

Additional Info

  • This is mostly copying the discovery code from LH for now while we figure out the best way to modularise and reuse this code.
  • This is the first step toward a full discovery implementation. More features must be added, like saving ENRs to the database.

EventStream::InActive
};

if !network_config.boot_nodes_multiaddr.is_empty() {
Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Author

@diegomrsantos diegomrsantos Dec 17, 2024

Choose a reason for hiding this comment

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

Or maybe we should accept a UDP MA for discv5

@diegomrsantos diegomrsantos marked this pull request as ready for review December 17, 2024 12:12
@diegomrsantos
Copy link
Author

I removed the hardcoded bootnode ENR. It's possible to use the holesky bootnode running: run --package anchor --bin anchor -- --boot-nodes-enr=enr:-Li4QFIQzamdvTxGJhvcXG_DFmCeyggSffDnllY5DiU47pd_K_1MRnSaJimWtfKJ-MD46jUX9TwgW5Jqe0t4pH41RYWGAYuFnlyth2F0dG5ldHOIAAAAAAAAAACEZXRoMpD1pf1CAAAAAP__________gmlkgnY0gmlwhCLdu_SJc2VjcDI1NmsxoQN4v-N9zFYwEqzGPBBX37q24QPFvAVUtokIo1fblIsmTIN0Y3CCE4uDdWRwgg-j

Copy link
Member

@jxs jxs left a comment

Choose a reason for hiding this comment

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

Thanks for starting this Diego! Left some comments, mainly I think we should not merge commented instructions without proper explaining on the why

// TODO handle other behaviour events
_ => {
log::debug!("Unhandled behaviour event: {:?}", behaviour_event);
}
},
// TODO handle other swarm events
SwarmEvent::NewListenAddr { .. } => {},
Copy link
Member

Choose a reason for hiding this comment

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

this isn't required for now right?

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, removed.

// Build and start the discovery sub-behaviour
let mut discovery = Discovery::new(local_keypair.clone(), network_config)
.await
.unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

nit, either:

Suggested change
.unwrap();
.expect("Discovery should be able to start");

or ? to bubble up the error and treat it in the function caller

Copy link
Author

@diegomrsantos diegomrsantos Dec 17, 2024

Choose a reason for hiding this comment

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

we'll need to refactor the function and return a Result instead.

Copy link
Author

Choose a reason for hiding this comment

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

Could we create an issue and address it in a new PR?

Copy link
Member

Choose a reason for hiding this comment

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

yeah ofc :)

Copy link
Author

Choose a reason for hiding this comment

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

#75

global = true,
value_delimiter = ',',
help = "One or more comma-delimited base64-encoded ENR's to bootstrap the p2p network",
display_order = 0
Copy link
Member

Choose a reason for hiding this comment

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

We can declare the default boot nodes somewhere (like anchor/network/src/config.rs) with:

const DEFAULT_BOOTNODES: [&'static str; 3] = ["ENR1", "ENR2", "ENR3"];

and then import it and use it here:

Suggested change
display_order = 0
display_order = 0
default_values_t = DEFAULT_BOOTNODES.into_iter().map(Into::into)

Copy link
Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

yeah can also be, but then we should get them by default, if you prefer it can be done in a subsequent PR

Copy link
Author

Choose a reason for hiding this comment

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

Yes, it's probably better in another PR.

}

// Start the discv5 service and obtain an event stream
let event_stream = if !network_config.disable_discovery {
Copy link
Member

Choose a reason for hiding this comment

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

will we want to disable discovery? cc @Age @jking-aus

Copy link
Member

Choose a reason for hiding this comment

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

hmm not sure. It is mainly used in testing, where you can set the bootnodes and only connect to that node. It is kinda handy. Maybe worth keeping

Comment on lines 98 to 101
// TODO info!(log, "ENR Initialised"; "enr" => local_enr.to_base64(), "seq" => local_enr.seq(), "id"=> %local_enr.node_id(),
// "ip4" => ?local_enr.ip4(), "udp4"=> ?local_enr.udp4(), "tcp4" => ?local_enr.tcp4(), "tcp6" => ?local_enr.tcp6(), "udp6" => ?local_enr.udp6(),
// "quic4" => ?local_enr.quic4(), "quic6" => ?local_enr.quic6()
// );
Copy link
Member

Choose a reason for hiding this comment

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

this can be removed right?

Copy link
Author

Choose a reason for hiding this comment

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

We probably need a local_enr, but I don't understand how it works yet.

Copy link
Author

Choose a reason for hiding this comment

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

Added a TODO

Comment on lines +118 to +121
// TODO if bootnode_enr.node_id() == local_node_id {
// // If we are a boot node, ignore adding it to the routing table
// continue;
// }
Copy link
Member

Choose a reason for hiding this comment

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

is anchor planned to also be run as bootnode? If so this can be uncommented right?

Copy link
Author

Choose a reason for hiding this comment

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

Waiting for input here as I don't know the answer

Copy link
Contributor

Choose a reason for hiding this comment

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

I think so yep -- would be good to be able to provide anchor based bootnodes so not reliant on the go client for entrypoints

anchor/network/src/discovery.rs Outdated Show resolved Hide resolved
anchor/network/src/discovery.rs Outdated Show resolved Hide resolved
}
}

impl NetworkBehaviour for Discovery {
Copy link
Member

Choose a reason for hiding this comment

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

this can probably be moved into upstream discv5 feature gated by libp2p (like the enr crate does) as its shared by both lighthouse and anchor wdyt @AgeManning

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, thats a good idea

Copy link
Member

Choose a reason for hiding this comment

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

oh except the types might be annoying. The NetworkBehaviour and libp2p traits, will come from the upstream libp2p dependency and then this won't work if Anchor sets its own libp2p version.

i.e We will have to always be doing releases for discv5 to keep up to libp2p, which could get annoying

Copy link
Member

Choose a reason for hiding this comment

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

the NetworkBehaviour traits (which they all depend) are contained in libp2p-swarm which updates roughly once a year, the last update to 0.45 was due to the Transport trait update. There isn't an update like that in sight wrt that I think we are ok

Comment on lines +421 to +444
// Add QUIC fields to the ENR.
// Since QUIC is used as an alternative transport for the libp2p protocols,
// the related fields should only be added when both QUIC and libp2p are enabled
if !config.disable_quic_support {
// If we are listening on ipv4, add the quic ipv4 port.
if let Some(quic4_port) = config.enr_quic4_port.or_else(|| {
config
.listen_addresses
.v4()
.and_then(|v4_addr| v4_addr.quic_port.try_into().ok())
}) {
builder.add_value(QUIC_ENR_KEY, &quic4_port.get());
}

// If we are listening on ipv6, add the quic ipv6 port.
if let Some(quic6_port) = config.enr_quic6_port.or_else(|| {
config
.listen_addresses
.v6()
.and_then(|v6_addr| v6_addr.quic_port.try_into().ok())
}) {
builder.add_value(QUIC6_ENR_KEY, &quic6_port.get());
}
}
Copy link
Member

Choose a reason for hiding this comment

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

the spec only mentions TCP as a transport, and the go ssv client doesn't seem to support it, do we plan to support it nonetheless?

Copy link
Author

@diegomrsantos diegomrsantos Dec 17, 2024

Choose a reason for hiding this comment

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

We could support QUIC for communication between rust nodes.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, lets support it, and hopefully they follow suit

Copy link
Member

Choose a reason for hiding this comment

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

ok nice! Then we should probably create a PR upstream to manifest that

Copy link
Contributor

@jking-aus jking-aus left a comment

Choose a reason for hiding this comment

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

one small change then let's merge

anchor/network/src/network.rs Outdated Show resolved Hide resolved
anchor/network/src/network.rs Outdated Show resolved Hide resolved
Co-authored-by: jking-aus <72330194+jking-aus@users.noreply.github.com>
diegomrsantos and others added 2 commits December 23, 2024 12:56
Co-authored-by: jking-aus <72330194+jking-aus@users.noreply.github.com>
@jking-aus jking-aus merged commit e15bdb4 into sigp:unstable Jan 2, 2025
9 checks passed
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.

4 participants