github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/les/peer.go (about) 1 // Copyright 2016 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 implements the Light Ethereum Subprotocol. 18 package les 19 20 import ( 21 "errors" 22 "fmt" 23 "math/big" 24 "sync" 25 26 "github.com/atheioschain/go-atheios/common" 27 "github.com/atheioschain/go-atheios/core/types" 28 "github.com/atheioschain/go-atheios/eth" 29 "github.com/atheioschain/go-atheios/les/flowcontrol" 30 "github.com/atheioschain/go-atheios/logger" 31 "github.com/atheioschain/go-atheios/logger/glog" 32 "github.com/atheioschain/go-atheios/p2p" 33 "github.com/atheioschain/go-atheios/rlp" 34 ) 35 36 var ( 37 errClosed = errors.New("peer set is closed") 38 errAlreadyRegistered = errors.New("peer is already registered") 39 errNotRegistered = errors.New("peer is not registered") 40 ) 41 42 const maxHeadInfoLen = 20 43 44 type peer struct { 45 *p2p.Peer 46 47 rw p2p.MsgReadWriter 48 49 version int // Protocol version negotiated 50 network int // Network ID being on 51 52 id string 53 54 headInfo *announceData 55 lock sync.RWMutex 56 57 announceChn chan announceData 58 59 poolEntry *poolEntry 60 hasBlock func(common.Hash, uint64) bool 61 62 fcClient *flowcontrol.ClientNode // nil if the peer is server only 63 fcServer *flowcontrol.ServerNode // nil if the peer is client only 64 fcServerParams *flowcontrol.ServerParams 65 fcCosts requestCostTable 66 } 67 68 func newPeer(version, network int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer { 69 id := p.ID() 70 71 return &peer{ 72 Peer: p, 73 rw: rw, 74 version: version, 75 network: network, 76 id: fmt.Sprintf("%x", id[:8]), 77 announceChn: make(chan announceData, 20), 78 } 79 } 80 81 // Info gathers and returns a collection of metadata known about a peer. 82 func (p *peer) Info() *eth.PeerInfo { 83 return ð.PeerInfo{ 84 Version: p.version, 85 Difficulty: p.Td(), 86 Head: fmt.Sprintf("%x", p.Head()), 87 } 88 } 89 90 // Head retrieves a copy of the current head (most recent) hash of the peer. 91 func (p *peer) Head() (hash common.Hash) { 92 p.lock.RLock() 93 defer p.lock.RUnlock() 94 95 copy(hash[:], p.headInfo.Hash[:]) 96 return hash 97 } 98 99 func (p *peer) HeadAndTd() (hash common.Hash, td *big.Int) { 100 p.lock.RLock() 101 defer p.lock.RUnlock() 102 103 copy(hash[:], p.headInfo.Hash[:]) 104 return hash, p.headInfo.Td 105 } 106 107 func (p *peer) headBlockInfo() blockInfo { 108 p.lock.RLock() 109 defer p.lock.RUnlock() 110 111 return blockInfo{Hash: p.headInfo.Hash, Number: p.headInfo.Number, Td: p.headInfo.Td} 112 } 113 114 // Td retrieves the current total difficulty of a peer. 115 func (p *peer) Td() *big.Int { 116 p.lock.RLock() 117 defer p.lock.RUnlock() 118 119 return new(big.Int).Set(p.headInfo.Td) 120 } 121 122 func sendRequest(w p2p.MsgWriter, msgcode, reqID, cost uint64, data interface{}) error { 123 type req struct { 124 ReqID uint64 125 Data interface{} 126 } 127 return p2p.Send(w, msgcode, req{reqID, data}) 128 } 129 130 func sendResponse(w p2p.MsgWriter, msgcode, reqID, bv uint64, data interface{}) error { 131 type resp struct { 132 ReqID, BV uint64 133 Data interface{} 134 } 135 return p2p.Send(w, msgcode, resp{reqID, bv, data}) 136 } 137 138 func (p *peer) GetRequestCost(msgcode uint64, amount int) uint64 { 139 p.lock.RLock() 140 defer p.lock.RUnlock() 141 142 cost := p.fcCosts[msgcode].baseCost + p.fcCosts[msgcode].reqCost*uint64(amount) 143 if cost > p.fcServerParams.BufLimit { 144 cost = p.fcServerParams.BufLimit 145 } 146 return cost 147 } 148 149 // HasBlock checks if the peer has a given block 150 func (p *peer) HasBlock(hash common.Hash, number uint64) bool { 151 p.lock.RLock() 152 hashBlock := p.hasBlock 153 p.lock.RUnlock() 154 return hashBlock != nil && hashBlock(hash, number) 155 } 156 157 // SendAnnounce announces the availability of a number of blocks through 158 // a hash notification. 159 func (p *peer) SendAnnounce(request announceData) error { 160 return p2p.Send(p.rw, AnnounceMsg, request) 161 } 162 163 // SendBlockHeaders sends a batch of block headers to the remote peer. 164 func (p *peer) SendBlockHeaders(reqID, bv uint64, headers []*types.Header) error { 165 return sendResponse(p.rw, BlockHeadersMsg, reqID, bv, headers) 166 } 167 168 // SendBlockBodiesRLP sends a batch of block contents to the remote peer from 169 // an already RLP encoded format. 170 func (p *peer) SendBlockBodiesRLP(reqID, bv uint64, bodies []rlp.RawValue) error { 171 return sendResponse(p.rw, BlockBodiesMsg, reqID, bv, bodies) 172 } 173 174 // SendCodeRLP sends a batch of arbitrary internal data, corresponding to the 175 // hashes requested. 176 func (p *peer) SendCode(reqID, bv uint64, data [][]byte) error { 177 return sendResponse(p.rw, CodeMsg, reqID, bv, data) 178 } 179 180 // SendReceiptsRLP sends a batch of transaction receipts, corresponding to the 181 // ones requested from an already RLP encoded format. 182 func (p *peer) SendReceiptsRLP(reqID, bv uint64, receipts []rlp.RawValue) error { 183 return sendResponse(p.rw, ReceiptsMsg, reqID, bv, receipts) 184 } 185 186 // SendProofs sends a batch of merkle proofs, corresponding to the ones requested. 187 func (p *peer) SendProofs(reqID, bv uint64, proofs proofsData) error { 188 return sendResponse(p.rw, ProofsMsg, reqID, bv, proofs) 189 } 190 191 // SendHeaderProofs sends a batch of header proofs, corresponding to the ones requested. 192 func (p *peer) SendHeaderProofs(reqID, bv uint64, proofs []ChtResp) error { 193 return sendResponse(p.rw, HeaderProofsMsg, reqID, bv, proofs) 194 } 195 196 // RequestHeadersByHash fetches a batch of blocks' headers corresponding to the 197 // specified header query, based on the hash of an origin block. 198 func (p *peer) RequestHeadersByHash(reqID, cost uint64, origin common.Hash, amount int, skip int, reverse bool) error { 199 glog.V(logger.Debug).Infof("%v fetching %d headers from %x, skipping %d (reverse = %v)", p, amount, origin[:4], skip, reverse) 200 return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 201 } 202 203 // RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the 204 // specified header query, based on the number of an origin block. 205 func (p *peer) RequestHeadersByNumber(reqID, cost, origin uint64, amount int, skip int, reverse bool) error { 206 glog.V(logger.Debug).Infof("%v fetching %d headers from #%d, skipping %d (reverse = %v)", p, amount, origin, skip, reverse) 207 return sendRequest(p.rw, GetBlockHeadersMsg, reqID, cost, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}) 208 } 209 210 // RequestBodies fetches a batch of blocks' bodies corresponding to the hashes 211 // specified. 212 func (p *peer) RequestBodies(reqID, cost uint64, hashes []common.Hash) error { 213 glog.V(logger.Debug).Infof("%v fetching %d block bodies", p, len(hashes)) 214 return sendRequest(p.rw, GetBlockBodiesMsg, reqID, cost, hashes) 215 } 216 217 // RequestCode fetches a batch of arbitrary data from a node's known state 218 // data, corresponding to the specified hashes. 219 func (p *peer) RequestCode(reqID, cost uint64, reqs []*CodeReq) error { 220 glog.V(logger.Debug).Infof("%v fetching %v state data", p, len(reqs)) 221 return sendRequest(p.rw, GetCodeMsg, reqID, cost, reqs) 222 } 223 224 // RequestReceipts fetches a batch of transaction receipts from a remote node. 225 func (p *peer) RequestReceipts(reqID, cost uint64, hashes []common.Hash) error { 226 glog.V(logger.Debug).Infof("%v fetching %v receipts", p, len(hashes)) 227 return sendRequest(p.rw, GetReceiptsMsg, reqID, cost, hashes) 228 } 229 230 // RequestProofs fetches a batch of merkle proofs from a remote node. 231 func (p *peer) RequestProofs(reqID, cost uint64, reqs []*ProofReq) error { 232 glog.V(logger.Debug).Infof("%v fetching %v proofs", p, len(reqs)) 233 return sendRequest(p.rw, GetProofsMsg, reqID, cost, reqs) 234 } 235 236 // RequestHeaderProofs fetches a batch of header merkle proofs from a remote node. 237 func (p *peer) RequestHeaderProofs(reqID, cost uint64, reqs []*ChtReq) error { 238 glog.V(logger.Debug).Infof("%v fetching %v header proofs", p, len(reqs)) 239 return sendRequest(p.rw, GetHeaderProofsMsg, reqID, cost, reqs) 240 } 241 242 func (p *peer) SendTxs(cost uint64, txs types.Transactions) error { 243 glog.V(logger.Debug).Infof("%v relaying %v txs", p, len(txs)) 244 reqID := getNextReqID() 245 p.fcServer.MustAssignRequest(reqID) 246 p.fcServer.SendRequest(reqID, cost) 247 return p2p.Send(p.rw, SendTxMsg, txs) 248 } 249 250 type keyValueEntry struct { 251 Key string 252 Value rlp.RawValue 253 } 254 type keyValueList []keyValueEntry 255 type keyValueMap map[string]rlp.RawValue 256 257 func (l keyValueList) add(key string, val interface{}) keyValueList { 258 var entry keyValueEntry 259 entry.Key = key 260 if val == nil { 261 val = uint64(0) 262 } 263 enc, err := rlp.EncodeToBytes(val) 264 if err == nil { 265 entry.Value = enc 266 } 267 return append(l, entry) 268 } 269 270 func (l keyValueList) decode() keyValueMap { 271 m := make(keyValueMap) 272 for _, entry := range l { 273 m[entry.Key] = entry.Value 274 } 275 return m 276 } 277 278 func (m keyValueMap) get(key string, val interface{}) error { 279 enc, ok := m[key] 280 if !ok { 281 return errResp(ErrHandshakeMissingKey, "%s", key) 282 } 283 if val == nil { 284 return nil 285 } 286 return rlp.DecodeBytes(enc, val) 287 } 288 289 func (p *peer) sendReceiveHandshake(sendList keyValueList) (keyValueList, error) { 290 // Send out own handshake in a new thread 291 errc := make(chan error, 1) 292 go func() { 293 errc <- p2p.Send(p.rw, StatusMsg, sendList) 294 }() 295 // In the mean time retrieve the remote status message 296 msg, err := p.rw.ReadMsg() 297 if err != nil { 298 return nil, err 299 } 300 if msg.Code != StatusMsg { 301 return nil, errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg) 302 } 303 if msg.Size > ProtocolMaxMsgSize { 304 return nil, errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize) 305 } 306 // Decode the handshake 307 var recvList keyValueList 308 if err := msg.Decode(&recvList); err != nil { 309 return nil, errResp(ErrDecode, "msg %v: %v", msg, err) 310 } 311 if err := <-errc; err != nil { 312 return nil, err 313 } 314 return recvList, nil 315 } 316 317 // Handshake executes the les protocol handshake, negotiating version number, 318 // network IDs, difficulties, head and genesis blocks. 319 func (p *peer) Handshake(td *big.Int, head common.Hash, headNum uint64, genesis common.Hash, server *LesServer) error { 320 p.lock.Lock() 321 defer p.lock.Unlock() 322 323 var send keyValueList 324 send = send.add("protocolVersion", uint64(p.version)) 325 send = send.add("networkId", uint64(p.network)) 326 send = send.add("headTd", td) 327 send = send.add("headHash", head) 328 send = send.add("headNum", headNum) 329 send = send.add("genesisHash", genesis) 330 if server != nil { 331 send = send.add("serveHeaders", nil) 332 send = send.add("serveChainSince", uint64(0)) 333 send = send.add("serveStateSince", uint64(0)) 334 send = send.add("txRelay", nil) 335 send = send.add("flowControl/BL", server.defParams.BufLimit) 336 send = send.add("flowControl/MRR", server.defParams.MinRecharge) 337 list := server.fcCostStats.getCurrentList() 338 send = send.add("flowControl/MRC", list) 339 p.fcCosts = list.decode() 340 } 341 recvList, err := p.sendReceiveHandshake(send) 342 if err != nil { 343 return err 344 } 345 recv := recvList.decode() 346 347 var rGenesis, rHash common.Hash 348 var rVersion, rNetwork, rNum uint64 349 var rTd *big.Int 350 351 if err := recv.get("protocolVersion", &rVersion); err != nil { 352 return err 353 } 354 if err := recv.get("networkId", &rNetwork); err != nil { 355 return err 356 } 357 if err := recv.get("headTd", &rTd); err != nil { 358 return err 359 } 360 if err := recv.get("headHash", &rHash); err != nil { 361 return err 362 } 363 if err := recv.get("headNum", &rNum); err != nil { 364 return err 365 } 366 if err := recv.get("genesisHash", &rGenesis); err != nil { 367 return err 368 } 369 370 if rGenesis != genesis { 371 return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", rGenesis, genesis) 372 } 373 if int(rNetwork) != p.network { 374 return errResp(ErrNetworkIdMismatch, "%d (!= %d)", rNetwork, p.network) 375 } 376 if int(rVersion) != p.version { 377 return errResp(ErrProtocolVersionMismatch, "%d (!= %d)", rVersion, p.version) 378 } 379 if server != nil { 380 if recv.get("serveStateSince", nil) == nil { 381 return errResp(ErrUselessPeer, "wanted client, got server") 382 } 383 p.fcClient = flowcontrol.NewClientNode(server.fcManager, server.defParams) 384 } else { 385 if recv.get("serveChainSince", nil) != nil { 386 return errResp(ErrUselessPeer, "peer cannot serve chain") 387 } 388 if recv.get("serveStateSince", nil) != nil { 389 return errResp(ErrUselessPeer, "peer cannot serve state") 390 } 391 if recv.get("txRelay", nil) != nil { 392 return errResp(ErrUselessPeer, "peer cannot relay transactions") 393 } 394 params := &flowcontrol.ServerParams{} 395 if err := recv.get("flowControl/BL", ¶ms.BufLimit); err != nil { 396 return err 397 } 398 if err := recv.get("flowControl/MRR", ¶ms.MinRecharge); err != nil { 399 return err 400 } 401 var MRC RequestCostList 402 if err := recv.get("flowControl/MRC", &MRC); err != nil { 403 return err 404 } 405 p.fcServerParams = params 406 p.fcServer = flowcontrol.NewServerNode(params) 407 p.fcCosts = MRC.decode() 408 } 409 410 p.headInfo = &announceData{Td: rTd, Hash: rHash, Number: rNum} 411 return nil 412 } 413 414 // String implements fmt.Stringer. 415 func (p *peer) String() string { 416 return fmt.Sprintf("Peer %s [%s]", p.id, 417 fmt.Sprintf("les/%d", p.version), 418 ) 419 } 420 421 // peerSet represents the collection of active peers currently participating in 422 // the Light Ethereum sub-protocol. 423 type peerSet struct { 424 peers map[string]*peer 425 lock sync.RWMutex 426 closed bool 427 } 428 429 // newPeerSet creates a new peer set to track the active participants. 430 func newPeerSet() *peerSet { 431 return &peerSet{ 432 peers: make(map[string]*peer), 433 } 434 } 435 436 // Register injects a new peer into the working set, or returns an error if the 437 // peer is already known. 438 func (ps *peerSet) Register(p *peer) error { 439 ps.lock.Lock() 440 defer ps.lock.Unlock() 441 442 if ps.closed { 443 return errClosed 444 } 445 if _, ok := ps.peers[p.id]; ok { 446 return errAlreadyRegistered 447 } 448 ps.peers[p.id] = p 449 return nil 450 } 451 452 // Unregister removes a remote peer from the active set, disabling any further 453 // actions to/from that particular entity. 454 func (ps *peerSet) Unregister(id string) error { 455 ps.lock.Lock() 456 defer ps.lock.Unlock() 457 458 if _, ok := ps.peers[id]; !ok { 459 return errNotRegistered 460 } 461 delete(ps.peers, id) 462 return nil 463 } 464 465 // AllPeerIDs returns a list of all registered peer IDs 466 func (ps *peerSet) AllPeerIDs() []string { 467 ps.lock.RLock() 468 defer ps.lock.RUnlock() 469 470 res := make([]string, len(ps.peers)) 471 idx := 0 472 for id := range ps.peers { 473 res[idx] = id 474 idx++ 475 } 476 return res 477 } 478 479 // Peer retrieves the registered peer with the given id. 480 func (ps *peerSet) Peer(id string) *peer { 481 ps.lock.RLock() 482 defer ps.lock.RUnlock() 483 484 return ps.peers[id] 485 } 486 487 // Len returns if the current number of peers in the set. 488 func (ps *peerSet) Len() int { 489 ps.lock.RLock() 490 defer ps.lock.RUnlock() 491 492 return len(ps.peers) 493 } 494 495 // BestPeer retrieves the known peer with the currently highest total difficulty. 496 func (ps *peerSet) BestPeer() *peer { 497 ps.lock.RLock() 498 defer ps.lock.RUnlock() 499 500 var ( 501 bestPeer *peer 502 bestTd *big.Int 503 ) 504 for _, p := range ps.peers { 505 if td := p.Td(); bestPeer == nil || td.Cmp(bestTd) > 0 { 506 bestPeer, bestTd = p, td 507 } 508 } 509 return bestPeer 510 } 511 512 // AllPeers returns all peers in a list 513 func (ps *peerSet) AllPeers() []*peer { 514 ps.lock.RLock() 515 defer ps.lock.RUnlock() 516 517 list := make([]*peer, len(ps.peers)) 518 i := 0 519 for _, peer := range ps.peers { 520 list[i] = peer 521 i++ 522 } 523 return list 524 } 525 526 // Close disconnects all peers. 527 // No new peers can be registered after Close has returned. 528 func (ps *peerSet) Close() { 529 ps.lock.Lock() 530 defer ps.lock.Unlock() 531 532 for _, p := range ps.peers { 533 p.Disconnect(p2p.DiscQuitting) 534 } 535 ps.closed = true 536 }