-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Tracking: P2P #64
Comments
Love the API proposed that uses AsyncRead/Write.
Same Q as above re: server refactor, if we do it from scratch, do you think we could build directly for such an API?
Great!
Do you mean like builder pattern? We can either do it manually, or for simple structs use something like https://docs.rs/derive_builder/latest/derive_builder/. Same for your
Didn't exactly understand what you mean here. cc @mattsse who's had thoughts on p2p.
Why does
Any reason not to? Any tradeoff here?
Makes a lot of sense.
^This is a sick doc.
Yep, makes sense. How does Akula do it?
How do you envision this to be exposed? Any changes you'd make vs how Akula does it, or how the so-far
What kind of discovery mechanisms?
Sorry, I misunderstood. Do you mean exposing the This proceeds to send a new fork choice to the Headers Stage receiver which will get consumed like this. Effectively CL calls Engine API, which triggers new HEAD which triggers EL to send Does that make sense? |
this is a great summary @Rjected
perhaps this is not even necessary if we have an ECIESStream codec https://docs.rs/tokio-codec/latest/tokio_codec/ and use the https://docs.rs/tokio-codec/latest/tokio_codec/struct.Framed.html adapter which automatically gives us AsyncRead+Write Serverthis pattern is pretty common:
CLientthis probably similar to the server but reversed. for the tech stack, we should look closely at tower's Service trait: https://docs.rs/tower/latest/tower/trait.Service.html which is a request -> response function. re @gakonst qs
not really, For |
No blockers, just hoping to get some input on the designs. A clean write would definitely let me build these APIs.
Yes
Interesting, that would be useful. Yeah, more referring to something like the builder pattern.
Since we need to handle the
Because a
I don't think there's any reason not to (unless anyone else can think of anything) especially if we provide a request/response API to other components
They have something similar here
Overall, I like the idea of splitting things up by interface (e.g.
Ah yeah that makes sense. The links are very helpful, thanks! |
What we needDiscovery stack
Devp2p stack
Server half (incoming connections)
Client half (outgoing connections)
@Rjected a RLPx session is symmetrical, so there's no distinction between client/server peer, right? So outgoing + incoming connections should look the same. Plugging everything together:Looks like we have 3 big parts:
2 + 3 should produce the same thing, a TerminologyThis can get confusing really quick. Proposing some terms: Swarm: Contains the state of the network and can be used to alter (e.g. adding peers manually). This will essentially be the user-facing API. Node/Peer: Any peer that implements the devp2p protocol (Connection)Pool: manages a set of connections struct Swarm {
incoming // A Stream type that produces "incoming connections"
pool // manages active nodes, basically just keeps track of background tasks for the sessions, since sessions are separate task they should have a channel back to the pool so `pool <-> sessions` can exchange info, for example for notifying if session closed
}
// this is effectively the main event loop
Stream for Swarm {
type Item = Event; // Some event type this stream produces
fn next() {
// 1. poll `incoming` stream that also yields an event
// somethings needs to handle this new connection and decided what to do with it, for example, reject if spammer etc. or establish a connection
// 2. pool manages established connections: spawn session with attached channel
}
} these are just my initial ideas, peer sessions are probably pretty self contained. |
makes sense
yes |
Part 1, the encrypted connection is done in #80. |
Wire protocol complete in #82 |
this has been completed. Follow-up via individual issues on specific topics. |
P2P Networking proposal and tracking
RLPx Peer Connection
The RLPx peer connection should implement framed encryption as specified by RLPx.
Client
The ECIES transport should implement
AsyncRead
andAsyncWrite
, so thep2p
connection can use it.Long term, it would be nice to interact with framed encryption like this (similar to TLS libraries):
High priority tasks:
AsyncRead
onECIESStream<Io>
AsyncWrite
onECIESStream<Io>
Lower priority:
ECIESStream<Io>
to support the above UX.Server
The RLPx Server should also work with any transport that implements
AsyncRead
andAsyncWrite
.Longer term, it should be possible to serve RLPx like this:
Low priority tasks:
accept
pattern onECIESStream
for an arbitraryIo
that implementsAsyncRead
andAsyncWrite
.p2p
Peer ConnectionThe RLPx peer connection will contain a server and client portion, and will take care of capability negotiation (the
p2p
capability), pings, and disconnects.Both the client and server should be capable of working with a type that implements
AsyncRead
andAsyncWrite
, meaning the transport does not need to implement framed encryption.This makes it slightly easier to test, since it would not require creating an
ECIESStream
.Client
We should be able to do something roughly similar to the above designs, but we need an extra task to handle driving the
p2p
state.This is roughly inspired by the design of
hyper
'sclient::conn
.Tasks:
Server
This is roughly inspired by the design of
hyper
'sserver::conn
.Tasks:
P2PServer
eth
Peer ConnectionThis contains a client and server, just like the RLPx and
p2p
connection.Instead of a
p2p
handshake, both ap2p
andeth
handshake are performed.Client
Tasks:
EthConfig
EthStream
Server
The
eth
server will wait for incoming connections and stream incomingTasks:
EthServer
eth
Wire ProtocolWe need to provide RLP encoding and decoding for each of the
eth
protocol messages and each of the types they contain.RequestPair
typeStatus
(feat: add eth-wire #20)Once this is done, we can also create a
Message
type can be created that is the sum type of all the protocol messages.eth
Network abstractionFinally, the
Network
abstraction will integrate all of the above components to provide a reliable connection to a set of peers on the network.This will implement interfaces that other components (e.g. staged sync, txpool) will use.
The network abstraction will also integrate with discovery mechanisms and manage the discovery state.
This will act as a
Server
(aneth
server) if the user is able to accept incoming connections and will use discovery methods to create outgoing connections, which will yield a set ofEthStream
s.Current questions
How will we implement the Engine API? It prompts the execution layer to request blocks, which happens over
eth
p2p.It could also just use the API provided by the
Network
abstraction.The text was updated successfully, but these errors were encountered: