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

Rename Version message to Handshake #2479

Merged
merged 8 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions message/messages_benchmark_test.go
danlaine marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,29 @@ var (
dummyOnFinishedHandling = func() {}
)

// Benchmarks marshal-ing "Version" message.
// Benchmarks marshal-ing "Handshake" message.
//
// e.g.,
//
// $ go install -v golang.org/x/tools/cmd/benchcmp@latest
// $ go install -v golang.org/x/perf/cmd/benchstat@latest
//
// $ go test -run=NONE -bench=BenchmarkMarshalVersion > /tmp/cpu.before.txt
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalVersion > /tmp/cpu.after.txt
// $ go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.before.txt
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake > /tmp/cpu.after.txt
// $ benchcmp /tmp/cpu.before.txt /tmp/cpu.after.txt
// $ benchstat -alpha 0.03 -geomean /tmp/cpu.before.txt /tmp/cpu.after.txt
//
// $ go test -run=NONE -bench=BenchmarkMarshalVersion -benchmem > /tmp/mem.before.txt
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalVersion -benchmem > /tmp/mem.after.txt
// $ go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.before.txt
// $ USE_BUILDER=true go test -run=NONE -bench=BenchmarkMarshalHandshake -benchmem > /tmp/mem.after.txt
// $ benchcmp /tmp/mem.before.txt /tmp/mem.after.txt
// $ benchstat -alpha 0.03 -geomean /tmp/mem.before.txt /tmp/mem.after.txt
func BenchmarkMarshalVersion(b *testing.B) {
func BenchmarkMarshalHandshake(b *testing.B) {
require := require.New(b)

id := ids.GenerateTestID()
msg := p2p.Message{
Message: &p2p.Message_Version{
Version: &p2p.Version{
Message: &p2p.Message_Handshake{
Handshake: &p2p.Handshake{
NetworkId: uint32(1337),
MyTime: uint64(time.Now().Unix()),
IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()),
Expand Down Expand Up @@ -103,8 +103,8 @@ func BenchmarkUnmarshalVersion(b *testing.B) {

id := ids.GenerateTestID()
msg := p2p.Message{
Message: &p2p.Message_Version{
Version: &p2p.Version{
Message: &p2p.Message_Handshake{
Handshake: &p2p.Handshake{
NetworkId: uint32(1337),
MyTime: uint64(time.Now().Unix()),
IpAddr: []byte(net.IPv4(1, 2, 3, 4).To16()),
Expand Down
8 changes: 4 additions & 4 deletions message/messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ func TestMessage(t *testing.T) {
bytesSaved: false,
},
{
desc: "version message with no compression",
op: VersionOp,
desc: "Handshake message with no compression",
op: HandshakeOp,
msg: &p2p.Message{
Message: &p2p.Message_Version{
Version: &p2p.Version{
Message: &p2p.Message_Handshake{
Handshake: &p2p.Handshake{
NetworkId: uint32(1337),
MyTime: uint64(nowUnix),
IpAddr: []byte(net.IPv6zero),
Expand Down
30 changes: 15 additions & 15 deletions message/mock_outbound_message_builder.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions message/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
// Handshake:
PingOp Op = iota
PongOp
VersionOp
HandshakeOp
PeerListOp
PeerListAckOp
// State sync:
Expand Down Expand Up @@ -71,7 +71,7 @@ var (
HandshakeOps = []Op{
PingOp,
PongOp,
VersionOp,
HandshakeOp,
PeerListOp,
PeerListAckOp,
}
Expand Down Expand Up @@ -209,8 +209,8 @@ func (op Op) String() string {
return "ping"
case PongOp:
return "pong"
case VersionOp:
return "version"
case HandshakeOp:
return "handshake"
case PeerListOp:
return "peerlist"
case PeerListAckOp:
Expand Down Expand Up @@ -303,8 +303,8 @@ func Unwrap(m *p2p.Message) (fmt.Stringer, error) {
return msg.Ping, nil
case *p2p.Message_Pong:
return msg.Pong, nil
case *p2p.Message_Version:
return msg.Version, nil
case *p2p.Message_Handshake:
return msg.Handshake, nil
case *p2p.Message_PeerList:
return msg.PeerList, nil
case *p2p.Message_PeerListAck:
Expand Down Expand Up @@ -362,8 +362,8 @@ func ToOp(m *p2p.Message) (Op, error) {
return PingOp, nil
case *p2p.Message_Pong:
return PongOp, nil
case *p2p.Message_Version:
return VersionOp, nil
case *p2p.Message_Handshake:
return HandshakeOp, nil
case *p2p.Message_PeerList:
return PeerListOp, nil
case *p2p.Message_PeerListAck:
Expand Down
8 changes: 4 additions & 4 deletions message/outbound_msg_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var _ OutboundMsgBuilder = (*outMsgBuilder)(nil)
// with a reference count of 1. Once the reference count hits 0, the message
// bytes should no longer be accessed.
type OutboundMsgBuilder interface {
Version(
Handshake(
networkID uint32,
myTime uint64,
ip ips.IPPort,
Expand Down Expand Up @@ -228,7 +228,7 @@ func (b *outMsgBuilder) Pong(
)
}

func (b *outMsgBuilder) Version(
func (b *outMsgBuilder) Handshake(
networkID uint32,
myTime uint64,
ip ips.IPPort,
Expand All @@ -245,8 +245,8 @@ func (b *outMsgBuilder) Version(
encodeIDs(trackedSubnets, subnetIDBytes)
return b.builder.createOutbound(
&p2p.Message{
Message: &p2p.Message_Version{
Version: &p2p.Version{
Message: &p2p.Message_Handshake{
Handshake: &p2p.Handshake{
NetworkId: networkID,
MyTime: myTime,
IpAddr: ip.IP.To16(),
Expand Down
12 changes: 6 additions & 6 deletions network/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,26 @@ In Avalanche, nodes connect to an initial set of bootstrapper nodes known as **b

Upon connection to any peer, a handshake is performed between the node attempting to establish the outbound connection to the peer and the peer receiving the inbound connection.

When attempting to establish the connection, the first message that the node attempting to connect to the peer in the network is a `Version` message describing compatibility of the candidate node with the peer. As an example, nodes that are attempting to connect with an incompatible version of AvalancheGo or a significantly skewed local clock are rejected by the peer.
When attempting to establish the connection, the first message that the node attempting to connect to the peer in the network is a `Handshake` message describing compatibility of the candidate node with the peer. As an example, nodes that are attempting to connect with an incompatible version of AvalancheGo or a significantly skewed local clock are rejected by the peer.

```mermaid
sequenceDiagram
Note over Node,Peer: Initiate Handshake
Note left of Node: I want to connect to you!
Note over Node,Peer: Version message
Note over Node,Peer: Handshake message
Node->>Peer: AvalancheGo v1.0.0
Note right of Peer: My version v1.9.4 is incompatible with your version v1.0.0.
Peer-xNode: Connection dropped
Note over Node,Peer: Handshake Failed
```

If the `Version` message is successfully received and the peer decides that it wants a connection with this node, it replies with a `PeerList` message that contains metadata about other peers that allows a node to connect to them. Upon reception of a `PeerList` message, a node will attempt to connect to any peers that the node is not already connected to to allow the node to discover more peers in the network.
If the `Handshake` message is successfully received and the peer decides that it wants a connection with this node, it replies with a `PeerList` message that contains metadata about other peers that allows a node to connect to them. Upon reception of a `PeerList` message, a node will attempt to connect to any peers that the node is not already connected to to allow the node to discover more peers in the network.

```mermaid
sequenceDiagram
Note over Node,Peer: Initiate Handshake
Note left of Node: I want to connect to you!
Note over Node,Peer: Version message
Note over Node,Peer: Handshake message
Node->>Peer: AvalancheGo v1.9.4
Note right of Peer: LGTM!
Note over Node,Peer: PeerList message
Expand All @@ -90,11 +90,11 @@ Some peers aren't discovered through the `PeerList` messages exchanged through p

```mermaid
sequenceDiagram
Node ->> Peer-1: Version - v1.9.5
Node ->> Peer-1: Handshake - v1.9.5
Peer-1 ->> Node: PeerList - Peer-2
Node ->> Peer-1: ACK - Peer-2
Note left of Node: Node is connected to Peer-1 and now tries to connect to Peer-2.
Node ->> Peer-2: Version - v1.9.5
Node ->> Peer-2: Handshake - v1.9.5
Peer-2 ->> Node: PeerList - Peer-1
Node ->> Peer-2: ACK - Peer-1
Note left of Node: Peer-3 was never sampled, so we haven't connected yet!
Expand Down
2 changes: 1 addition & 1 deletion network/peer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ type Config struct {
// Calculates uptime of peers
UptimeCalculator uptime.Calculator

// Signs my IP so I can send my signed IP address in the Version message
// Signs my IP so I can send my signed IP address in the Handshake message
IPSigner *IPSigner
}
38 changes: 19 additions & 19 deletions network/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ type peer struct {
// queue of messages to send to this peer.
messageQueue MessageQueue

// ip is the claimed IP the peer gave us in the Version message.
// ip is the claimed IP the peer gave us in the Handshake message.
ip *SignedIP
// version is the claimed version the peer is running that we received in
// the Version message.
// the Handshake message.
version *version.Application
// trackedSubnets is the subset of subnetIDs the peer sent us in the Version
// trackedSubnets is the subset of subnetIDs the peer sent us in the Handshake
// message that we are also tracking.
trackedSubnets set.Set[ids.ID]

Expand All @@ -134,13 +134,13 @@ type peer struct {
// Subnet ID --> Our uptime for the given subnet as perceived by the peer
observedUptimes map[ids.ID]uint32

// True if this peer has sent us a valid Version message and
// True if this peer has sent us a valid Handshake message and
// is running a compatible version.
// Only modified on the connection's reader routine.
gotVersion utils.Atomic[bool]
gotHandshake utils.Atomic[bool]

// True if the peer:
// * Has sent us a Version message
// * Has sent us a Handshake message
// * Has sent us a PeerList message
// * Is running a compatible version
// Only modified on the connection's reader routine.
Expand Down Expand Up @@ -487,7 +487,7 @@ func (p *peer) writeMessages() {

writer := bufio.NewWriterSize(p.conn, p.Config.WriteBufferSize)

// Make sure that the version is the first message sent
// Make sure that the Handshake is the first message sent
mySignedIP, err := p.IPSigner.GetSignedIP()
if err != nil {
p.Log.Error("failed to get signed IP",
Expand All @@ -505,7 +505,7 @@ func (p *peer) writeMessages() {
Patch: myVersion.Patch,
}

msg, err := p.MessageCreator.Version(
msg, err := p.MessageCreator.Handshake(
p.NetworkID,
p.Clock.Unix(),
mySignedIP.IPPort,
Expand All @@ -520,7 +520,7 @@ func (p *peer) writeMessages() {
)
if err != nil {
p.Log.Error("failed to create message",
zap.Stringer("messageOp", message.VersionOp),
zap.Stringer("messageOp", message.HandshakeOp),
zap.Stringer("nodeID", p.id),
zap.Error(err),
)
Expand Down Expand Up @@ -690,8 +690,8 @@ func (p *peer) handle(msg message.InboundMessage) {
p.handlePong(m)
msg.OnFinishedHandling()
return
case *p2p.Version:
p.handleVersion(m)
case *p2p.Handshake:
p.handleHandshake(m)
msg.OnFinishedHandling()
return
case *p2p.PeerList:
Expand Down Expand Up @@ -840,10 +840,10 @@ func (p *peer) observeUptime(subnetID ids.ID, uptime uint32) {
p.observedUptimesLock.Unlock()
}

func (p *peer) handleVersion(msg *p2p.Version) {
if p.gotVersion.Get() {
func (p *peer) handleHandshake(msg *p2p.Handshake) {
if p.gotHandshake.Get() {
// TODO: this should never happen, should we close the connection here?
p.Log.Verbo("dropping duplicated version message",
p.Log.Verbo("dropping duplicated handshake message",
zap.Stringer("nodeID", p.id),
)
return
Expand Down Expand Up @@ -960,7 +960,7 @@ func (p *peer) handleVersion(msg *p2p.Version) {
if ipLen := len(msg.IpAddr); ipLen != net.IPv6len {
p.Log.Debug("message with invalid field",
zap.Stringer("nodeID", p.id),
zap.Stringer("messageOp", message.VersionOp),
zap.Stringer("messageOp", message.HandshakeOp),
zap.String("field", "IP"),
zap.Int("ipLen", ipLen),
)
Expand All @@ -987,7 +987,7 @@ func (p *peer) handleVersion(msg *p2p.Version) {
return
}

p.gotVersion.Set(true)
p.gotHandshake.Set(true)

peerIPs, err := p.Network.Peers(p.id)
if err != nil {
Expand All @@ -998,7 +998,7 @@ func (p *peer) handleVersion(msg *p2p.Version) {
return
}

// We bypass throttling here to ensure that the version message is
// We bypass throttling here to ensure that the peerlist message is
// acknowledged timely.
peerListMsg, err := p.Config.MessageCreator.PeerList(peerIPs, true /*=bypassThrottling*/)
if err != nil {
Expand All @@ -1022,7 +1022,7 @@ func (p *peer) handleVersion(msg *p2p.Version) {

func (p *peer) handlePeerList(msg *p2p.PeerList) {
if !p.finishedHandshake.Get() {
if !p.gotVersion.Get() {
if !p.gotHandshake.Get() {
return
}

Expand Down Expand Up @@ -1050,7 +1050,7 @@ func (p *peer) handlePeerList(msg *p2p.PeerList) {
if ipLen := len(claimedIPPort.IpAddr); ipLen != net.IPv6len {
p.Log.Debug("message with invalid field",
zap.Stringer("nodeID", p.id),
zap.Stringer("messageOp", message.VersionOp),
zap.Stringer("messageOp", message.HandshakeOp),
zap.String("field", "IP"),
zap.Int("ipLen", ipLen),
)
Expand Down
Loading
Loading