github.com/avence12/go-ethereum@v1.5.10-0.20170320123548-1dfd65f6d047/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/ethereum/go-ethereum/common" 25 "github.com/ethereum/go-ethereum/core/types" 26 "github.com/ethereum/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 type errCode int 69 70 const ( 71 ErrMsgTooLarge = iota 72 ErrDecode 73 ErrInvalidMsgCode 74 ErrProtocolVersionMismatch 75 ErrNetworkIdMismatch 76 ErrGenesisBlockMismatch 77 ErrNoStatusMsg 78 ErrExtraStatusMsg 79 ErrSuspendedPeer 80 ) 81 82 func (e errCode) String() string { 83 return errorToString[int(e)] 84 } 85 86 // XXX change once legacy code is out 87 var errorToString = map[int]string{ 88 ErrMsgTooLarge: "Message too long", 89 ErrDecode: "Invalid message", 90 ErrInvalidMsgCode: "Invalid message code", 91 ErrProtocolVersionMismatch: "Protocol version mismatch", 92 ErrNetworkIdMismatch: "NetworkId mismatch", 93 ErrGenesisBlockMismatch: "Genesis block mismatch", 94 ErrNoStatusMsg: "No status message", 95 ErrExtraStatusMsg: "Extra status message", 96 ErrSuspendedPeer: "Suspended peer", 97 } 98 99 type txPool interface { 100 // AddBatch should add the given transactions to the pool. 101 AddBatch([]*types.Transaction) error 102 103 // Pending should return pending transactions. 104 // The slice should be modifiable by the caller. 105 Pending() (map[common.Address]types.Transactions, error) 106 } 107 108 // statusData is the network packet for the status message. 109 type statusData struct { 110 ProtocolVersion uint32 111 NetworkId uint32 112 TD *big.Int 113 CurrentBlock common.Hash 114 GenesisBlock common.Hash 115 } 116 117 // newBlockHashesData is the network packet for the block announcements. 118 type newBlockHashesData []struct { 119 Hash common.Hash // Hash of one particular block being announced 120 Number uint64 // Number of one particular block being announced 121 } 122 123 // getBlockHeadersData represents a block header query. 124 type getBlockHeadersData struct { 125 Origin hashOrNumber // Block from which to retrieve headers 126 Amount uint64 // Maximum number of headers to retrieve 127 Skip uint64 // Blocks to skip between consecutive headers 128 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 129 } 130 131 // hashOrNumber is a combined field for specifying an origin block. 132 type hashOrNumber struct { 133 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 134 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 135 } 136 137 // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the 138 // two contained union fields. 139 func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { 140 if hn.Hash == (common.Hash{}) { 141 return rlp.Encode(w, hn.Number) 142 } 143 if hn.Number != 0 { 144 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 145 } 146 return rlp.Encode(w, hn.Hash) 147 } 148 149 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents 150 // into either a block hash or a block number. 151 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { 152 _, size, _ := s.Kind() 153 origin, err := s.Raw() 154 if err == nil { 155 switch { 156 case size == 32: 157 err = rlp.DecodeBytes(origin, &hn.Hash) 158 case size <= 8: 159 err = rlp.DecodeBytes(origin, &hn.Number) 160 default: 161 err = fmt.Errorf("invalid input size %d for origin", size) 162 } 163 } 164 return err 165 } 166 167 // newBlockData is the network packet for the block propagation message. 168 type newBlockData struct { 169 Block *types.Block 170 TD *big.Int 171 } 172 173 // blockBody represents the data content of a single block. 174 type blockBody struct { 175 Transactions []*types.Transaction // Transactions contained within a block 176 Uncles []*types.Header // Uncles contained within a block 177 } 178 179 // blockBodiesData is the network packet for block content distribution. 180 type blockBodiesData []*blockBody