github.com/klaytn/klaytn@v1.12.1/node/cn/snap/peer.go (about) 1 // Modifications Copyright 2022 The klaytn Authors 2 // Copyright 2020 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from eth/protocols/snap/peer.go (2022/06/29). 19 // Modified and improved for the klaytn development. 20 21 package snap 22 23 import ( 24 "github.com/klaytn/klaytn/common" 25 "github.com/klaytn/klaytn/log" 26 "github.com/klaytn/klaytn/networks/p2p" 27 ) 28 29 // Peer is a collection of relevant information we have about a `snap` peer. 30 type Peer struct { 31 id string // Unique ID for the peer, cached 32 33 *p2p.Peer // The embedded P2P package peer 34 rw p2p.MsgReadWriter // Input/output streams for snap 35 version uint // Protocol version negotiated 36 37 logger log.Logger // Contextual logger with the peer id injected 38 } 39 40 // NewPeer create a wrapper for a network connection and negotiated protocol 41 // version. 42 func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer { 43 id := p.ID().String() 44 return &Peer{ 45 id: id[:16], 46 Peer: p, 47 rw: rw, 48 version: version, 49 logger: logger.NewWith("peer", id[:16]), 50 } 51 } 52 53 // NewFakePeer create a fake snap peer without a backing p2p peer, for testing purposes. 54 func NewFakePeer(version uint, id string, rw p2p.MsgReadWriter) *Peer { 55 return &Peer{ 56 id: id[:16], 57 rw: rw, 58 version: version, 59 logger: logger.NewWith("peer", id[:16]), 60 } 61 } 62 63 // ID retrieves the peer's unique identifier. 64 func (p *Peer) ID() string { 65 return p.id 66 } 67 68 // Version retrieves the peer's negoatiated `snap` protocol version. 69 func (p *Peer) Version() uint { 70 return p.version 71 } 72 73 // Log overrides the P2P logget with the higher level one containing only the id. 74 func (p *Peer) Log() log.Logger { 75 return p.logger 76 } 77 78 // RequestAccountRange fetches a batch of accounts rooted in a specific account 79 // trie, starting with the origin. 80 func (p *Peer) RequestAccountRange(id uint64, root common.Hash, origin, limit common.Hash, bytes uint64) error { 81 p.logger.Trace("Fetching range of accounts", "reqid", id, "root", root, "origin", origin, "limit", limit, "bytes", common.StorageSize(bytes)) 82 83 requestTracker.Track(p.id, p.version, GetAccountRangeMsg, AccountRangeMsg, id) 84 return p2p.Send(p.rw, GetAccountRangeMsg, &GetAccountRangePacket{ 85 ID: id, 86 Root: root, 87 Origin: origin, 88 Limit: limit, 89 Bytes: bytes, 90 }) 91 } 92 93 // RequestStorageRanges fetches a batch of storage slots belonging to one or more 94 // accounts. If slots from only one accout is requested, an origin marker may also 95 // be used to retrieve from there. 96 func (p *Peer) RequestStorageRanges(id uint64, root common.Hash, accounts []common.Hash, origin, limit []byte, bytes uint64) error { 97 if len(accounts) == 1 && origin != nil { 98 p.logger.Trace("Fetching range of large storage slots", "reqid", id, "root", root, "account", accounts[0], "origin", common.BytesToHash(origin), "limit", common.BytesToHash(limit), "bytes", common.StorageSize(bytes)) 99 } else { 100 p.logger.Trace("Fetching ranges of small storage slots", "reqid", id, "root", root, "accounts", len(accounts), "first", accounts[0], "bytes", common.StorageSize(bytes)) 101 } 102 requestTracker.Track(p.id, p.version, GetStorageRangesMsg, StorageRangesMsg, id) 103 return p2p.Send(p.rw, GetStorageRangesMsg, &GetStorageRangesPacket{ 104 ID: id, 105 Root: root, 106 Accounts: accounts, 107 Origin: origin, 108 Limit: limit, 109 Bytes: bytes, 110 }) 111 } 112 113 // RequestByteCodes fetches a batch of bytecodes by hash. 114 func (p *Peer) RequestByteCodes(id uint64, hashes []common.Hash, bytes uint64) error { 115 p.logger.Trace("Fetching set of byte codes", "reqid", id, "hashes", len(hashes), "bytes", common.StorageSize(bytes)) 116 117 requestTracker.Track(p.id, p.version, GetByteCodesMsg, ByteCodesMsg, id) 118 return p2p.Send(p.rw, GetByteCodesMsg, &GetByteCodesPacket{ 119 ID: id, 120 Hashes: hashes, 121 Bytes: bytes, 122 }) 123 } 124 125 // RequestTrieNodes fetches a batch of account or storage trie nodes rooted in 126 // a specificstate trie. 127 func (p *Peer) RequestTrieNodes(id uint64, root common.Hash, paths []TrieNodePathSet, bytes uint64) error { 128 p.logger.Trace("Fetching set of trie nodes", "reqid", id, "root", root, "pathsets", len(paths), "bytes", common.StorageSize(bytes)) 129 130 requestTracker.Track(p.id, p.version, GetTrieNodesMsg, TrieNodesMsg, id) 131 return p2p.Send(p.rw, GetTrieNodesMsg, &GetTrieNodesPacket{ 132 ID: id, 133 Root: root, 134 Paths: paths, 135 Bytes: bytes, 136 }) 137 }