Skip to content

refactor(p2p)!: Extract TCP transport#4148

Merged
melekes merged 9 commits intomainfrom
2128-quic-go
Oct 24, 2024
Merged

refactor(p2p)!: Extract TCP transport#4148
melekes merged 9 commits intomainfrom
2128-quic-go

Conversation

@melekes
Copy link
Collaborator

@melekes melekes commented Sep 21, 2024

Closes #4301

This PR refactors the peer-to-peer (p2p) module by extracting the TCP transport into its own component, laying groundwork for potential QUIC transport integration. It introduces a breaking change to the Go API, particularly in the handling of peer connections and transport interfaces.

Important: no logic has been changed; just moving stuff and updating interfaces.

Changes

Public API

  • Updated Transport interface
// Transport emits and connects to Peers. The implementation of Peer is left to
// the transport. Each transport is also responsible to filter establishing
// peers specific to its domain.
type Transport interface {
	// NetAddr returns the network address of the local node.
	NetAddr() na.Addr

	// Accept waits for and returns the next connection to the local node.
	Accept() (net.Conn, *na.Addr, error)

	// Dial dials the given address and returns a connection.
	Dial(addr na.Addr) (net.Conn, error)

	// Cleanup any resources associated with the given connection.
	//
	// Must be run when the peer is dropped for any reason.
	Cleanup(conn net.Conn) error
}

New Go packages (extracted from p2p)

  • netaddress - network address
  • nodeinfo - node's info
  • nodekey - ID of the node
  • transport/tcp - TCP transport

Internalized Go packages

  • fuzz - fuzzing connection

#go-api-breaking

@melekes melekes self-assigned this Sep 21, 2024
@melekes melekes added p2p breaking A breaking change labels Sep 22, 2024
@cason
Copy link

cason commented Sep 26, 2024

A general fast comment here: if we don't rename GetChannels() reactor's method and the type that stores it, we have much less changes and maybe is not (that) API breaking?

@github-actions
Copy link

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@github-actions github-actions bot added stale For use by stalebot and removed stale For use by stalebot labels Oct 13, 2024
@faddat
Copy link
Contributor

faddat commented Oct 15, 2024

thanks!

@melekes
Copy link
Collaborator Author

melekes commented Oct 17, 2024

A general fast comment here: if we don't rename GetChannels() reactor's method and the type that stores it, we have much less changes and maybe is not (that) API breaking?

It will be API-breaking anyway because I had to extract many packages. But if you think the renaming is unjustified, I can revert it to the "channels" concept.

@melekes melekes marked this pull request as ready for review October 17, 2024 18:41
@melekes melekes requested review from a team as code owners October 17, 2024 18:41
@melekes melekes requested a review from a team October 17, 2024 18:41
@melekes melekes added the hygiene Any work relating to code legibility/hygiene to make it easier to read label Oct 18, 2024
Copy link
Collaborator

@andynog andynog left a comment

Choose a reason for hiding this comment

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

Overall looks good to me. Made some comments and suggestions. Also ran a few tests. Good job. 👍


// GetChannels implements Reactor.
func (*Reactor) GetChannels() []*p2p.ChannelDescriptor {
// StreamDescriptors implements Reactor.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was just trying to understand the semantics for the naming difference, why the ChannelDescriptor changed to StreamDescriptor. Looking at some related code, eg. in node/node.go CustomReactors seems there's a mixing of these semantics like

	for _, chDesc := range reactor.StreamDescriptors() {
					if !ni.HasChannel(chDesc.StreamID()) {
						ni.Channels = append(ni.Channels, chDesc.StreamID())
					}
				}

Just want to understand the difference between channels and streams

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So, "channel" is what we were using before, but I don't know where this naming concept is coming from. Channels are not mentioned anywhere in TCP or multiplexed TCP.

Where's in QUIC, there's a direct concept of data streams. Hence, I've decided to change the name.

p2p/peer.go Outdated

return cmtconn.NewMConnectionWithConfig(
// filter out non-tcpconn.ChannelDescriptor streams
chDescs := make([]*tcpconn.ChannelDescriptor, 0, len(streams))
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we pre-allocate capacity here? I'm wondering if most of the streams will be non-tcpconn, then maybe we don't pre-allocate. The GC will eventually kick-in but just a suggestion if it makes sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This part will be refactored out later :)

)
}

func wrapPeer(c net.Conn, ni ni.NodeInfo, cfg peerConfig, socketAddr *na.NetAddress, mConfig tcpconn.MConnConfig) Peer {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you please add some context here ? e.g. comments why wrapPeer? I tried to check with the logic in the switch acceptRoutine and it seems this method changes the logic a little bit, I couldn't find logic related to persistence check in the previous acceptRoutine, having additional comments may provide more context for that. Thanks.

if err != nil {
return nil, err
}

Copy link
Collaborator

Choose a reason for hiding this comment

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

just noticed that in the previous file, there was a cfg parameter and the outbound was set. I'm assuming this is not needed or was removed on purpose but just wanted to highlight here

cfg.outbound = true

@melekes melekes added this pull request to the merge queue Oct 24, 2024
Merged via the queue into main with commit eef3464 Oct 24, 2024
@melekes melekes deleted the 2128-quic-go branch October 24, 2024 05:34
@tac0turtle
Copy link
Contributor

nice job!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking A breaking change hygiene Any work relating to code legibility/hygiene to make it easier to read p2p

Projects

None yet

Development

Successfully merging this pull request may close these issues.

p2p: extract TCP transport to a separate package

5 participants