github.com/ethereum/go-ethereum@v1.16.1/p2p/enode/localnode_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 "math/rand" 21 "net" 22 "net/netip" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/crypto" 26 "github.com/ethereum/go-ethereum/p2p/enr" 27 "github.com/ethereum/go-ethereum/p2p/netutil" 28 "github.com/stretchr/testify/assert" 29 ) 30 31 func newLocalNodeForTesting() (*LocalNode, *DB) { 32 db, _ := OpenDB("") 33 key, _ := crypto.GenerateKey() 34 return NewLocalNode(db, key), db 35 } 36 37 func TestLocalNode(t *testing.T) { 38 ln, db := newLocalNodeForTesting() 39 defer db.Close() 40 41 if ln.Node().ID() != ln.ID() { 42 t.Fatal("inconsistent ID") 43 } 44 45 ln.Set(enr.WithEntry("x", uint(3))) 46 var x uint 47 if err := ln.Node().Load(enr.WithEntry("x", &x)); err != nil { 48 t.Fatal("can't load entry 'x':", err) 49 } else if x != 3 { 50 t.Fatal("wrong value for entry 'x':", x) 51 } 52 } 53 54 // This test checks that the sequence number is persisted between restarts. 55 func TestLocalNodeSeqPersist(t *testing.T) { 56 timestamp := nowMilliseconds() 57 58 ln, db := newLocalNodeForTesting() 59 defer db.Close() 60 61 initialSeq := ln.Node().Seq() 62 if initialSeq < timestamp { 63 t.Fatalf("wrong initial seq %d, want at least %d", initialSeq, timestamp) 64 } 65 66 ln.Set(enr.WithEntry("x", uint(1))) 67 if s := ln.Node().Seq(); s != initialSeq+1 { 68 t.Fatalf("wrong seq %d after set, want %d", s, initialSeq+1) 69 } 70 71 // Create a new instance, it should reload the sequence number. 72 // The number increases just after that because a new record is 73 // created without the "x" entry. 74 ln2 := NewLocalNode(db, ln.key) 75 if s := ln2.Node().Seq(); s != initialSeq+2 { 76 t.Fatalf("wrong seq %d on new instance, want %d", s, initialSeq+2) 77 } 78 79 finalSeq := ln2.Node().Seq() 80 81 // Create a new instance with a different node key on the same database. 82 // This should reset the sequence number. 83 key, _ := crypto.GenerateKey() 84 ln3 := NewLocalNode(db, key) 85 if s := ln3.Node().Seq(); s < finalSeq { 86 t.Fatalf("wrong seq %d on instance with changed key, want >= %d", s, finalSeq) 87 } 88 } 89 90 // This test checks behavior of the endpoint predictor. 91 func TestLocalNodeEndpoint(t *testing.T) { 92 var ( 93 rng = rand.New(rand.NewSource(4)) 94 fallback = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: 80} 95 predicted = &net.UDPAddr{IP: net.IP{127, 0, 1, 2}, Port: 81} 96 staticIP = net.IP{127, 0, 1, 2} 97 ) 98 ln, db := newLocalNodeForTesting() 99 defer db.Close() 100 101 // Nothing is set initially. 102 assert.Equal(t, netip.Addr{}, ln.Node().IPAddr()) 103 assert.Equal(t, net.IP(nil), ln.Node().IP()) 104 assert.Equal(t, 0, ln.Node().UDP()) 105 initialSeq := ln.Node().Seq() 106 107 // Set up fallback address. 108 ln.SetFallbackIP(fallback.IP) 109 ln.SetFallbackUDP(fallback.Port) 110 assert.Equal(t, netutil.IPToAddr(fallback.IP), ln.Node().IPAddr()) 111 assert.Equal(t, fallback.IP, ln.Node().IP()) 112 assert.Equal(t, fallback.Port, ln.Node().UDP()) 113 assert.Equal(t, initialSeq+1, ln.Node().Seq()) 114 115 // Add endpoint statements from random hosts. 116 for i := 0; i < iptrackMinStatements; i++ { 117 assert.Equal(t, netutil.IPToAddr(fallback.IP), ln.Node().IPAddr()) 118 assert.Equal(t, fallback.IP, ln.Node().IP()) 119 assert.Equal(t, fallback.Port, ln.Node().UDP()) 120 assert.Equal(t, initialSeq+1, ln.Node().Seq()) 121 122 from := netip.AddrPortFrom(netutil.RandomAddr(rng, true), 9000) 123 endpoint := netip.AddrPortFrom(netutil.IPToAddr(predicted.IP), uint16(predicted.Port)) 124 ln.UDPEndpointStatement(from, endpoint) 125 } 126 assert.Equal(t, netutil.IPToAddr(predicted.IP), ln.Node().IPAddr()) 127 assert.Equal(t, predicted.IP, ln.Node().IP()) 128 assert.Equal(t, predicted.Port, ln.Node().UDP()) 129 assert.Equal(t, initialSeq+2, ln.Node().Seq()) 130 131 // Static IP overrides prediction. 132 ln.SetStaticIP(staticIP) 133 assert.Equal(t, netutil.IPToAddr(staticIP), ln.Node().IPAddr()) 134 assert.Equal(t, staticIP, ln.Node().IP()) 135 assert.Equal(t, fallback.Port, ln.Node().UDP()) 136 assert.Equal(t, initialSeq+3, ln.Node().Seq()) 137 }