github.com/Openstars/go-ethereum@v1.9.7/les/peer_test.go (about) 1 // Copyright 2019 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 les 18 19 import ( 20 "math/big" 21 "net" 22 "testing" 23 24 "github.com/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/common/mclock" 26 "github.com/ethereum/go-ethereum/core/rawdb" 27 "github.com/ethereum/go-ethereum/crypto" 28 "github.com/ethereum/go-ethereum/eth" 29 "github.com/ethereum/go-ethereum/les/flowcontrol" 30 "github.com/ethereum/go-ethereum/p2p" 31 "github.com/ethereum/go-ethereum/p2p/enode" 32 "github.com/ethereum/go-ethereum/rlp" 33 ) 34 35 const protocolVersion = lpv2 36 37 var ( 38 hash = common.HexToHash("deadbeef") 39 genesis = common.HexToHash("cafebabe") 40 headNum = uint64(1234) 41 td = big.NewInt(123) 42 ) 43 44 func newNodeID(t *testing.T) *enode.Node { 45 key, err := crypto.GenerateKey() 46 if err != nil { 47 t.Fatal("generate key err:", err) 48 } 49 return enode.NewV4(&key.PublicKey, net.IP{}, 35000, 35000) 50 } 51 52 // ulc connects to trusted peer and send announceType=announceTypeSigned 53 func TestPeerHandshakeSetAnnounceTypeToAnnounceTypeSignedForTrustedPeer(t *testing.T) { 54 id := newNodeID(t).ID() 55 56 // peer to connect(on ulc side) 57 p := peer{ 58 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 59 version: protocolVersion, 60 trusted: true, 61 rw: &rwStub{ 62 WriteHook: func(recvList keyValueList) { 63 recv, _ := recvList.decode() 64 var reqType uint64 65 err := recv.get("announceType", &reqType) 66 if err != nil { 67 t.Fatal(err) 68 } 69 if reqType != announceTypeSigned { 70 t.Fatal("Expected announceTypeSigned") 71 } 72 }, 73 ReadHook: func(l keyValueList) keyValueList { 74 l = l.add("serveHeaders", nil) 75 l = l.add("serveChainSince", uint64(0)) 76 l = l.add("serveStateSince", uint64(0)) 77 l = l.add("txRelay", nil) 78 l = l.add("flowControl/BL", uint64(0)) 79 l = l.add("flowControl/MRR", uint64(0)) 80 l = l.add("flowControl/MRC", testCostList(0)) 81 return l 82 }, 83 }, 84 network: NetworkId, 85 } 86 err := p.Handshake(td, hash, headNum, genesis, nil) 87 if err != nil { 88 t.Fatalf("Handshake error: %s", err) 89 } 90 if p.announceType != announceTypeSigned { 91 t.Fatal("Incorrect announceType") 92 } 93 } 94 95 func TestPeerHandshakeAnnounceTypeSignedForTrustedPeersPeerNotInTrusted(t *testing.T) { 96 id := newNodeID(t).ID() 97 p := peer{ 98 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 99 version: protocolVersion, 100 rw: &rwStub{ 101 WriteHook: func(recvList keyValueList) { 102 // checking that ulc sends to peer allowedRequests=noRequests and announceType != announceTypeSigned 103 recv, _ := recvList.decode() 104 var reqType uint64 105 err := recv.get("announceType", &reqType) 106 if err != nil { 107 t.Fatal(err) 108 } 109 if reqType == announceTypeSigned { 110 t.Fatal("Expected not announceTypeSigned") 111 } 112 }, 113 ReadHook: func(l keyValueList) keyValueList { 114 l = l.add("serveHeaders", nil) 115 l = l.add("serveChainSince", uint64(0)) 116 l = l.add("serveStateSince", uint64(0)) 117 l = l.add("txRelay", nil) 118 l = l.add("flowControl/BL", uint64(0)) 119 l = l.add("flowControl/MRR", uint64(0)) 120 l = l.add("flowControl/MRC", testCostList(0)) 121 return l 122 }, 123 }, 124 network: NetworkId, 125 } 126 err := p.Handshake(td, hash, headNum, genesis, nil) 127 if err != nil { 128 t.Fatal(err) 129 } 130 if p.announceType == announceTypeSigned { 131 t.Fatal("Incorrect announceType") 132 } 133 } 134 135 func TestPeerHandshakeDefaultAllRequests(t *testing.T) { 136 id := newNodeID(t).ID() 137 138 s := generateLesServer() 139 140 p := peer{ 141 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 142 version: protocolVersion, 143 rw: &rwStub{ 144 ReadHook: func(l keyValueList) keyValueList { 145 l = l.add("announceType", uint64(announceTypeSigned)) 146 l = l.add("allowedRequests", uint64(0)) 147 return l 148 }, 149 }, 150 network: NetworkId, 151 } 152 153 err := p.Handshake(td, hash, headNum, genesis, s) 154 if err != nil { 155 t.Fatal(err) 156 } 157 158 if p.onlyAnnounce { 159 t.Fatal("Incorrect announceType") 160 } 161 } 162 163 func TestPeerHandshakeServerSendOnlyAnnounceRequestsHeaders(t *testing.T) { 164 id := newNodeID(t).ID() 165 166 s := generateLesServer() 167 s.config.UltraLightOnlyAnnounce = true 168 169 p := peer{ 170 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 171 version: protocolVersion, 172 rw: &rwStub{ 173 ReadHook: func(l keyValueList) keyValueList { 174 l = l.add("announceType", uint64(announceTypeSigned)) 175 return l 176 }, 177 WriteHook: func(l keyValueList) { 178 for _, v := range l { 179 if v.Key == "serveHeaders" || 180 v.Key == "serveChainSince" || 181 v.Key == "serveStateSince" || 182 v.Key == "txRelay" { 183 t.Fatalf("%v exists", v.Key) 184 } 185 } 186 }, 187 }, 188 network: NetworkId, 189 } 190 191 err := p.Handshake(td, hash, headNum, genesis, s) 192 if err != nil { 193 t.Fatal(err) 194 } 195 } 196 func TestPeerHandshakeClientReceiveOnlyAnnounceRequestsHeaders(t *testing.T) { 197 id := newNodeID(t).ID() 198 199 p := peer{ 200 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 201 version: protocolVersion, 202 rw: &rwStub{ 203 ReadHook: func(l keyValueList) keyValueList { 204 l = l.add("flowControl/BL", uint64(0)) 205 l = l.add("flowControl/MRR", uint64(0)) 206 l = l.add("flowControl/MRC", RequestCostList{}) 207 208 l = l.add("announceType", uint64(announceTypeSigned)) 209 210 return l 211 }, 212 }, 213 network: NetworkId, 214 trusted: true, 215 } 216 217 err := p.Handshake(td, hash, headNum, genesis, nil) 218 if err != nil { 219 t.Fatal(err) 220 } 221 222 if !p.onlyAnnounce { 223 t.Fatal("onlyAnnounce must be true") 224 } 225 } 226 227 func TestPeerHandshakeClientReturnErrorOnUselessPeer(t *testing.T) { 228 id := newNodeID(t).ID() 229 230 p := peer{ 231 Peer: p2p.NewPeer(id, "test peer", []p2p.Cap{}), 232 version: protocolVersion, 233 rw: &rwStub{ 234 ReadHook: func(l keyValueList) keyValueList { 235 l = l.add("flowControl/BL", uint64(0)) 236 l = l.add("flowControl/MRR", uint64(0)) 237 l = l.add("flowControl/MRC", RequestCostList{}) 238 l = l.add("announceType", uint64(announceTypeSigned)) 239 return l 240 }, 241 }, 242 network: NetworkId, 243 } 244 245 err := p.Handshake(td, hash, headNum, genesis, nil) 246 if err == nil { 247 t.FailNow() 248 } 249 } 250 251 func generateLesServer() *LesServer { 252 s := &LesServer{ 253 lesCommons: lesCommons{ 254 config: ð.Config{UltraLightOnlyAnnounce: true}, 255 }, 256 defParams: flowcontrol.ServerParams{ 257 BufLimit: uint64(300000000), 258 MinRecharge: uint64(50000), 259 }, 260 fcManager: flowcontrol.NewClientManager(nil, &mclock.System{}), 261 } 262 s.costTracker, _ = newCostTracker(rawdb.NewMemoryDatabase(), s.config) 263 return s 264 } 265 266 type rwStub struct { 267 ReadHook func(l keyValueList) keyValueList 268 WriteHook func(l keyValueList) 269 } 270 271 func (s *rwStub) ReadMsg() (p2p.Msg, error) { 272 payload := keyValueList{} 273 payload = payload.add("protocolVersion", uint64(protocolVersion)) 274 payload = payload.add("networkId", uint64(NetworkId)) 275 payload = payload.add("headTd", td) 276 payload = payload.add("headHash", hash) 277 payload = payload.add("headNum", headNum) 278 payload = payload.add("genesisHash", genesis) 279 280 if s.ReadHook != nil { 281 payload = s.ReadHook(payload) 282 } 283 size, p, err := rlp.EncodeToReader(payload) 284 if err != nil { 285 return p2p.Msg{}, err 286 } 287 return p2p.Msg{ 288 Size: uint32(size), 289 Payload: p, 290 }, nil 291 } 292 293 func (s *rwStub) WriteMsg(m p2p.Msg) error { 294 recvList := keyValueList{} 295 if err := m.Decode(&recvList); err != nil { 296 return err 297 } 298 if s.WriteHook != nil { 299 s.WriteHook(recvList) 300 } 301 return nil 302 }