github.com/puppeth/go-ethereum@v0.8.6-0.20171014130046-e9295163aa25/les/protocol.go (about) 1 // Copyright 2016 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 les implements the Light Ethereum Subprotocol. 18 package les 19 20 import ( 21 "fmt" 22 "io" 23 "math/big" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/rlp" 27 ) 28 29 // Constants to match up protocol versions and messages 30 const ( 31 lpv1 = 1 32 ) 33 34 // Supported versions of the les protocol (first is primary). 35 var ProtocolVersions = []uint{lpv1} 36 37 // Number of implemented message corresponding to different protocol versions. 38 var ProtocolLengths = []uint64{15} 39 40 const ( 41 NetworkId = 1 42 ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message 43 ) 44 45 // les protocol message codes 46 const ( 47 // Protocol messages belonging to LPV1 48 StatusMsg = 0x00 49 AnnounceMsg = 0x01 50 GetBlockHeadersMsg = 0x02 51 BlockHeadersMsg = 0x03 52 GetBlockBodiesMsg = 0x04 53 BlockBodiesMsg = 0x05 54 GetReceiptsMsg = 0x06 55 ReceiptsMsg = 0x07 56 GetProofsMsg = 0x08 57 ProofsMsg = 0x09 58 GetCodeMsg = 0x0a 59 CodeMsg = 0x0b 60 SendTxMsg = 0x0c 61 GetHeaderProofsMsg = 0x0d 62 HeaderProofsMsg = 0x0e 63 ) 64 65 type errCode int 66 67 const ( 68 ErrMsgTooLarge = iota 69 ErrDecode 70 ErrInvalidMsgCode 71 ErrProtocolVersionMismatch 72 ErrNetworkIdMismatch 73 ErrGenesisBlockMismatch 74 ErrNoStatusMsg 75 ErrExtraStatusMsg 76 ErrSuspendedPeer 77 ErrUselessPeer 78 ErrRequestRejected 79 ErrUnexpectedResponse 80 ErrInvalidResponse 81 ErrTooManyTimeouts 82 ErrHandshakeMissingKey 83 ) 84 85 func (e errCode) String() string { 86 return errorToString[int(e)] 87 } 88 89 // XXX change once legacy code is out 90 var errorToString = map[int]string{ 91 ErrMsgTooLarge: "Message too long", 92 ErrDecode: "Invalid message", 93 ErrInvalidMsgCode: "Invalid message code", 94 ErrProtocolVersionMismatch: "Protocol version mismatch", 95 ErrNetworkIdMismatch: "NetworkId mismatch", 96 ErrGenesisBlockMismatch: "Genesis block mismatch", 97 ErrNoStatusMsg: "No status message", 98 ErrExtraStatusMsg: "Extra status message", 99 ErrSuspendedPeer: "Suspended peer", 100 ErrRequestRejected: "Request rejected", 101 ErrUnexpectedResponse: "Unexpected response", 102 ErrInvalidResponse: "Invalid response", 103 ErrTooManyTimeouts: "Too many request timeouts", 104 ErrHandshakeMissingKey: "Key missing from handshake message", 105 } 106 107 // announceData is the network packet for the block announcements. 108 type announceData struct { 109 Hash common.Hash // Hash of one particular block being announced 110 Number uint64 // Number of one particular block being announced 111 Td *big.Int // Total difficulty of one particular block being announced 112 ReorgDepth uint64 113 Update keyValueList 114 } 115 116 type blockInfo struct { 117 Hash common.Hash // Hash of one particular block being announced 118 Number uint64 // Number of one particular block being announced 119 Td *big.Int // Total difficulty of one particular block being announced 120 } 121 122 // getBlockHeadersData represents a block header query. 123 type getBlockHeadersData struct { 124 Origin hashOrNumber // Block from which to retrieve headers 125 Amount uint64 // Maximum number of headers to retrieve 126 Skip uint64 // Blocks to skip between consecutive headers 127 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 128 } 129 130 // hashOrNumber is a combined field for specifying an origin block. 131 type hashOrNumber struct { 132 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 133 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 134 } 135 136 // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the 137 // two contained union fields. 138 func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { 139 if hn.Hash == (common.Hash{}) { 140 return rlp.Encode(w, hn.Number) 141 } 142 if hn.Number != 0 { 143 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 144 } 145 return rlp.Encode(w, hn.Hash) 146 } 147 148 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents 149 // into either a block hash or a block number. 150 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { 151 _, size, _ := s.Kind() 152 origin, err := s.Raw() 153 if err == nil { 154 switch { 155 case size == 32: 156 err = rlp.DecodeBytes(origin, &hn.Hash) 157 case size <= 8: 158 err = rlp.DecodeBytes(origin, &hn.Number) 159 default: 160 err = fmt.Errorf("invalid input size %d for origin", size) 161 } 162 } 163 return err 164 } 165 166 // CodeData is the network response packet for a node data retrieval. 167 type CodeData []struct { 168 Value []byte 169 } 170 171 type proofsData [][]rlp.RawValue