github.com/nitinawathare/ethereumassignment3@v0.0.0-20211021213010-f07344c2b868/go-ethereum/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 18 19 import ( 20 "crypto/ecdsa" 21 "errors" 22 "fmt" 23 "io" 24 "math/big" 25 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/core" 28 "github.com/ethereum/go-ethereum/core/rawdb" 29 "github.com/ethereum/go-ethereum/crypto" 30 "github.com/ethereum/go-ethereum/p2p/enode" 31 "github.com/ethereum/go-ethereum/rlp" 32 ) 33 34 // Constants to match up protocol versions and messages 35 const ( 36 lpv2 = 2 37 ) 38 39 // Supported versions of the les protocol (first is primary) 40 var ( 41 ClientProtocolVersions = []uint{lpv2} 42 ServerProtocolVersions = []uint{lpv2} 43 AdvertiseProtocolVersions = []uint{lpv2} // clients are searching for the first advertised protocol in the list 44 ) 45 46 // Number of implemented message corresponding to different protocol versions. 47 var ProtocolLengths = map[uint]uint64{lpv2: 22} 48 49 const ( 50 NetworkId = 1 51 ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message 52 ) 53 54 // les protocol message codes 55 const ( 56 // Protocol messages inherited from LPV1 57 StatusMsg = 0x00 58 AnnounceMsg = 0x01 59 GetBlockHeadersMsg = 0x02 60 BlockHeadersMsg = 0x03 61 GetBlockBodiesMsg = 0x04 62 BlockBodiesMsg = 0x05 63 GetReceiptsMsg = 0x06 64 ReceiptsMsg = 0x07 65 GetCodeMsg = 0x0a 66 CodeMsg = 0x0b 67 // Protocol messages introduced in LPV2 68 GetProofsV2Msg = 0x0f 69 ProofsV2Msg = 0x10 70 GetHelperTrieProofsMsg = 0x11 71 HelperTrieProofsMsg = 0x12 72 SendTxV2Msg = 0x13 73 GetTxStatusMsg = 0x14 74 TxStatusMsg = 0x15 75 ) 76 77 type requestInfo struct { 78 name string 79 maxCount uint64 80 } 81 82 var requests = map[uint64]requestInfo{ 83 GetBlockHeadersMsg: {"GetBlockHeaders", MaxHeaderFetch}, 84 GetBlockBodiesMsg: {"GetBlockBodies", MaxBodyFetch}, 85 GetReceiptsMsg: {"GetReceipts", MaxReceiptFetch}, 86 GetCodeMsg: {"GetCode", MaxCodeFetch}, 87 GetProofsV2Msg: {"GetProofsV2", MaxProofsFetch}, 88 GetHelperTrieProofsMsg: {"GetHelperTrieProofs", MaxHelperTrieProofsFetch}, 89 SendTxV2Msg: {"SendTxV2", MaxTxSend}, 90 GetTxStatusMsg: {"GetTxStatus", MaxTxStatus}, 91 } 92 93 type errCode int 94 95 const ( 96 ErrMsgTooLarge = iota 97 ErrDecode 98 ErrInvalidMsgCode 99 ErrProtocolVersionMismatch 100 ErrNetworkIdMismatch 101 ErrGenesisBlockMismatch 102 ErrNoStatusMsg 103 ErrExtraStatusMsg 104 ErrSuspendedPeer 105 ErrUselessPeer 106 ErrRequestRejected 107 ErrUnexpectedResponse 108 ErrInvalidResponse 109 ErrTooManyTimeouts 110 ErrMissingKey 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 ErrRequestRejected: "Request rejected", 129 ErrUnexpectedResponse: "Unexpected response", 130 ErrInvalidResponse: "Invalid response", 131 ErrTooManyTimeouts: "Too many request timeouts", 132 ErrMissingKey: "Key missing from list", 133 } 134 135 type announceBlock struct { 136 Hash common.Hash // Hash of one particular block being announced 137 Number uint64 // Number of one particular block being announced 138 Td *big.Int // Total difficulty of one particular block being announced 139 } 140 141 // announceData is the network packet for the block announcements. 142 type announceData struct { 143 Hash common.Hash // Hash of one particular block being announced 144 Number uint64 // Number of one particular block being announced 145 Td *big.Int // Total difficulty of one particular block being announced 146 ReorgDepth uint64 147 Update keyValueList 148 } 149 150 // sign adds a signature to the block announcement by the given privKey 151 func (a *announceData) sign(privKey *ecdsa.PrivateKey) { 152 rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td}) 153 sig, _ := crypto.Sign(crypto.Keccak256(rlp), privKey) 154 a.Update = a.Update.add("sign", sig) 155 } 156 157 // checkSignature verifies if the block announcement has a valid signature by the given pubKey 158 func (a *announceData) checkSignature(id enode.ID, update keyValueMap) error { 159 var sig []byte 160 if err := update.get("sign", &sig); err != nil { 161 return err 162 } 163 rlp, _ := rlp.EncodeToBytes(announceBlock{a.Hash, a.Number, a.Td}) 164 recPubkey, err := crypto.SigToPub(crypto.Keccak256(rlp), sig) 165 if err != nil { 166 return err 167 } 168 if id == enode.PubkeyToIDV4(recPubkey) { 169 return nil 170 } 171 return errors.New("wrong signature") 172 } 173 174 type blockInfo struct { 175 Hash common.Hash // Hash of one particular block being announced 176 Number uint64 // Number of one particular block being announced 177 Td *big.Int // Total difficulty of one particular block being announced 178 } 179 180 // getBlockHeadersData represents a block header query. 181 type getBlockHeadersData struct { 182 Origin hashOrNumber // Block from which to retrieve headers 183 Amount uint64 // Maximum number of headers to retrieve 184 Skip uint64 // Blocks to skip between consecutive headers 185 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 186 } 187 188 // hashOrNumber is a combined field for specifying an origin block. 189 type hashOrNumber struct { 190 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 191 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 192 } 193 194 // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the 195 // two contained union fields. 196 func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { 197 if hn.Hash == (common.Hash{}) { 198 return rlp.Encode(w, hn.Number) 199 } 200 if hn.Number != 0 { 201 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 202 } 203 return rlp.Encode(w, hn.Hash) 204 } 205 206 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents 207 // into either a block hash or a block number. 208 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { 209 _, size, _ := s.Kind() 210 origin, err := s.Raw() 211 if err == nil { 212 switch { 213 case size == 32: 214 err = rlp.DecodeBytes(origin, &hn.Hash) 215 case size <= 8: 216 err = rlp.DecodeBytes(origin, &hn.Number) 217 default: 218 err = fmt.Errorf("invalid input size %d for origin", size) 219 } 220 } 221 return err 222 } 223 224 // CodeData is the network response packet for a node data retrieval. 225 type CodeData []struct { 226 Value []byte 227 } 228 229 type proofsData [][]rlp.RawValue 230 231 type txStatus struct { 232 Status core.TxStatus 233 Lookup *rawdb.LegacyTxLookupEntry `rlp:"nil"` 234 Error string 235 }