github.com/codingfuture/orig-energi3@v0.8.4/eth/protocol.go (about)

     1  // Copyright 2018 The Energi Core Authors
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the Energi Core library.
     4  //
     5  // The Energi Core 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 Energi Core 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 Energi Core library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package eth
    19  
    20  import (
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/core"
    27  	"github.com/ethereum/go-ethereum/core/types"
    28  	"github.com/ethereum/go-ethereum/event"
    29  	"github.com/ethereum/go-ethereum/rlp"
    30  )
    31  
    32  // Constants to match up protocol versions and messages
    33  const (
    34  	nrg70 = 70
    35  )
    36  
    37  // ProtocolName is the official short name of the protocol used during capability negotiation.
    38  var ProtocolName = "eth"
    39  
    40  // ProtocolVersions are the supported versions of the eth protocol (first is primary).
    41  var ProtocolVersions = []uint{nrg70}
    42  
    43  // ProtocolLengths are the number of implemented message corresponding to different protocol versions.
    44  var ProtocolLengths = []uint64{0x13}
    45  
    46  const ProtocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
    47  
    48  // eth protocol message codes
    49  const (
    50  	// Protocol messages belonging to eth/62
    51  	StatusMsg          = 0x00
    52  	NewBlockHashesMsg  = 0x01
    53  	TxMsg              = 0x02
    54  	GetBlockHeadersMsg = 0x03
    55  	BlockHeadersMsg    = 0x04
    56  	GetBlockBodiesMsg  = 0x05
    57  	BlockBodiesMsg     = 0x06
    58  	NewBlockMsg        = 0x07
    59  
    60  	// Protocol messages belonging to eth/63
    61  	GetNodeDataMsg = 0x0d
    62  	NodeDataMsg    = 0x0e
    63  	GetReceiptsMsg = 0x0f
    64  	ReceiptsMsg    = 0x10
    65  
    66  	// Protocol messages belonging to nrg/70
    67  	GetCheckpointsMsg = 0x11
    68  	CheckpointMsg     = 0x12
    69  )
    70  
    71  type errCode int
    72  
    73  const (
    74  	ErrMsgTooLarge = iota
    75  	ErrDecode
    76  	ErrInvalidMsgCode
    77  	ErrProtocolVersionMismatch
    78  	ErrNetworkIdMismatch
    79  	ErrGenesisBlockMismatch
    80  	ErrNoStatusMsg
    81  	ErrExtraStatusMsg
    82  	ErrSuspendedPeer
    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  }
   101  
   102  type txPool interface {
   103  	// AddRemotes should add the given transactions to the pool.
   104  	AddRemotes([]*types.Transaction) []error
   105  
   106  	// Pending should return pending transactions.
   107  	// The slice should be modifiable by the caller.
   108  	Pending() (map[common.Address]types.Transactions, error)
   109  
   110  	// SubscribeNewTxsEvent should return an event subscription of
   111  	// NewTxsEvent and send events to the given channel.
   112  	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
   113  
   114  	PreBlacklistHook(blocks types.Blocks) types.Blocks
   115  }
   116  
   117  // statusData is the network packet for the status message.
   118  type statusData struct {
   119  	ProtocolVersion uint32
   120  	NetworkId       uint64
   121  	TD              *big.Int
   122  	CurrentBlock    common.Hash
   123  	GenesisBlock    common.Hash
   124  }
   125  
   126  // newBlockHashesData is the network packet for the block announcements.
   127  type newBlockHashesData []struct {
   128  	Hash   common.Hash // Hash of one particular block being announced
   129  	Number uint64      // Number of one particular block being announced
   130  }
   131  
   132  // getBlockHeadersData represents a block header query.
   133  type getBlockHeadersData struct {
   134  	Origin  hashOrNumber // Block from which to retrieve headers
   135  	Amount  uint64       // Maximum number of headers to retrieve
   136  	Skip    uint64       // Blocks to skip between consecutive headers
   137  	Reverse bool         // Query direction (false = rising towards latest, true = falling towards genesis)
   138  }
   139  
   140  // hashOrNumber is a combined field for specifying an origin block.
   141  type hashOrNumber struct {
   142  	Hash   common.Hash // Block hash from which to retrieve headers (excludes Number)
   143  	Number uint64      // Block hash from which to retrieve headers (excludes Hash)
   144  }
   145  
   146  // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the
   147  // two contained union fields.
   148  func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
   149  	if hn.Hash == (common.Hash{}) {
   150  		return rlp.Encode(w, hn.Number)
   151  	}
   152  	if hn.Number != 0 {
   153  		return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
   154  	}
   155  	return rlp.Encode(w, hn.Hash)
   156  }
   157  
   158  // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
   159  // into either a block hash or a block number.
   160  func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
   161  	_, size, _ := s.Kind()
   162  	origin, err := s.Raw()
   163  	if err == nil {
   164  		switch {
   165  		case size == 32:
   166  			err = rlp.DecodeBytes(origin, &hn.Hash)
   167  		case size <= 8:
   168  			err = rlp.DecodeBytes(origin, &hn.Number)
   169  		default:
   170  			err = fmt.Errorf("invalid input size %d for origin", size)
   171  		}
   172  	}
   173  	return err
   174  }
   175  
   176  // newBlockData is the network packet for the block propagation message.
   177  type newBlockData struct {
   178  	Block *types.Block
   179  	TD    *big.Int
   180  }
   181  
   182  // blockBody represents the data content of a single block.
   183  type blockBody struct {
   184  	Transactions []*types.Transaction // Transactions contained within a block
   185  	Uncles       []*types.Header      // Uncles contained within a block
   186  }
   187  
   188  // blockBodiesData is the network packet for block content distribution.
   189  type blockBodiesData []*blockBody
   190  
   191  type newCheckpointData struct {
   192  	Number   uint64
   193  	Hash     common.Hash
   194  	CppSig   core.CheckpointSignature
   195  	SigCount uint64
   196  }