github.com/theQRL/go-zond@v0.1.1/zond/protocols/snap/protocol.go (about) 1 // Copyright 2020 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 snap 18 19 import ( 20 "errors" 21 "fmt" 22 23 "github.com/theQRL/go-zond/common" 24 "github.com/theQRL/go-zond/core/types" 25 "github.com/theQRL/go-zond/rlp" 26 ) 27 28 // Constants to match up protocol versions and messages 29 const ( 30 SNAP1 = 1 31 ) 32 33 // ProtocolName is the official short name of the `snap` protocol used during 34 // devp2p capability negotiation. 35 const ProtocolName = "snap" 36 37 // ProtocolVersions are the supported versions of the `snap` protocol (first 38 // is primary). 39 var ProtocolVersions = []uint{SNAP1} 40 41 // protocolLengths are the number of implemented message corresponding to 42 // different protocol versions. 43 var protocolLengths = map[uint]uint64{SNAP1: 8} 44 45 // maxMessageSize is the maximum cap on the size of a protocol message. 46 const maxMessageSize = 10 * 1024 * 1024 47 48 const ( 49 GetAccountRangeMsg = 0x00 50 AccountRangeMsg = 0x01 51 GetStorageRangesMsg = 0x02 52 StorageRangesMsg = 0x03 53 GetByteCodesMsg = 0x04 54 ByteCodesMsg = 0x05 55 GetTrieNodesMsg = 0x06 56 TrieNodesMsg = 0x07 57 ) 58 59 var ( 60 errMsgTooLarge = errors.New("message too long") 61 errDecode = errors.New("invalid message") 62 errInvalidMsgCode = errors.New("invalid message code") 63 errBadRequest = errors.New("bad request") 64 ) 65 66 // Packet represents a p2p message in the `snap` protocol. 67 type Packet interface { 68 Name() string // Name returns a string corresponding to the message type. 69 Kind() byte // Kind returns the message type. 70 } 71 72 // GetAccountRangePacket represents an account query. 73 type GetAccountRangePacket struct { 74 ID uint64 // Request ID to match up responses with 75 Root common.Hash // Root hash of the account trie to serve 76 Origin common.Hash // Hash of the first account to retrieve 77 Limit common.Hash // Hash of the last account to retrieve 78 Bytes uint64 // Soft limit at which to stop returning data 79 } 80 81 // AccountRangePacket represents an account query response. 82 type AccountRangePacket struct { 83 ID uint64 // ID of the request this is a response for 84 Accounts []*AccountData // List of consecutive accounts from the trie 85 Proof [][]byte // List of trie nodes proving the account range 86 } 87 88 // AccountData represents a single account in a query response. 89 type AccountData struct { 90 Hash common.Hash // Hash of the account 91 Body rlp.RawValue // Account body in slim format 92 } 93 94 // Unpack retrieves the accounts from the range packet and converts from slim 95 // wire representation to consensus format. The returned data is RLP encoded 96 // since it's expected to be serialized to disk without further interpretation. 97 // 98 // Note, this method does a round of RLP decoding and reencoding, so only use it 99 // once and cache the results if need be. Ideally discard the packet afterwards 100 // to not double the memory use. 101 func (p *AccountRangePacket) Unpack() ([]common.Hash, [][]byte, error) { 102 var ( 103 hashes = make([]common.Hash, len(p.Accounts)) 104 accounts = make([][]byte, len(p.Accounts)) 105 ) 106 for i, acc := range p.Accounts { 107 val, err := types.FullAccountRLP(acc.Body) 108 if err != nil { 109 return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err) 110 } 111 hashes[i], accounts[i] = acc.Hash, val 112 } 113 return hashes, accounts, nil 114 } 115 116 // GetStorageRangesPacket represents an storage slot query. 117 type GetStorageRangesPacket struct { 118 ID uint64 // Request ID to match up responses with 119 Root common.Hash // Root hash of the account trie to serve 120 Accounts []common.Hash // Account hashes of the storage tries to serve 121 Origin []byte // Hash of the first storage slot to retrieve (large contract mode) 122 Limit []byte // Hash of the last storage slot to retrieve (large contract mode) 123 Bytes uint64 // Soft limit at which to stop returning data 124 } 125 126 // StorageRangesPacket represents a storage slot query response. 127 type StorageRangesPacket struct { 128 ID uint64 // ID of the request this is a response for 129 Slots [][]*StorageData // Lists of consecutive storage slots for the requested accounts 130 Proof [][]byte // Merkle proofs for the *last* slot range, if it's incomplete 131 } 132 133 // StorageData represents a single storage slot in a query response. 134 type StorageData struct { 135 Hash common.Hash // Hash of the storage slot 136 Body []byte // Data content of the slot 137 } 138 139 // Unpack retrieves the storage slots from the range packet and returns them in 140 // a split flat format that's more consistent with the internal data structures. 141 func (p *StorageRangesPacket) Unpack() ([][]common.Hash, [][][]byte) { 142 var ( 143 hashset = make([][]common.Hash, len(p.Slots)) 144 slotset = make([][][]byte, len(p.Slots)) 145 ) 146 for i, slots := range p.Slots { 147 hashset[i] = make([]common.Hash, len(slots)) 148 slotset[i] = make([][]byte, len(slots)) 149 for j, slot := range slots { 150 hashset[i][j] = slot.Hash 151 slotset[i][j] = slot.Body 152 } 153 } 154 return hashset, slotset 155 } 156 157 // GetByteCodesPacket represents a contract bytecode query. 158 type GetByteCodesPacket struct { 159 ID uint64 // Request ID to match up responses with 160 Hashes []common.Hash // Code hashes to retrieve the code for 161 Bytes uint64 // Soft limit at which to stop returning data 162 } 163 164 // ByteCodesPacket represents a contract bytecode query response. 165 type ByteCodesPacket struct { 166 ID uint64 // ID of the request this is a response for 167 Codes [][]byte // Requested contract bytecodes 168 } 169 170 // GetTrieNodesPacket represents a state trie node query. 171 type GetTrieNodesPacket struct { 172 ID uint64 // Request ID to match up responses with 173 Root common.Hash // Root hash of the account trie to serve 174 Paths []TrieNodePathSet // Trie node hashes to retrieve the nodes for 175 Bytes uint64 // Soft limit at which to stop returning data 176 } 177 178 // TrieNodePathSet is a list of trie node paths to retrieve. A naive way to 179 // represent trie nodes would be a simple list of `account || storage` path 180 // segments concatenated, but that would be very wasteful on the network. 181 // 182 // Instead, this array special cases the first element as the path in the 183 // account trie and the remaining elements as paths in the storage trie. To 184 // address an account node, the slice should have a length of 1 consisting 185 // of only the account path. There's no need to be able to address both an 186 // account node and a storage node in the same request as it cannot happen 187 // that a slot is accessed before the account path is fully expanded. 188 type TrieNodePathSet [][]byte 189 190 // TrieNodesPacket represents a state trie node query response. 191 type TrieNodesPacket struct { 192 ID uint64 // ID of the request this is a response for 193 Nodes [][]byte // Requested state trie nodes 194 } 195 196 func (*GetAccountRangePacket) Name() string { return "GetAccountRange" } 197 func (*GetAccountRangePacket) Kind() byte { return GetAccountRangeMsg } 198 199 func (*AccountRangePacket) Name() string { return "AccountRange" } 200 func (*AccountRangePacket) Kind() byte { return AccountRangeMsg } 201 202 func (*GetStorageRangesPacket) Name() string { return "GetStorageRanges" } 203 func (*GetStorageRangesPacket) Kind() byte { return GetStorageRangesMsg } 204 205 func (*StorageRangesPacket) Name() string { return "StorageRanges" } 206 func (*StorageRangesPacket) Kind() byte { return StorageRangesMsg } 207 208 func (*GetByteCodesPacket) Name() string { return "GetByteCodes" } 209 func (*GetByteCodesPacket) Kind() byte { return GetByteCodesMsg } 210 211 func (*ByteCodesPacket) Name() string { return "ByteCodes" } 212 func (*ByteCodesPacket) Kind() byte { return ByteCodesMsg } 213 214 func (*GetTrieNodesPacket) Name() string { return "GetTrieNodes" } 215 func (*GetTrieNodesPacket) Kind() byte { return GetTrieNodesMsg } 216 217 func (*TrieNodesPacket) Name() string { return "TrieNodes" } 218 func (*TrieNodesPacket) Kind() byte { return TrieNodesMsg }