From 79ab35c29c6a676c46eb227ac96e1b9347db8ea9 Mon Sep 17 00:00:00 2001 From: JKincorperated Date: Tue, 18 Mar 2025 14:59:29 +0000 Subject: [PATCH] p2p: Add EIP-7636 support --- p2p/enr/enr_test.go | 27 +++++++++++++++++++++++++++ p2p/enr/entries.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/p2p/enr/enr_test.go b/p2p/enr/enr_test.go index 4fccb0cce9..5b2f145b2a 100644 --- a/p2p/enr/enr_test.go +++ b/p2p/enr/enr_test.go @@ -81,6 +81,33 @@ func TestGetSetUDP(t *testing.T) { assert.Equal(t, port, port2) } +// TestGetSetClientInfo tests encoding/decoding and setting/getting of the Client key. +func TestGetSetClientInfo(t *testing.T) { + name := "go-ethereum" + ver := "1.0.0" + build := "build-example" + + // Without build info + + client := Client(Client{&name, &ver, nil}) + var r Record + r.Set(client) + + var client2 Client + require.NoError(t, r.Load(&client2)) + assert.Equal(t, client, client2) + + // With build info + + clientWithBuild := Client(Client{&name, &ver, &build}) + var r2 Record + r2.Set(clientWithBuild) + + var clientWithBuild2 Client + require.NoError(t, r2.Load(&clientWithBuild2)) + assert.Equal(t, clientWithBuild, clientWithBuild2) +} + func TestLoadErrors(t *testing.T) { var r Record ip4 := IPv4{127, 0, 0, 1} diff --git a/p2p/enr/entries.go b/p2p/enr/entries.go index 58e660c154..292616a56e 100644 --- a/p2p/enr/entries.go +++ b/p2p/enr/entries.go @@ -153,6 +153,41 @@ func (v *IPv4) DecodeRLP(s *rlp.Stream) error { return nil } +// Client is the "client" key, which holds the EIP-7636 client info. +type Client [3]*string; + +func (v Client) ENRKey() string { return "client" } + +// EncodeRLP implements rlp.Encoder. +func (v Client) EncodeRLP(w io.Writer) error { + var list []string + for _, s := range v { + if s != nil { + list = append(list, *s) + } + } + if len(list) < 2 || len(list) > 3 { + return fmt.Errorf("invalid client info length: %d", len(list)) + } + return rlp.Encode(w, list) +} + +// DecodeRLP implements rlp.Decoder. +func (v *Client) DecodeRLP(s *rlp.Stream) error { + var list []string + if err := s.Decode(&list); err != nil { + return err + } + if len(list) < 2 || len(list) > 3 { + return fmt.Errorf("invalid client info length: %d", len(list)) + } + for i := 0; i < len(list); i++ { + str := list[i] + v[i] = &str + } + return nil +} + // IPv6 is the "ip6" key, which holds the IP address of the node. type IPv6 net.IP