github.com/klaytn/klaytn@v1.12.1/node/cn/protocol.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2014 The go-ethereum Authors 3 // This file is part of go-ethereum. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from eth/protocol.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package cn 22 23 import ( 24 "fmt" 25 "io" 26 "math/big" 27 "time" 28 29 "github.com/klaytn/klaytn" 30 "github.com/klaytn/klaytn/blockchain/types" 31 "github.com/klaytn/klaytn/common" 32 "github.com/klaytn/klaytn/datasync/downloader" 33 "github.com/klaytn/klaytn/datasync/fetcher" 34 "github.com/klaytn/klaytn/node/cn/snap" 35 "github.com/klaytn/klaytn/reward" 36 "github.com/klaytn/klaytn/rlp" 37 ) 38 39 // Constants to match up protocol versions and messages 40 const ( 41 klay62 = 62 42 klay63 = 63 43 klay64 = 64 44 klay65 = 65 45 ) 46 47 // ProtocolName is the official short name of the protocol used during capability negotiation. 48 var ProtocolName = "klay" 49 50 // ProtocolVersions are the upported versions of the klay protocol (first is primary). 51 var ProtocolVersions = []uint{klay65, klay64, klay63, klay62} 52 53 // ProtocolLengths are the number of implemented message corresponding to different protocol versions. 54 var ProtocolLengths = []uint64{21, 19, 17, 8} 55 56 const ProtocolMaxMsgSize = 12 * 1024 * 1024 // Maximum cap on the size of a protocol message 57 58 // Klaytn protocol message codes 59 // TODO-Klaytn-Issue751 Protocol message should be refactored. Present code is not used. 60 const ( 61 // Protocol messages belonging to klay/62 62 StatusMsg = 0x00 63 NewBlockHashesMsg = 0x01 64 BlockHeaderFetchRequestMsg = 0x02 65 BlockHeaderFetchResponseMsg = 0x03 66 BlockBodiesFetchRequestMsg = 0x04 67 BlockBodiesFetchResponseMsg = 0x05 68 TxMsg = 0x06 69 BlockHeadersRequestMsg = 0x07 70 BlockHeadersMsg = 0x08 71 BlockBodiesRequestMsg = 0x09 72 BlockBodiesMsg = 0x0a 73 NewBlockMsg = 0x0b 74 75 // Protocol messages belonging to klay/63 76 NodeDataRequestMsg = 0x0c 77 NodeDataMsg = 0x0d 78 ReceiptsRequestMsg = 0x0e 79 ReceiptsMsg = 0x0f 80 81 // Protocol messages belonging to klay/64 82 Unused10 = 0x10 // Skipped a number because 0x11 is already taken 83 Unused11 = 0x11 // Already used by consensus (IstanbulMsg) 84 85 // Protocol messages belonging to klay/65 86 StakingInfoRequestMsg = 0x12 87 StakingInfoMsg = 0x13 88 89 MsgCodeEnd = 0x14 90 ) 91 92 type errCode int 93 94 const ( 95 ErrMsgTooLarge = iota 96 ErrDecode 97 ErrInvalidMsgCode 98 ErrProtocolVersionMismatch 99 ErrNetworkIdMismatch 100 ErrGenesisBlockMismatch 101 ErrChainIDMismatch 102 ErrNoStatusMsg 103 ErrExtraStatusMsg 104 ErrSuspendedPeer 105 ErrUnexpectedTxType 106 ErrFailedToGetStateDB 107 ErrUnsupportedEnginePolicy 108 ) 109 110 func (e errCode) String() string { 111 return errorToString[int(e)] 112 } 113 114 // XXX change once legacy code is out 115 var errorToString = map[int]string{ 116 ErrMsgTooLarge: "Message too long", 117 ErrDecode: "Invalid message", 118 ErrInvalidMsgCode: "Invalid message code", 119 ErrProtocolVersionMismatch: "Protocol version mismatch", 120 ErrNetworkIdMismatch: "NetworkId mismatch", 121 ErrGenesisBlockMismatch: "Genesis block mismatch", 122 ErrChainIDMismatch: "ChainID mismatch", 123 ErrNoStatusMsg: "No status message", 124 ErrExtraStatusMsg: "Extra status message", 125 ErrSuspendedPeer: "Suspended peer", 126 ErrUnexpectedTxType: "Unexpected tx type", 127 ErrFailedToGetStateDB: "Failed to get stateDB", 128 ErrUnsupportedEnginePolicy: "Unsupported engine or policy", 129 } 130 131 //go:generate mockgen -destination=node/cn/mocks/downloader_mock.go -package=mocks github.com/klaytn/klaytn/node/cn ProtocolManagerDownloader 132 // ProtocolManagerDownloader is an interface of downloader.Downloader used by ProtocolManager. 133 type ProtocolManagerDownloader interface { 134 RegisterPeer(id string, version int, peer downloader.Peer) error 135 UnregisterPeer(id string) error 136 137 DeliverBodies(id string, transactions [][]*types.Transaction) error 138 DeliverHeaders(id string, headers []*types.Header) error 139 DeliverNodeData(id string, data [][]byte) error 140 DeliverReceipts(id string, receipts [][]*types.Receipt) error 141 DeliverStakingInfos(id string, stakingInfos []*reward.StakingInfo) error 142 DeliverSnapPacket(peer *snap.Peer, packet snap.Packet) error 143 144 Terminate() 145 Synchronise(id string, head common.Hash, td *big.Int, mode downloader.SyncMode) error 146 Progress() klaytn.SyncProgress 147 Cancel() 148 149 GetSnapSyncer() *snap.Syncer 150 SyncStakingInfo(id string, from, to uint64) error 151 SyncStakingInfoStatus() *downloader.SyncingStatus 152 } 153 154 //go:generate mockgen -destination=node/cn/mocks/fetcher_mock.go -package=mocks github.com/klaytn/klaytn/node/cn ProtocolManagerFetcher 155 // ProtocolManagerFetcher is an interface of fetcher.Fetcher used by ProtocolManager. 156 type ProtocolManagerFetcher interface { 157 Enqueue(peer string, block *types.Block) error 158 FilterBodies(peer string, transactions [][]*types.Transaction, time time.Time) [][]*types.Transaction 159 FilterHeaders(peer string, headers []*types.Header, time time.Time) []*types.Header 160 Notify(peer string, hash common.Hash, number uint64, time time.Time, headerFetcher fetcher.HeaderRequesterFn, bodyFetcher fetcher.BodyRequesterFn) error 161 Start() 162 Stop() 163 } 164 165 // statusData is the network packet for the status message. 166 type statusData struct { 167 ProtocolVersion uint32 168 NetworkId uint64 169 TD *big.Int 170 CurrentBlock common.Hash 171 GenesisBlock common.Hash 172 ChainID *big.Int // ChainID to sign a transaction. 173 } 174 175 // newBlockHashesData is the network packet for the block announcements. 176 type newBlockHashesData []struct { 177 Hash common.Hash // Hash of one particular block being announced 178 Number uint64 // Number of one particular block being announced 179 } 180 181 // getBlockHeadersData represents a block header query. 182 type getBlockHeadersData struct { 183 Origin hashOrNumber // Block from which to retrieve headers 184 Amount uint64 // Maximum number of headers to retrieve 185 Skip uint64 // Blocks to skip between consecutive headers 186 Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) 187 } 188 189 // hashOrNumber is a combined field for specifying an origin block. 190 type hashOrNumber struct { 191 Hash common.Hash // Block hash from which to retrieve headers (excludes Number) 192 Number uint64 // Block hash from which to retrieve headers (excludes Hash) 193 } 194 195 // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the 196 // two contained union fields. 197 func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { 198 if hn.Hash == (common.Hash{}) { 199 return rlp.Encode(w, hn.Number) 200 } 201 if hn.Number != 0 { 202 return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) 203 } 204 return rlp.Encode(w, hn.Hash) 205 } 206 207 // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents 208 // into either a block hash or a block number. 209 func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { 210 _, size, _ := s.Kind() 211 origin, err := s.Raw() 212 if err == nil { 213 switch { 214 case size == 32: 215 err = rlp.DecodeBytes(origin, &hn.Hash) 216 case size <= 8: 217 err = rlp.DecodeBytes(origin, &hn.Number) 218 default: 219 err = fmt.Errorf("invalid input size %d for origin", size) 220 } 221 } 222 return err 223 } 224 225 // newBlockData is the network packet for the block propagation message. 226 type newBlockData struct { 227 Block *types.Block 228 TD *big.Int 229 } 230 231 // blockBody represents the data content of a single block. 232 type blockBody struct { 233 Transactions []*types.Transaction // Transactions contained within a block 234 } 235 236 // blockBodiesData is the network packet for block content distribution. 237 type blockBodiesData []*blockBody