github.com/ethereum/go-ethereum@v1.16.1/p2p/discover/table_reval_test.go (about) 1 // Copyright 2024 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 discover 18 19 import ( 20 "net" 21 "testing" 22 "time" 23 24 "github.com/ethereum/go-ethereum/common/mclock" 25 "github.com/ethereum/go-ethereum/p2p/enode" 26 "github.com/ethereum/go-ethereum/p2p/enr" 27 ) 28 29 // This test checks that revalidation can handle a node disappearing while 30 // a request is active. 31 func TestRevalidation_nodeRemoved(t *testing.T) { 32 var ( 33 clock mclock.Simulated 34 transport = newPingRecorder() 35 tab, db = newInactiveTestTable(transport, Config{Clock: &clock}) 36 tr = &tab.revalidation 37 ) 38 defer db.Close() 39 40 // Add a node to the table. 41 node := nodeAtDistance(tab.self().ID(), 255, net.IP{77, 88, 99, 1}) 42 tab.handleAddNode(addNodeOp{node: node}) 43 44 // Start a revalidation request. Schedule once to get the next start time, 45 // then advance the clock to that point and schedule again to start. 46 next := tr.run(tab, clock.Now()) 47 clock.Run(time.Duration(next + 1)) 48 tr.run(tab, clock.Now()) 49 if len(tr.activeReq) != 1 { 50 t.Fatal("revalidation request did not start:", tr.activeReq) 51 } 52 53 // Delete the node. 54 tab.deleteInBucket(tab.bucket(node.ID()), node.ID()) 55 56 // Now finish the revalidation request. 57 var resp revalidationResponse 58 select { 59 case resp = <-tab.revalResponseCh: 60 case <-time.After(1 * time.Second): 61 t.Fatal("timed out waiting for revalidation") 62 } 63 tr.handleResponse(tab, resp) 64 65 // Ensure the node was not re-added to the table. 66 if tab.getNode(node.ID()) != nil { 67 t.Fatal("node was re-added to Table") 68 } 69 if tr.fast.contains(node.ID()) || tr.slow.contains(node.ID()) { 70 t.Fatal("removed node contained in revalidation list") 71 } 72 } 73 74 // This test checks that nodes with an updated endpoint remain in the fast revalidation list. 75 func TestRevalidation_endpointUpdate(t *testing.T) { 76 var ( 77 clock mclock.Simulated 78 transport = newPingRecorder() 79 tab, db = newInactiveTestTable(transport, Config{Clock: &clock}) 80 tr = &tab.revalidation 81 ) 82 defer db.Close() 83 84 // Add node to table. 85 node := nodeAtDistance(tab.self().ID(), 255, net.IP{77, 88, 99, 1}) 86 tab.handleAddNode(addNodeOp{node: node}) 87 88 // Update the record in transport, including endpoint update. 89 record := node.Record() 90 record.Set(enr.IP{100, 100, 100, 100}) 91 record.Set(enr.UDP(9999)) 92 nodev2 := enode.SignNull(record, node.ID()) 93 transport.updateRecord(nodev2) 94 95 // Start a revalidation request. Schedule once to get the next start time, 96 // then advance the clock to that point and schedule again to start. 97 next := tr.run(tab, clock.Now()) 98 clock.Run(time.Duration(next + 1)) 99 tr.run(tab, clock.Now()) 100 if len(tr.activeReq) != 1 { 101 t.Fatal("revalidation request did not start:", tr.activeReq) 102 } 103 104 // Now finish the revalidation request. 105 var resp revalidationResponse 106 select { 107 case resp = <-tab.revalResponseCh: 108 case <-time.After(1 * time.Second): 109 t.Fatal("timed out waiting for revalidation") 110 } 111 tr.handleResponse(tab, resp) 112 113 if tr.fast.nodes[0].ID() != node.ID() { 114 t.Fatal("node not contained in fast revalidation list") 115 } 116 if tr.fast.nodes[0].isValidatedLive { 117 t.Fatal("node is marked live after endpoint change") 118 } 119 }