github.com/klaytn/klaytn@v1.12.1/networks/p2p/discover/discover_api_test.go (about) 1 // Copyright 2019 The klaytn Authors 2 // This file is part of the klaytn library. 3 // 4 // The klaytn 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 klaytn 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 klaytn library. If not, see <http://www.gnu.org/licenses/>. 16 17 package discover 18 19 import ( 20 "testing" 21 22 "github.com/klaytn/klaytn/common" 23 "github.com/klaytn/klaytn/log" 24 ) 25 26 var rawUrls = []string{ 27 "kni://a3fd567e0e1bb9f7d7a20385b797563883ebb9d45ff6f05a588b56256f46bd649b7ecc8e3e17cc50df4599c1809463e66ad964f7a3fb6cf4c768c25d647f2c02@0.0.0.1:3000", 28 "kni://bf0d5b99945d5b94bc8430af9ec8019dd3535be586809d04422aa1bacf16b9161cc868c63d11423e30525d8ea41407c28854b1e12058297f8e0ef3c357c8d6c0@0.0.0.2:4000?discport=0", 29 "kni://418211f65eb3c14ddab49f690ed291f7681bff08742889a518ca58d2176b4afaa8fdaff1cd45957d7a7c14965d1ffd811bd677e70dc2e309cf8baacf73eb2bdc@0.0.0.3:5000?discport=32323", 30 "kni://7ea7fae31c0d1a0a3208607f948b7b8d2eb5c410fb07d27bbcad8359fef1e78ec10e3f9132feaa69b0438ac70d5a3a13af041e47089bc43d90f68ba5fc72a23c@0.0.0.4:6000", 31 "kni://e92f2fcd87ad42b9f6e55aebc2e35c73e5443fc3128a82dc11cc84acf445a14beee202140c5004d73c981d8bf423cb05714e9f7b1cabfd2720e34ed22e819dc3@0.0.0.5:7000", 32 "kni://01a63da798a08b6322ae59d398628addebd87eb582a801976d7d1b2a1143574a15adc4a8ae08d1286e8cb36ef6d904e25ae932d3cb4e695944b48afb58981550@0.0.0.6:8000?discport=0", 33 } 34 35 type mockDiscoveryStorage struct { 36 data []*Node 37 } 38 39 func (mds *mockDiscoveryStorage) name() string { return "mockDiscoveryStorage" } 40 func (mds *mockDiscoveryStorage) setTable(t *Table) {} 41 func (mds *mockDiscoveryStorage) setTargetNodeType(tType NodeType) {} 42 func (mds *mockDiscoveryStorage) init() {} 43 func (mds *mockDiscoveryStorage) add(n *Node) { mds.data = append(mds.data, n) } 44 func (mds *mockDiscoveryStorage) delete(n *Node) { mds.data = deleteNode(mds.data, n) } 45 func (mds *mockDiscoveryStorage) len() (n int) { return 0 } 46 func (mds *mockDiscoveryStorage) nodeAll() []*Node { return mds.data } 47 func (mds *mockDiscoveryStorage) readRandomNodes(buf []*Node) (n int) { return 0 } 48 func (mds *mockDiscoveryStorage) closest(target common.Hash, nresults int) *nodesByDistance { 49 return nil 50 } 51 func (mds *mockDiscoveryStorage) stuff(nodes []*Node) {} 52 func (mds *mockDiscoveryStorage) copyBondedNodes() {} 53 func (mds *mockDiscoveryStorage) lookup(targetID NodeID, refreshIfEmpty bool, targetType NodeType) []*Node { 54 return nil 55 } 56 func (mds *mockDiscoveryStorage) getNodes(max int) []*Node { return nil } 57 func (mds *mockDiscoveryStorage) doRevalidate() {} 58 func (mds *mockDiscoveryStorage) doRefresh() {} 59 60 func (mds *mockDiscoveryStorage) isAuthorized(id NodeID) bool { return true } 61 func (mds *mockDiscoveryStorage) getBucketEntries() []*Node { return mds.data } 62 func (mds *mockDiscoveryStorage) getAuthorizedNodes() []*Node { return nil } 63 func (mds *mockDiscoveryStorage) putAuthorizedNode(node *Node) {} 64 func (mds *mockDiscoveryStorage) deleteAuthorizedNode(id NodeID) {} 65 66 func createTestData() *mockDiscoveryStorage { 67 var d []*Node 68 for _, url := range rawUrls { 69 node, _ := ParseNode(url) 70 d = append(d, node) 71 } 72 mds := &mockDiscoveryStorage{ 73 data: d, 74 } 75 return mds 76 } 77 78 func createTestTable() (*Table, error) { 79 id := MustHexID("904afadc3587310adad21971c28a9213d03b04c4bd5ec73f7609861eb57b60b26809a52e72cbc6af9dfdd780a6d6629898ef197149f840e03f237660bc0dbb48") 80 tmpDB, _ := newNodeDB("", Version, id) 81 tab := &Table{ 82 db: tmpDB, 83 storages: make(map[NodeType]discoverStorage), 84 localLogger: log.NewModuleLogger(log.NetworksP2PDiscover).NewWith("Discover", "Test"), 85 } 86 storage := createTestData() 87 tab.addStorage(NodeTypeUnknown, storage) 88 for _, node := range storage.data { 89 err := tab.db.updateNode(node) 90 if err != nil { 91 return nil, err 92 } 93 } 94 return tab, nil 95 } 96 97 func TestTable_CreateUpdateNodeOnDB(t *testing.T) { 98 tab, _ := createTestTable() 99 n, _ := ParseNode("kni://31a03810a315b200053ea5905d4e0a32a50eafcf2613e90e17ee877652dbb2aba1c725016ebe44d48529c8755203046a927fb01b97d758c009d248c4d7dfdd8c@0.0.0.0:32323?discport=0") 100 err := tab.CreateUpdateNodeOnDB(n) 101 if err != nil { 102 t.Error("CreateUpdateNodeOnDB is failed", "err", err) 103 } 104 id, _ := HexID("31a03810a315b200053ea5905d4e0a32a50eafcf2613e90e17ee877652dbb2aba1c725016ebe44d48529c8755203046a927fb01b97d758c009d248c4d7dfdd8c") 105 n2 := tab.db.node(id) 106 if !n.CompareNode(n2) { 107 t.Error("nodes are different", "inserted:", n, "retrieved", n2) 108 } 109 } 110 111 func TestTable_CreateUpdateNodeOnTable(t *testing.T) { 112 tab, _ := createTestTable() 113 n, _ := ParseNode("kni://31a03810a315b200053ea5905d4e0a32a50eafcf2613e90e17ee877652dbb2aba1c725016ebe44d48529c8755203046a927fb01b97d758c009d248c4d7dfdd8c@0.0.0.0:32323?discport=0") 114 err := tab.CreateUpdateNodeOnTable(n) 115 if err != nil { 116 t.Error("CreateUpdateNodeOnTable is failed", "err", err) 117 } 118 entries := tab.GetBucketEntries() 119 replacements := tab.GetReplacements() 120 if !isIn(n, append(entries, replacements...)) { 121 t.Errorf("the node does not exist. nodeid: %v", n.ID) 122 } 123 } 124 125 func TestTable_GetNodeFromDB(t *testing.T) { 126 tab, _ := createTestTable() 127 id0 := MustHexID("a3fd567e0e1bb9f7d7a20385b797563883ebb9d45ff6f05a588b56256f46bd649b7ecc8e3e17cc50df4599c1809463e66ad964f7a3fb6cf4c768c25d647f2c02") 128 id1 := MustHexID("bf0d5b99945d5b94bc8430af9ec8019dd3535be586809d04422aa1bacf16b9161cc868c63d11423e30525d8ea41407c28854b1e12058297f8e0ef3c357c8d6c0") 129 id2 := MustHexID("418211f65eb3c14ddab49f690ed291f7681bff08742889a518ca58d2176b4afaa8fdaff1cd45957d7a7c14965d1ffd811bd677e70dc2e309cf8baacf73eb2bdc") 130 id3 := MustHexID("7ea7fae31c0d1a0a3208607f948b7b8d2eb5c410fb07d27bbcad8359fef1e78ec10e3f9132feaa69b0438ac70d5a3a13af041e47089bc43d90f68ba5fc72a23c") 131 id4 := MustHexID("e92f2fcd87ad42b9f6e55aebc2e35c73e5443fc3128a82dc11cc84acf445a14beee202140c5004d73c981d8bf423cb05714e9f7b1cabfd2720e34ed22e819dc3") 132 id5 := MustHexID("01a63da798a08b6322ae59d398628addebd87eb582a801976d7d1b2a1143574a15adc4a8ae08d1286e8cb36ef6d904e25ae932d3cb4e695944b48afb58981550") 133 ids := []NodeID{id0, id1, id2, id3, id4, id5} 134 for idx, id := range ids { 135 node1, err := tab.GetNodeFromDB(id) 136 if err != nil { 137 t.Error("get node is failed.", "err:", err) 138 } 139 node2, _ := ParseNode(rawUrls[idx]) 140 if !node1.CompareNode(node2) { 141 t.Error("node1 is different from node2.", "node1:", node1, "node2:", node2) 142 } 143 } 144 } 145 146 func TestTable_GetBucketEntries(t *testing.T) { 147 tab, _ := createTestTable() 148 entries := tab.GetBucketEntries() 149 if storage, ok := tab.storages[NodeTypeUnknown].(*mockDiscoveryStorage); ok { 150 if len(storage.data) != len(entries) { 151 t.Error("the length of actual data is different from the result of GetBucketEntries") 152 } 153 for _, node := range storage.data { 154 existed := false 155 for _, node2 := range entries { 156 if node.CompareNode(node2) { 157 existed = true 158 break 159 } 160 } 161 if !existed { 162 t.Error("node does not existed", "nodeid", node.ID) 163 } 164 } 165 for _, node := range storage.data { 166 faultyNode, _ := ParseNode("kni://71cd148865fd6dd9658a233aef8e7d844d279f4d04c9783c91d63c664109709609900ee3bc6e6b8ca7f4bff555be5331c10801e1e6e6713ebfd339674ccc377b@0.0.0.0:32323?discport=0") 167 if node.CompareNode(faultyNode) { 168 t.Error("the node existed although it is not updated", "nodeid", faultyNode.ID) 169 } 170 } 171 } 172 } 173 174 func TestTable_DeleteNodeFromDB(t *testing.T) { 175 testData1 := MustParseNode(rawUrls[0]) 176 testData2 := MustParseNode(rawUrls[1]) 177 tab, _ := createTestTable() 178 if n := tab.db.node(testData1.ID); n == nil { 179 t.Error("node does not exist", "nodeid", testData1.ID) 180 } 181 if n := tab.db.node(testData2.ID); n == nil { 182 t.Error("node does not exist", "nodeid", testData2.ID) 183 } 184 err := tab.DeleteNodeFromDB(testData1) 185 if err != nil { 186 t.Error("delete node from table is failed", "err", err) 187 } 188 err = tab.DeleteNodeFromDB(testData2) 189 if err != nil { 190 t.Error("delete node from table is failed", "err", err) 191 } 192 if n := tab.db.node(testData1.ID); n != nil { 193 t.Error("node is not removed", "nodeid", n.ID) 194 } 195 if n := tab.db.node(testData2.ID); n != nil { 196 t.Error("node is not removed", "nodeid", n.ID) 197 } 198 } 199 200 func TestTable_DeleteNodeFromTable(t *testing.T) { 201 tab, _ := createTestTable() 202 storage, _ := tab.storages[NodeTypeUnknown].(*mockDiscoveryStorage) 203 node0 := storage.data[0] 204 node1 := storage.data[1] 205 err := tab.DeleteNodeFromTable(node0) 206 if err != nil { 207 t.Error("delete node from table is failed", "err", err) 208 } 209 err = tab.DeleteNodeFromTable(node1) 210 if err != nil { 211 t.Error("delete node from table is failed", "err", err) 212 } 213 if isIn(node0, storage.data) { 214 t.Error("the node is not removed", "nodeid", node0.ID) 215 } 216 if isIn(node1, storage.data) { 217 t.Error("the node is not removed", "nodeid", node1.ID) 218 } 219 }