Skip to content

Commit f544fc3

Browse files
p2p/enode: add quic ENR entry (#30283)
Add `quic` entry to the ENR as proposed in ethereum/consensus-specs#3644 --------- Co-authored-by: lightclient <[email protected]>
1 parent 9be2e01 commit f544fc3

File tree

3 files changed

+91
-5
lines changed

3 files changed

+91
-5
lines changed

p2p/enode/node.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,20 @@ func (n *Node) TCPEndpoint() (netip.AddrPort, bool) {
200200
return netip.AddrPortFrom(n.ip, n.tcp), true
201201
}
202202

203+
// QUICEndpoint returns the announced QUIC endpoint.
204+
func (n *Node) QUICEndpoint() (netip.AddrPort, bool) {
205+
var quic uint16
206+
if n.ip.Is4() || n.ip.Is4In6() {
207+
n.Load((*enr.QUIC)(&quic))
208+
} else if n.ip.Is6() {
209+
n.Load((*enr.QUIC6)(&quic))
210+
}
211+
if !n.ip.IsValid() || n.ip.IsUnspecified() || quic == 0 {
212+
return netip.AddrPort{}, false
213+
}
214+
return netip.AddrPortFrom(n.ip, quic), true
215+
}
216+
203217
// Pubkey returns the secp256k1 public key of the node, if present.
204218
func (n *Node) Pubkey() *ecdsa.PublicKey {
205219
var key ecdsa.PublicKey

p2p/enode/node_test.go

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ func TestPythonInterop(t *testing.T) {
6868
func TestNodeEndpoints(t *testing.T) {
6969
id := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
7070
type endpointTest struct {
71-
name string
72-
node *Node
73-
wantIP netip.Addr
74-
wantUDP int
75-
wantTCP int
71+
name string
72+
node *Node
73+
wantIP netip.Addr
74+
wantUDP int
75+
wantTCP int
76+
wantQUIC int
7677
}
7778
tests := []endpointTest{
7879
{
@@ -98,6 +99,22 @@ func TestNodeEndpoints(t *testing.T) {
9899
return SignNull(&r, id)
99100
}(),
100101
},
102+
{
103+
name: "quic-only",
104+
node: func() *Node {
105+
var r enr.Record
106+
r.Set(enr.QUIC(9000))
107+
return SignNull(&r, id)
108+
}(),
109+
},
110+
{
111+
name: "quic6-only",
112+
node: func() *Node {
113+
var r enr.Record
114+
r.Set(enr.QUIC6(9000))
115+
return SignNull(&r, id)
116+
}(),
117+
},
101118
{
102119
name: "ipv4-only-loopback",
103120
node: func() *Node {
@@ -209,6 +226,48 @@ func TestNodeEndpoints(t *testing.T) {
209226
wantIP: netip.MustParseAddr("192.168.2.2"),
210227
wantUDP: 30304,
211228
},
229+
{
230+
name: "ipv4-quic",
231+
node: func() *Node {
232+
var r enr.Record
233+
r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1")))
234+
r.Set(enr.QUIC(9001))
235+
return SignNull(&r, id)
236+
}(),
237+
wantIP: netip.MustParseAddr("99.22.33.1"),
238+
wantQUIC: 9001,
239+
},
240+
{ // Because the node is IPv4, the quic6 entry won't be loaded.
241+
name: "ipv4-quic6",
242+
node: func() *Node {
243+
var r enr.Record
244+
r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1")))
245+
r.Set(enr.QUIC6(9001))
246+
return SignNull(&r, id)
247+
}(),
248+
wantIP: netip.MustParseAddr("99.22.33.1"),
249+
},
250+
{
251+
name: "ipv6-quic",
252+
node: func() *Node {
253+
var r enr.Record
254+
r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
255+
r.Set(enr.QUIC(9001))
256+
return SignNull(&r, id)
257+
}(),
258+
wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
259+
},
260+
{
261+
name: "ipv6-quic6",
262+
node: func() *Node {
263+
var r enr.Record
264+
r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
265+
r.Set(enr.QUIC6(9001))
266+
return SignNull(&r, id)
267+
}(),
268+
wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
269+
wantQUIC: 9001,
270+
},
212271
}
213272

214273
for _, test := range tests {
@@ -222,6 +281,9 @@ func TestNodeEndpoints(t *testing.T) {
222281
if test.wantTCP != test.node.TCP() {
223282
t.Errorf("node has wrong TCP port %d, want %d", test.node.TCP(), test.wantTCP)
224283
}
284+
if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) {
285+
t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC)
286+
}
225287
})
226288
}
227289
}

p2p/enr/entries.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ type UDP6 uint16
7777

7878
func (v UDP6) ENRKey() string { return "udp6" }
7979

80+
// QUIC is the "quic" key, which holds the QUIC port of the node.
81+
type QUIC uint16
82+
83+
func (v QUIC) ENRKey() string { return "quic" }
84+
85+
// QUIC6 is the "quic6" key, which holds the IPv6-specific quic6 port of the node.
86+
type QUIC6 uint16
87+
88+
func (v QUIC6) ENRKey() string { return "quic6" }
89+
8090
// ID is the "id" key, which holds the name of the identity scheme.
8191
type ID string
8292

0 commit comments

Comments
 (0)