github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/eth/protocol.go (about)

     1  // Copyright 2014 The go-simplechain Authors
     2  // This file is part of the go-simplechain library.
     3  //
     4  // The go-simplechain 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-simplechain 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-simplechain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package eth
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"math/big"
    23  
    24  	"github.com/bigzoro/my_simplechain/common"
    25  	"github.com/bigzoro/my_simplechain/core"
    26  	"github.com/bigzoro/my_simplechain/core/forkid"
    27  	"github.com/bigzoro/my_simplechain/core/types"
    28  	"github.com/bigzoro/my_simplechain/event"
    29  	"github.com/bigzoro/my_simplechain/rlp"
    30  )
    31  
    32  // Constants to match up protocol versions and messages
    33  const (
    34  	eth63 = 63
    35  	eth64 = 64
    36  )
    37  
    38  // protocolName is the official short name of the protocol used during capability negotiation.
    39  const protocolName = "eth"
    40  
    41  // ProtocolVersions are the supported versions of the eth protocol (first is primary).
    42  var ProtocolVersions = []uint{eth64, eth63}
    43  
    44  // protocolLengths are the number of implemented message corresponding to different protocol versions.
    45  var protocolLengths = map[uint]uint64{eth64: 18, eth63: 18}
    46  
    47  const protocolMaxMsgSize = 10 * 1024 * 1024 // Maximum cap on the size of a protocol message
    48  
    49  // eth protocol message codes
    50  const (
    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  	GetNodeDataMsg               = 0x0d
    60  	NodeDataMsg                  = 0x0e
    61  	GetReceiptsMsg               = 0x0f
    62  	ReceiptsMsg                  = 0x10
    63  	CertificateRevocationListMsg = 0x11
    64  )
    65  
    66  type errCode int
    67  
    68  const (
    69  	ErrMsgTooLarge = iota
    70  	ErrDecode
    71  	ErrInvalidMsgCode
    72  	ErrProtocolVersionMismatch
    73  	ErrNetworkIDMismatch
    74  	ErrGenesisMismatch
    75  	ErrForkIDRejected
    76  	ErrNoStatusMsg
    77  	ErrExtraStatusMsg
    78  )
    79  
    80  func (e errCode) String() string {
    81  	return errorToString[int(e)]
    82  }
    83  
    84  // XXX change once legacy code is out
    85  var errorToString = map[int]string{
    86  	ErrMsgTooLarge:             "Message too long",
    87  	ErrDecode:                  "Invalid message",
    88  	ErrInvalidMsgCode:          "Invalid message code",
    89  	ErrProtocolVersionMismatch: "Protocol version mismatch",
    90  	ErrNetworkIDMismatch:       "Network ID mismatch",
    91  	ErrGenesisMismatch:         "Genesis mismatch",
    92  	ErrForkIDRejected:          "Fork ID rejected",
    93  	ErrNoStatusMsg:             "No status message",
    94  	ErrExtraStatusMsg:          "Extra status message",
    95  }
    96  
    97  type txPool interface {
    98  	// AddRemotes should add the given transactions to the pool.
    99  	AddRemotes([]*types.Transaction) []error
   100  
   101  	// Pending should return pending transactions.
   102  	// The slice should be modifiable by the caller.
   103  	Pending() (map[common.Address]types.Transactions, error)
   104  
   105  	// SubscribeNewTxsEvent should return an event subscription of
   106  	// NewTxsEvent and send events to the given channel.
   107  	SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
   108  }
   109  
   110  // statusData63 is the network packet for the status message for eth/63.
   111  type statusData63 struct {
   112  	ProtocolVersion uint32
   113  	NetworkId       uint64
   114  	TD              *big.Int
   115  	CurrentBlock    common.Hash
   116  	GenesisBlock    common.Hash
   117  }
   118  
   119  // statusData is the network packet for the status message for eth/64 and later.
   120  type statusData struct {
   121  	ProtocolVersion uint32
   122  	NetworkID       uint64
   123  	TD              *big.Int
   124  	Head            common.Hash
   125  	Genesis         common.Hash
   126  	ForkID          forkid.ID
   127  }
   128  
   129  // newBlockHashesData is the network packet for the block announcements.
   130  type newBlockHashesData []struct {
   131  	Hash   common.Hash // Hash of one particular block being announced
   132  	Number uint64      // Number of one particular block being announced
   133  }
   134  
   135  // getBlockHeadersData represents a block header query.
   136  type getBlockHeadersData struct {
   137  	Origin  hashOrNumber // Block from which to retrieve headers
   138  	Amount  uint64       // Maximum number of headers to retrieve
   139  	Skip    uint64       // Blocks to skip between consecutive headers
   140  	Reverse bool         // Query direction (false = rising towards latest, true = falling towards genesis)
   141  }
   142  
   143  // hashOrNumber is a combined field for specifying an origin block.
   144  type hashOrNumber struct {
   145  	Hash   common.Hash // Block hash from which to retrieve headers (excludes Number)
   146  	Number uint64      // Block hash from which to retrieve headers (excludes Hash)
   147  }
   148  
   149  // EncodeRLP is a specialized encoder for hashOrNumber to encode only one of the
   150  // two contained union fields.
   151  func (hn *hashOrNumber) EncodeRLP(w io.Writer) error {
   152  	if hn.Hash == (common.Hash{}) {
   153  		return rlp.Encode(w, hn.Number)
   154  	}
   155  	if hn.Number != 0 {
   156  		return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
   157  	}
   158  	return rlp.Encode(w, hn.Hash)
   159  }
   160  
   161  // DecodeRLP is a specialized decoder for hashOrNumber to decode the contents
   162  // into either a block hash or a block number.
   163  func (hn *hashOrNumber) DecodeRLP(s *rlp.Stream) error {
   164  	_, size, _ := s.Kind()
   165  	origin, err := s.Raw()
   166  	if err == nil {
   167  		switch {
   168  		case size == 32:
   169  			err = rlp.DecodeBytes(origin, &hn.Hash)
   170  		case size <= 8:
   171  			err = rlp.DecodeBytes(origin, &hn.Number)
   172  		default:
   173  			err = fmt.Errorf("invalid input size %d for origin", size)
   174  		}
   175  	}
   176  	return err
   177  }
   178  
   179  // newBlockData is the network packet for the block propagation message.
   180  type newBlockData struct {
   181  	Block *types.Block
   182  	TD    *big.Int
   183  }
   184  
   185  // sanityCheck verifies that the values are reasonable, as a DoS protection
   186  func (request *newBlockData) sanityCheck() error {
   187  	if err := request.Block.SanityCheck(); err != nil {
   188  		return err
   189  	}
   190  	//TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
   191  	// larger, it will still fit within 100 bits
   192  	if tdlen := request.TD.BitLen(); tdlen > 100 {
   193  		return fmt.Errorf("too large block TD: bitlen %d", tdlen)
   194  	}
   195  	return nil
   196  }
   197  
   198  // blockBody represents the data content of a single block.
   199  type blockBody struct {
   200  	Transactions []*types.Transaction // Transactions contained within a block
   201  	Uncles       []*types.Header      // Uncles contained within a block
   202  }
   203  
   204  // blockBodiesData is the network packet for block content distribution.
   205  type blockBodiesData []*blockBody
   206  
   207  type CertificateRevocationListPacket struct {
   208  	ID uint64 // ID of the request this is a response for
   209  	//revocation lists
   210  	Content   []byte
   211  	Signature []byte
   212  }