github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/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 "fmt" 21 "io" 22 "math/big" 23 24 "github.com/ethereumproject/go-ethereum/common" 25 "github.com/ethereumproject/go-ethereum/core/types" 26 "github.com/ethereumproject/go-ethereum/rlp" 27 ) 28 29 // Constants to match up protocol versions and messages 30 const ( 31 eth62 = 62 32 eth63 = 63 33 ) 34 35 // Official short name of the protocol used during capability negotiation. 36 var ProtocolName = "eth" 37 38 // Supported versions of the eth protocol (first is primary). 39 var ProtocolVersions = []uint{eth63, eth62} 40 41 // Number of implemented message corresponding to different protocol versions. 42 var ProtocolLengths = []uint64{17, 8} 43 44 const ( 45 NetworkId = 1 46 ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message 47 ) 48 49 // eth protocol message codes 50 const ( 51 // Protocol messages belonging to eth/62 52 StatusMsg = 0x00 53 NewBlockHashesMsg = 0x01 54 TxMsg = 0x02 55 GetBlockHeadersMsg = 0x03 56 BlockHeadersMsg = 0x04 57 GetBlockBodiesMsg = 0x05 58 BlockBodiesMsg = 0x06 59 NewBlockMsg = 0x07 60 61 // Protocol messages belonging to eth/63 62 GetNodeDataMsg = 0x0d 63 NodeDataMsg = 0x0e 64 GetReceiptsMsg = 0x0f 65 ReceiptsMsg = 0x10 66 ) 67 68 func ProtocolMessageStringer(m uint) string { 69 switch m { 70 case StatusMsg: 71 return "Status" 72 case NewBlockHashesMsg: 73 return "NewBlockHashes" 74 case TxMsg: 75 return "Txs" 76 case GetBlockHeadersMsg: 77 return "GetBlockHeaders" 78 case BlockHeadersMsg: 79 return "BlockHeaders" 80 case GetBlockBodiesMsg: 81 return "GetBlockBodies" 82 case BlockBodiesMsg: 83 return "BlockBodies" 84 case NewBlockMsg: 85 return "NewBlock" 86 case GetNodeDataMsg: 87 return "GetNodeData" 88 case NodeDataMsg: 89 return "NodeData" 90 case GetReceiptsMsg: 91 return "GetReceipts" 92 case ReceiptsMsg: 93 return "Receipts" 94 default: 95 return "Unknown" 96 } 97 } 98 99 type errCode int 100 101 const ( 102 ErrMsgTooLarge = iota 103 ErrDecode 104 ErrInvalidMsgCode 105 ErrProtocolVersionMismatch 106 ErrNetworkIdMismatch 107 ErrGenesisBlockMismatch 108 ErrNoStatusMsg 109 ErrExtraStatusMsg 110 ErrSuspendedPeer 111 ) 112 113 func (e errCode) String() string { 114 return errorToString[int(e)] 115 } 116 117 // XXX change once legacy code is out 118 var errorToString = map[int]string{ 119 ErrMsgTooLarge: "Message too long", 120 ErrDecode: "Invalid message", 121 ErrInvalidMsgCode: "Invalid message code", 122 ErrProtocolVersionMismatch: "Protocol version mismatch", 123 ErrNetworkIdMismatch: "NetworkId mismatch", 124 ErrGenesisBlockMismatch: "Genesis block mismatch", 125 ErrNoStatusMsg: "No status message", 126 ErrExtraStatusMsg: "Extra status message", 127 ErrSuspendedPeer: "Suspended peer", 128 } 129 130 type txPool interface { 131 // AddTransactions should add the given transactions to the pool. 132 AddTransactions([]*types.Transaction) 133 134 // GetTransactions should return pending transactions. 135 // The slice should be modifiable by the caller. 136 GetTransactions() types.Transactions 137 } 138 139 // statusData is the network packet for the status message. 140 type statusData struct { 141 ProtocolVersion uint32 142 NetworkId uint32 143 TD *big.Int 144 CurrentBlock common.Hash 145 GenesisBlock common.Hash 146 } 147 148 // newBlockData is the network packet for the block propagation message. 149 type newBlockData struct { 150 Block *types.Block 151 TD *big.Int 152 } 153 154 // blockBody represents the data content of a single block. 155 type blockBody struct { 156 Transactions []*types.Transaction // Transactions contained within a block 157 Uncles []*types.Header // Uncles contained within a block 158 } 159 160 // blockBodiesData is the network packet for block content distribution. 161 type blockBodiesData []*blockBody 162 163 // announce is received with NewBlockHashesMsg 164 type announce struct { 165 Hash common.Hash // Hash of one particular block being announced 166 Number uint64 // Number of one particular block being announced 167 } 168 169 // newBlockHashesData is the network packet for the block announcements. 170 type newBlockHashesData []announce 171 172 // getBlockHeadersData represents a block header query. 173 type getBlockHeadersData struct { 174 Origin hashOrNumber // Block from which to retrieve headers 175 Amount uint64 // Maximum number of headers to retrieve 176 Skip uint64 // Blocks to skip between consecutive headers 177 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 178 } 179 180 // hashOrNumber is a combined field for specifying an origin block. 181 type hashOrNumber struct { 182 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 183 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 184 } 185 186 // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the 187 // two contained union fields. 188 func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { 189 if hn.Hash == (common.Hash{}) { 190 return rlp.Encode(w, hn.Number) 191 } 192 if hn.Number != 0 { 193 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 194 } 195 return rlp.Encode(w, hn.Hash) 196 } 197 198 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents 199 // into either a block hash or a block number. 200 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { 201 _, size, _ := s.Kind() 202 origin, err := s.Raw() 203 if err == nil { 204 switch { 205 case size == 32: 206 err = rlp.DecodeBytes(origin, &hn.Hash) 207 case size <= 8: 208 err = rlp.DecodeBytes(origin, &hn.Number) 209 default: 210 err = fmt.Errorf("invalid input size %d for origin", size) 211 } 212 } 213 return err 214 }