github.com/arjunbeliever/ignite@v0.0.0-20220406110515-46bbbbec2587/eth/protocols/eth/protocol.go (about) 1 // Copyright 2014 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 eth 18 19 import ( 20 "errors" 21 "fmt" 22 "io" 23 "math/big" 24 25 "github.com/arjunbeliever/ignite/common" 26 "github.com/arjunbeliever/ignite/core/forkid" 27 "github.com/arjunbeliever/ignite/core/types" 28 "github.com/arjunbeliever/ignite/rlp" 29 ) 30 31 // Constants to match up protocol versions and messages 32 const ( 33 ETH66 = 66 34 ) 35 36 // ProtocolName is the official short name of the `eth` protocol used during 37 // devp2p capability negotiation. 38 const ProtocolName = "eth" 39 40 // ProtocolVersions are the supported versions of the `eth` protocol (first 41 // is primary). 42 var ProtocolVersions = []uint{ETH66} 43 44 // protocolLengths are the number of implemented message corresponding to 45 // different protocol versions. 46 var protocolLengths = map[uint]uint64{ETH66: 17} 47 48 // maxMessageSize is the maximum cap on the size of a protocol message. 49 const maxMessageSize = 10 * 1024 * 1024 50 51 const ( 52 StatusMsg = 0x00 53 NewBlockHashesMsg = 0x01 54 TransactionsMsg = 0x02 55 GetBlockHeadersMsg = 0x03 56 BlockHeadersMsg = 0x04 57 GetBlockBodiesMsg = 0x05 58 BlockBodiesMsg = 0x06 59 NewBlockMsg = 0x07 60 GetNodeDataMsg = 0x0d 61 NodeDataMsg = 0x0e 62 GetReceiptsMsg = 0x0f 63 ReceiptsMsg = 0x10 64 NewPooledTransactionHashesMsg = 0x08 65 GetPooledTransactionsMsg = 0x09 66 PooledTransactionsMsg = 0x0a 67 ) 68 69 var ( 70 errNoStatusMsg = errors.New("no status message") 71 errMsgTooLarge = errors.New("message too long") 72 errDecode = errors.New("invalid message") 73 errInvalidMsgCode = errors.New("invalid message code") 74 errProtocolVersionMismatch = errors.New("protocol version mismatch") 75 errNetworkIDMismatch = errors.New("network ID mismatch") 76 errGenesisMismatch = errors.New("genesis mismatch") 77 errForkIDRejected = errors.New("fork ID rejected") 78 ) 79 80 // Packet represents a p2p message in the `eth` protocol. 81 type Packet interface { 82 Name() string // Name returns a string corresponding to the message type. 83 Kind() byte // Kind returns the message type. 84 } 85 86 // StatusPacket is the network packet for the status message for eth/64 and later. 87 type StatusPacket struct { 88 ProtocolVersion uint32 89 NetworkID uint64 90 TD *big.Int 91 Head common.Hash 92 Genesis common.Hash 93 ForkID forkid.ID 94 } 95 96 // NewBlockHashesPacket is the network packet for the block announcements. 97 type NewBlockHashesPacket []struct { 98 Hash common.Hash // Hash of one particular block being announced 99 Number uint64 // Number of one particular block being announced 100 } 101 102 // Unpack retrieves the block hashes and numbers from the announcement packet 103 // and returns them in a split flat format that's more consistent with the 104 // internal data structures. 105 func (p *NewBlockHashesPacket) Unpack() ([]common.Hash, []uint64) { 106 var ( 107 hashes = make([]common.Hash, len(*p)) 108 numbers = make([]uint64, len(*p)) 109 ) 110 for i, body := range *p { 111 hashes[i], numbers[i] = body.Hash, body.Number 112 } 113 return hashes, numbers 114 } 115 116 // TransactionsPacket is the network packet for broadcasting new transactions. 117 type TransactionsPacket []*types.Transaction 118 119 // GetBlockHeadersPacket represents a block header query. 120 type GetBlockHeadersPacket struct { 121 Origin HashOrNumber // Block from which to retrieve headers 122 Amount uint64 // Maximum number of headers to retrieve 123 Skip uint64 // Blocks to skip between consecutive headers 124 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 125 } 126 127 // GetBlockHeadersPacket66 represents a block header query over eth/66 128 type GetBlockHeadersPacket66 struct { 129 RequestId uint64 130 *GetBlockHeadersPacket 131 } 132 133 // HashOrNumber is a combined field for specifying an origin block. 134 type HashOrNumber struct { 135 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 136 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 137 } 138 139 // EncodeRLP is a specialized encoder for HashOrNumber to encode only one of the 140 // two contained union fields. 141 func (hn *HashOrNumber) EncodeRLP(w io.Writer) error { 142 if hn.Hash == (common.Hash{}) { 143 return rlp.Encode(w, hn.Number) 144 } 145 if hn.Number != 0 { 146 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 147 } 148 return rlp.Encode(w, hn.Hash) 149 } 150 151 // DecodeRLP is a specialized decoder for HashOrNumber to decode the contents 152 // into either a block hash or a block number. 153 func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error { 154 _, size, err := s.Kind() 155 switch { 156 case err != nil: 157 return err 158 case size == 32: 159 hn.Number = 0 160 return s.Decode(&hn.Hash) 161 case size <= 8: 162 hn.Hash = common.Hash{} 163 return s.Decode(&hn.Number) 164 default: 165 return fmt.Errorf("invalid input size %d for origin", size) 166 } 167 } 168 169 // BlockHeadersPacket represents a block header response. 170 type BlockHeadersPacket []*types.Header 171 172 // BlockHeadersPacket represents a block header response over eth/66. 173 type BlockHeadersPacket66 struct { 174 RequestId uint64 175 BlockHeadersPacket 176 } 177 178 // NewBlockPacket is the network packet for the block propagation message. 179 type NewBlockPacket struct { 180 Block *types.Block 181 TD *big.Int 182 } 183 184 // sanityCheck verifies that the values are reasonable, as a DoS protection 185 func (request *NewBlockPacket) sanityCheck() error { 186 if err := request.Block.SanityCheck(); err != nil { 187 return err 188 } 189 //TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times 190 // larger, it will still fit within 100 bits 191 if tdlen := request.TD.BitLen(); tdlen > 100 { 192 return fmt.Errorf("too large block TD: bitlen %d", tdlen) 193 } 194 return nil 195 } 196 197 // GetBlockBodiesPacket represents a block body query. 198 type GetBlockBodiesPacket []common.Hash 199 200 // GetBlockBodiesPacket represents a block body query over eth/66. 201 type GetBlockBodiesPacket66 struct { 202 RequestId uint64 203 GetBlockBodiesPacket 204 } 205 206 // BlockBodiesPacket is the network packet for block content distribution. 207 type BlockBodiesPacket []*BlockBody 208 209 // BlockBodiesPacket is the network packet for block content distribution over eth/66. 210 type BlockBodiesPacket66 struct { 211 RequestId uint64 212 BlockBodiesPacket 213 } 214 215 // BlockBodiesRLPPacket is used for replying to block body requests, in cases 216 // where we already have them RLP-encoded, and thus can avoid the decode-encode 217 // roundtrip. 218 type BlockBodiesRLPPacket []rlp.RawValue 219 220 // BlockBodiesRLPPacket66 is the BlockBodiesRLPPacket over eth/66 221 type BlockBodiesRLPPacket66 struct { 222 RequestId uint64 223 BlockBodiesRLPPacket 224 } 225 226 // BlockBody represents the data content of a single block. 227 type BlockBody struct { 228 Transactions []*types.Transaction // Transactions contained within a block 229 Uncles []*types.Header // Uncles contained within a block 230 } 231 232 // Unpack retrieves the transactions and uncles from the range packet and returns 233 // them in a split flat format that's more consistent with the internal data structures. 234 func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header) { 235 var ( 236 txset = make([][]*types.Transaction, len(*p)) 237 uncleset = make([][]*types.Header, len(*p)) 238 ) 239 for i, body := range *p { 240 txset[i], uncleset[i] = body.Transactions, body.Uncles 241 } 242 return txset, uncleset 243 } 244 245 // GetNodeDataPacket represents a trie node data query. 246 type GetNodeDataPacket []common.Hash 247 248 // GetNodeDataPacket represents a trie node data query over eth/66. 249 type GetNodeDataPacket66 struct { 250 RequestId uint64 251 GetNodeDataPacket 252 } 253 254 // NodeDataPacket is the network packet for trie node data distribution. 255 type NodeDataPacket [][]byte 256 257 // NodeDataPacket is the network packet for trie node data distribution over eth/66. 258 type NodeDataPacket66 struct { 259 RequestId uint64 260 NodeDataPacket 261 } 262 263 // GetReceiptsPacket represents a block receipts query. 264 type GetReceiptsPacket []common.Hash 265 266 // GetReceiptsPacket represents a block receipts query over eth/66. 267 type GetReceiptsPacket66 struct { 268 RequestId uint64 269 GetReceiptsPacket 270 } 271 272 // ReceiptsPacket is the network packet for block receipts distribution. 273 type ReceiptsPacket [][]*types.Receipt 274 275 // ReceiptsPacket is the network packet for block receipts distribution over eth/66. 276 type ReceiptsPacket66 struct { 277 RequestId uint64 278 ReceiptsPacket 279 } 280 281 // ReceiptsRLPPacket is used for receipts, when we already have it encoded 282 type ReceiptsRLPPacket []rlp.RawValue 283 284 // ReceiptsPacket66 is the eth-66 version of ReceiptsRLPPacket 285 type ReceiptsRLPPacket66 struct { 286 RequestId uint64 287 ReceiptsRLPPacket 288 } 289 290 // NewPooledTransactionHashesPacket represents a transaction announcement packet. 291 type NewPooledTransactionHashesPacket []common.Hash 292 293 // GetPooledTransactionsPacket represents a transaction query. 294 type GetPooledTransactionsPacket []common.Hash 295 296 type GetPooledTransactionsPacket66 struct { 297 RequestId uint64 298 GetPooledTransactionsPacket 299 } 300 301 // PooledTransactionsPacket is the network packet for transaction distribution. 302 type PooledTransactionsPacket []*types.Transaction 303 304 // PooledTransactionsPacket is the network packet for transaction distribution over eth/66. 305 type PooledTransactionsPacket66 struct { 306 RequestId uint64 307 PooledTransactionsPacket 308 } 309 310 // PooledTransactionsPacket is the network packet for transaction distribution, used 311 // in the cases we already have them in rlp-encoded form 312 type PooledTransactionsRLPPacket []rlp.RawValue 313 314 // PooledTransactionsRLPPacket66 is the eth/66 form of PooledTransactionsRLPPacket 315 type PooledTransactionsRLPPacket66 struct { 316 RequestId uint64 317 PooledTransactionsRLPPacket 318 } 319 320 func (*StatusPacket) Name() string { return "Status" } 321 func (*StatusPacket) Kind() byte { return StatusMsg } 322 323 func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" } 324 func (*NewBlockHashesPacket) Kind() byte { return NewBlockHashesMsg } 325 326 func (*TransactionsPacket) Name() string { return "Transactions" } 327 func (*TransactionsPacket) Kind() byte { return TransactionsMsg } 328 329 func (*GetBlockHeadersPacket) Name() string { return "GetBlockHeaders" } 330 func (*GetBlockHeadersPacket) Kind() byte { return GetBlockHeadersMsg } 331 332 func (*BlockHeadersPacket) Name() string { return "BlockHeaders" } 333 func (*BlockHeadersPacket) Kind() byte { return BlockHeadersMsg } 334 335 func (*GetBlockBodiesPacket) Name() string { return "GetBlockBodies" } 336 func (*GetBlockBodiesPacket) Kind() byte { return GetBlockBodiesMsg } 337 338 func (*BlockBodiesPacket) Name() string { return "BlockBodies" } 339 func (*BlockBodiesPacket) Kind() byte { return BlockBodiesMsg } 340 341 func (*NewBlockPacket) Name() string { return "NewBlock" } 342 func (*NewBlockPacket) Kind() byte { return NewBlockMsg } 343 344 func (*GetNodeDataPacket) Name() string { return "GetNodeData" } 345 func (*GetNodeDataPacket) Kind() byte { return GetNodeDataMsg } 346 347 func (*NodeDataPacket) Name() string { return "NodeData" } 348 func (*NodeDataPacket) Kind() byte { return NodeDataMsg } 349 350 func (*GetReceiptsPacket) Name() string { return "GetReceipts" } 351 func (*GetReceiptsPacket) Kind() byte { return GetReceiptsMsg } 352 353 func (*ReceiptsPacket) Name() string { return "Receipts" } 354 func (*ReceiptsPacket) Kind() byte { return ReceiptsMsg } 355 356 func (*NewPooledTransactionHashesPacket) Name() string { return "NewPooledTransactionHashes" } 357 func (*NewPooledTransactionHashesPacket) Kind() byte { return NewPooledTransactionHashesMsg } 358 359 func (*GetPooledTransactionsPacket) Name() string { return "GetPooledTransactions" } 360 func (*GetPooledTransactionsPacket) Kind() byte { return GetPooledTransactionsMsg } 361 362 func (*PooledTransactionsPacket) Name() string { return "PooledTransactions" } 363 func (*PooledTransactionsPacket) Kind() byte { return PooledTransactionsMsg }