github.com/ethereum/go-ethereum@v1.16.1/p2p/enode/node_test.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package enode
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/hex"
    22  	"fmt"
    23  	"math/big"
    24  	"net/netip"
    25  	"testing"
    26  	"testing/quick"
    27  
    28  	"github.com/ethereum/go-ethereum/p2p/enr"
    29  	"github.com/ethereum/go-ethereum/rlp"
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f")
    34  
    35  // TestPythonInterop checks that we can decode and verify a record produced by the Python
    36  // implementation.
    37  func TestPythonInterop(t *testing.T) {
    38  	var r enr.Record
    39  	if err := rlp.DecodeBytes(pyRecord, &r); err != nil {
    40  		t.Fatalf("can't decode: %v", err)
    41  	}
    42  	n, err := New(ValidSchemes, &r)
    43  	if err != nil {
    44  		t.Fatalf("can't verify record: %v", err)
    45  	}
    46  
    47  	var (
    48  		wantID  = HexID("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7")
    49  		wantSeq = uint64(1)
    50  		wantIP  = enr.IPv4{127, 0, 0, 1}
    51  		wantUDP = enr.UDP(30303)
    52  	)
    53  	if n.Seq() != wantSeq {
    54  		t.Errorf("wrong seq: got %d, want %d", n.Seq(), wantSeq)
    55  	}
    56  	if n.ID() != wantID {
    57  		t.Errorf("wrong id: got %x, want %x", n.ID(), wantID)
    58  	}
    59  	want := map[enr.Entry]interface{}{new(enr.IPv4): &wantIP, new(enr.UDP): &wantUDP}
    60  	for k, v := range want {
    61  		desc := fmt.Sprintf("loading key %q", k.ENRKey())
    62  		if assert.NoError(t, n.Load(k), desc) {
    63  			assert.Equal(t, k, v, desc)
    64  		}
    65  	}
    66  }
    67  
    68  func TestNodeEndpoints(t *testing.T) {
    69  	id := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
    70  	type endpointTest struct {
    71  		name     string
    72  		node     *Node
    73  		wantIP   netip.Addr
    74  		wantUDP  int
    75  		wantTCP  int
    76  		wantQUIC int
    77  		wantDNS  string
    78  	}
    79  	tests := []endpointTest{
    80  		{
    81  			name: "no-addr",
    82  			node: func() *Node {
    83  				var r enr.Record
    84  				return SignNull(&r, id)
    85  			}(),
    86  		},
    87  		{
    88  			name: "udp-only",
    89  			node: func() *Node {
    90  				var r enr.Record
    91  				r.Set(enr.UDP(9000))
    92  				return SignNull(&r, id)
    93  			}(),
    94  			wantUDP: 9000,
    95  		},
    96  		{
    97  			name: "tcp-only",
    98  			node: func() *Node {
    99  				var r enr.Record
   100  				r.Set(enr.TCP(9000))
   101  				return SignNull(&r, id)
   102  			}(),
   103  			wantTCP: 9000,
   104  		},
   105  		{
   106  			name: "quic-only",
   107  			node: func() *Node {
   108  				var r enr.Record
   109  				r.Set(enr.QUIC(9000))
   110  				return SignNull(&r, id)
   111  			}(),
   112  		},
   113  		{
   114  			name: "quic6-only",
   115  			node: func() *Node {
   116  				var r enr.Record
   117  				r.Set(enr.QUIC6(9000))
   118  				return SignNull(&r, id)
   119  			}(),
   120  		},
   121  		{
   122  			name: "ipv4-only-loopback",
   123  			node: func() *Node {
   124  				var r enr.Record
   125  				r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1")))
   126  				return SignNull(&r, id)
   127  			}(),
   128  			wantIP: netip.MustParseAddr("127.0.0.1"),
   129  		},
   130  		{
   131  			name: "ipv4-only-unspecified",
   132  			node: func() *Node {
   133  				var r enr.Record
   134  				r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0")))
   135  				return SignNull(&r, id)
   136  			}(),
   137  			wantIP: netip.MustParseAddr("0.0.0.0"),
   138  		},
   139  		{
   140  			name: "ipv4-only",
   141  			node: func() *Node {
   142  				var r enr.Record
   143  				r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1")))
   144  				return SignNull(&r, id)
   145  			}(),
   146  			wantIP: netip.MustParseAddr("99.22.33.1"),
   147  		},
   148  		{
   149  			name: "ipv6-only",
   150  			node: func() *Node {
   151  				var r enr.Record
   152  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   153  				return SignNull(&r, id)
   154  			}(),
   155  			wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
   156  		},
   157  		{
   158  			name: "ipv4-loopback-and-ipv6-global",
   159  			node: func() *Node {
   160  				var r enr.Record
   161  				r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1")))
   162  				r.Set(enr.UDP(30304))
   163  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   164  				r.Set(enr.UDP6(30306))
   165  				return SignNull(&r, id)
   166  			}(),
   167  			wantIP:  netip.MustParseAddr("2001::ff00:0042:8329"),
   168  			wantUDP: 30306,
   169  		},
   170  		{
   171  			name: "ipv4-unspecified-and-ipv6-loopback",
   172  			node: func() *Node {
   173  				var r enr.Record
   174  				r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0")))
   175  				r.Set(enr.IPv6Addr(netip.MustParseAddr("::1")))
   176  				return SignNull(&r, id)
   177  			}(),
   178  			wantIP: netip.MustParseAddr("::1"),
   179  		},
   180  		{
   181  			name: "ipv4-private-and-ipv6-global",
   182  			node: func() *Node {
   183  				var r enr.Record
   184  				r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2")))
   185  				r.Set(enr.UDP(30304))
   186  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   187  				r.Set(enr.UDP6(30306))
   188  				return SignNull(&r, id)
   189  			}(),
   190  			wantIP:  netip.MustParseAddr("2001::ff00:0042:8329"),
   191  			wantUDP: 30306,
   192  		},
   193  		{
   194  			name: "ipv4-local-and-ipv6-global",
   195  			node: func() *Node {
   196  				var r enr.Record
   197  				r.Set(enr.IPv4Addr(netip.MustParseAddr("169.254.2.6")))
   198  				r.Set(enr.UDP(30304))
   199  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   200  				r.Set(enr.UDP6(30306))
   201  				return SignNull(&r, id)
   202  			}(),
   203  			wantIP:  netip.MustParseAddr("2001::ff00:0042:8329"),
   204  			wantUDP: 30306,
   205  		},
   206  		{
   207  			name: "ipv4-private-and-ipv6-private",
   208  			node: func() *Node {
   209  				var r enr.Record
   210  				r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2")))
   211  				r.Set(enr.UDP(30304))
   212  				r.Set(enr.IPv6Addr(netip.MustParseAddr("fd00::abcd:1")))
   213  				r.Set(enr.UDP6(30306))
   214  				return SignNull(&r, id)
   215  			}(),
   216  			wantIP:  netip.MustParseAddr("192.168.2.2"),
   217  			wantUDP: 30304,
   218  		},
   219  		{
   220  			name: "ipv4-private-and-ipv6-link-local",
   221  			node: func() *Node {
   222  				var r enr.Record
   223  				r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2")))
   224  				r.Set(enr.UDP(30304))
   225  				r.Set(enr.IPv6Addr(netip.MustParseAddr("fe80::1")))
   226  				r.Set(enr.UDP6(30306))
   227  				return SignNull(&r, id)
   228  			}(),
   229  			wantIP:  netip.MustParseAddr("192.168.2.2"),
   230  			wantUDP: 30304,
   231  		},
   232  		{
   233  			name: "ipv4-quic",
   234  			node: func() *Node {
   235  				var r enr.Record
   236  				r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1")))
   237  				r.Set(enr.QUIC(9001))
   238  				return SignNull(&r, id)
   239  			}(),
   240  			wantIP:   netip.MustParseAddr("99.22.33.1"),
   241  			wantQUIC: 9001,
   242  		},
   243  		{ // Because the node is IPv4, the quic6 entry won't be loaded.
   244  			name: "ipv4-quic6",
   245  			node: func() *Node {
   246  				var r enr.Record
   247  				r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1")))
   248  				r.Set(enr.QUIC6(9001))
   249  				return SignNull(&r, id)
   250  			}(),
   251  			wantIP: netip.MustParseAddr("99.22.33.1"),
   252  		},
   253  		{
   254  			name: "ipv6-quic",
   255  			node: func() *Node {
   256  				var r enr.Record
   257  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   258  				r.Set(enr.QUIC(9001))
   259  				return SignNull(&r, id)
   260  			}(),
   261  			wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
   262  		},
   263  		{
   264  			name: "ipv6-quic6",
   265  			node: func() *Node {
   266  				var r enr.Record
   267  				r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329")))
   268  				r.Set(enr.QUIC6(9001))
   269  				return SignNull(&r, id)
   270  			}(),
   271  			wantIP:   netip.MustParseAddr("2001::ff00:0042:8329"),
   272  			wantQUIC: 9001,
   273  		},
   274  		{
   275  			name: "dns-only",
   276  			node: func() *Node {
   277  				var r enr.Record
   278  				r.Set(enr.UDP(30303))
   279  				r.Set(enr.TCP(30303))
   280  				n := SignNull(&r, id).WithHostname("example.com")
   281  				return n
   282  			}(),
   283  			wantTCP: 30303,
   284  			wantUDP: 30303,
   285  			wantDNS: "example.com",
   286  		},
   287  	}
   288  
   289  	for _, test := range tests {
   290  		t.Run(test.name, func(t *testing.T) {
   291  			if test.wantIP != test.node.IPAddr() {
   292  				t.Errorf("node has wrong IP %v, want %v", test.node.IPAddr(), test.wantIP)
   293  			}
   294  			if test.wantUDP != test.node.UDP() {
   295  				t.Errorf("node has wrong UDP port %d, want %d", test.node.UDP(), test.wantUDP)
   296  			}
   297  			if test.wantTCP != test.node.TCP() {
   298  				t.Errorf("node has wrong TCP port %d, want %d", test.node.TCP(), test.wantTCP)
   299  			}
   300  			if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) {
   301  				t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC)
   302  			}
   303  			if test.wantDNS != test.node.Hostname() {
   304  				t.Errorf("node has wrong DNS name %s, want %s", test.node.Hostname(), test.wantDNS)
   305  			}
   306  		})
   307  	}
   308  }
   309  
   310  func TestHexID(t *testing.T) {
   311  	ref := ID{0, 0, 0, 0, 0, 0, 0, 128, 106, 217, 182, 31, 165, 174, 1, 67, 7, 235, 220, 150, 66, 83, 173, 205, 159, 44, 10, 57, 42, 161, 26, 188}
   312  	id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   313  	id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   314  
   315  	if id1 != ref {
   316  		t.Errorf("wrong id1\ngot  %v\nwant %v", id1[:], ref[:])
   317  	}
   318  	if id2 != ref {
   319  		t.Errorf("wrong id2\ngot  %v\nwant %v", id2[:], ref[:])
   320  	}
   321  }
   322  
   323  func TestID_textEncoding(t *testing.T) {
   324  	ref := ID{
   325  		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
   326  		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
   327  		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
   328  		0x31, 0x32,
   329  	}
   330  	hex := "0102030405060708091011121314151617181920212223242526272829303132"
   331  
   332  	text, err := ref.MarshalText()
   333  	if err != nil {
   334  		t.Fatal(err)
   335  	}
   336  	if !bytes.Equal(text, []byte(hex)) {
   337  		t.Fatalf("text encoding did not match\nexpected: %s\ngot:      %s", hex, text)
   338  	}
   339  
   340  	id := new(ID)
   341  	if err := id.UnmarshalText(text); err != nil {
   342  		t.Fatal(err)
   343  	}
   344  	if *id != ref {
   345  		t.Fatalf("text decoding did not match\nexpected: %s\ngot:      %s", ref, id)
   346  	}
   347  }
   348  
   349  func TestID_distcmp(t *testing.T) {
   350  	distcmpBig := func(target, a, b ID) int {
   351  		tbig := new(big.Int).SetBytes(target[:])
   352  		abig := new(big.Int).SetBytes(a[:])
   353  		bbig := new(big.Int).SetBytes(b[:])
   354  		return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig))
   355  	}
   356  	if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil {
   357  		t.Error(err)
   358  	}
   359  }
   360  
   361  // The random tests is likely to miss the case where a and b are equal,
   362  // this test checks it explicitly.
   363  func TestID_distcmpEqual(t *testing.T) {
   364  	base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   365  	x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
   366  	if DistCmp(base, x, x) != 0 {
   367  		t.Errorf("DistCmp(base, x, x) != 0")
   368  	}
   369  }
   370  
   371  func TestID_logdist(t *testing.T) {
   372  	logdistBig := func(a, b ID) int {
   373  		abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:])
   374  		return new(big.Int).Xor(abig, bbig).BitLen()
   375  	}
   376  	if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil {
   377  		t.Error(err)
   378  	}
   379  }
   380  
   381  // The random tests is likely to miss the case where a and b are equal,
   382  // this test checks it explicitly.
   383  func TestID_logdistEqual(t *testing.T) {
   384  	x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   385  	if LogDist(x, x) != 0 {
   386  		t.Errorf("LogDist(x, x) != 0")
   387  	}
   388  }