diff options
author | Péter Szilágyi <peterke@gmail.com> | 2015-07-03 00:55:18 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2015-08-24 22:57:28 +0800 |
commit | 42f44dda5468000b3b2c005ec485529bc5da3674 (patch) | |
tree | c93c9a2734adceac75e48f825076d48325826140 /eth/protocol.go | |
parent | c51e153b5c5327f971e7b410e49e7babfc3f0b8e (diff) | |
download | go-tangerine-42f44dda5468000b3b2c005ec485529bc5da3674.tar.gz go-tangerine-42f44dda5468000b3b2c005ec485529bc5da3674.tar.zst go-tangerine-42f44dda5468000b3b2c005ec485529bc5da3674.zip |
eth, eth/downloader: handle header requests, table driven proto tests
Diffstat (limited to 'eth/protocol.go')
-rw-r--r-- | eth/protocol.go | 124 |
1 files changed, 105 insertions, 19 deletions
diff --git a/eth/protocol.go b/eth/protocol.go index fcc5f21e2..c16223ccf 100644 --- a/eth/protocol.go +++ b/eth/protocol.go @@ -17,17 +17,29 @@ package eth import ( + "fmt" + "io" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// Constants to match up protocol versions and messages +const ( + eth60 = 60 + eth61 = 61 + eth62 = 62 + eth63 = 63 + eth64 = 64 ) // Supported versions of the eth protocol (first is primary). -var ProtocolVersions = []uint{62, 61, 60} +var ProtocolVersions = []uint{eth64, eth63, eth62, eth61, eth60} // Number of implemented message corresponding to different protocol versions. -var ProtocolLengths = []uint64{13, 9, 8} +var ProtocolLengths = []uint64{15, 12, 8, 9, 8} const ( NetworkId = 1 @@ -37,23 +49,38 @@ const ( // eth protocol message codes const ( // Protocol messages belonging to eth/60 - StatusMsg = iota - NewBlockHashesMsg - TxMsg - GetBlockHashesMsg - BlockHashesMsg - GetBlocksMsg - BlocksMsg - NewBlockMsg - - // Protocol messages belonging to eth/61 - GetBlockHashesFromNumberMsg - - // Protocol messages belonging to eth/62 - GetBlockHeadersMsg - BlockHeadersMsg - GetNodeDataMsg - NodeDataMsg + StatusMsg = 0x00 + NewBlockHashesMsg = 0x01 + TxMsg = 0x02 + GetBlockHashesMsg = 0x03 + BlockHashesMsg = 0x04 + GetBlocksMsg = 0x05 + BlocksMsg = 0x06 + NewBlockMsg = 0x07 + + // Protocol messages belonging to eth/61 (extension of eth/60) + GetBlockHashesFromNumberMsg = 0x08 + + // Protocol messages belonging to eth/62 (new protocol from scratch) + // StatusMsg = 0x00 (uncomment after eth/61 deprecation) + // NewBlockHashesMsg = 0x01 (uncomment after eth/61 deprecation) + // TxMsg = 0x02 (uncomment after eth/61 deprecation) + GetBlockHeadersMsg = 0x03 + BlockHeadersMsg = 0x04 + GetBlockBodiesMsg = 0x05 + BlockBodiesMsg = 0x06 + // NewBlockMsg = 0x07 (uncomment after eth/61 deprecation) + + // Protocol messages belonging to eth/63 + GetNodeDataMsg = 0x0d + NodeDataMsg = 0x0e + GetReceiptsMsg = 0x0f + ReceiptsMsg = 0x10 + + // Protocol messages belonging to eth/64 + GetAcctProofMsg = 0x11 + GetStorageDataProof = 0x12 + Proof = 0x13 ) type errCode int @@ -111,6 +138,12 @@ type statusData struct { GenesisBlock common.Hash } +// newBlockHashesData is the network packet for the block announcements. +type newBlockHashesData []struct { + Hash common.Hash // Hash of one particular block being announced + Number uint64 // Number of one particular block being announced +} + // getBlockHashesData is the network packet for the hash based hash retrieval. type getBlockHashesData struct { Hash common.Hash @@ -124,12 +157,65 @@ type getBlockHashesFromNumberData struct { Amount uint64 } +// getBlockHeadersData represents a block header query. +type getBlockHeadersData struct { + Origin hashOrNumber // Block from which to retrieve headers + Amount uint64 // Maximum number of headers to retrieve + Skip uint64 // Blocks to skip between consecutive headers + Reverse bool // Query direction (false = rising towards latest, true = falling towards genesis) +} + +// hashOrNumber is a combined field for specifying an origin block. +type hashOrNumber struct { + Hash common.Hash // Block hash from which to retrieve headers (excludes Number) + Number uint64 // Block hash from which to retrieve headers (excludes Hash) +} + +// EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the +// two contained union fields. +func (hn *hashOrNumber) EncodeRLP(w io.Writer) error { + if hn.Hash == (common.Hash{}) { + return rlp.Encode(w, hn.Number) + } + if hn.Number != 0 { + return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number) + } + return rlp.Encode(w, hn.Hash) +} + +// DecodeRLP is a specialized decoder for hashOrNumber to decode the contents +// into either a block hash or a block number. +func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error { + _, size, _ := s.Kind() + origin, err := s.Raw() + if err == nil { + switch { + case size == 32: + err = rlp.DecodeBytes(origin, &hn.Hash) + case size <= 8: + err = rlp.DecodeBytes(origin, &hn.Number) + default: + err = fmt.Errorf("invalid input size %d for origin", size) + } + } + return err +} + // newBlockData is the network packet for the block propagation message. type newBlockData struct { Block *types.Block TD *big.Int } +// blockBody represents the data content of a single block. +type blockBody struct { + Transactions []*types.Transaction // Transactions contained within a block + Uncles []*types.Header // Uncles contained within a block +} + +// blockBodiesData is the network packet for block content distribution. +type blockBodiesData []*blockBody + // nodeDataData is the network response packet for a node data retrieval. type nodeDataData []struct { Value []byte |