github.com/arjunbeliever/ignite@v0.0.0-20220406110515-46bbbbec2587/eth/protocols/eth/protocol.go (about)

     1  // Copyright 2014 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 eth
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"math/big"
    24  
    25  	"github.com/arjunbeliever/ignite/common"
    26  	"github.com/arjunbeliever/ignite/core/forkid"
    27  	"github.com/arjunbeliever/ignite/core/types"
    28  	"github.com/arjunbeliever/ignite/rlp"
    29  )
    30  
    31  // Constants to match up protocol versions and messages
    32  const (
    33  	ETH66 = 66
    34  )
    35  
    36  // ProtocolName is the official short name of the `eth` protocol used during
    37  // devp2p capability negotiation.
    38  const ProtocolName = "eth"
    39  
    40  // ProtocolVersions are the supported versions of the `eth` protocol (first
    41  // is primary).
    42  var ProtocolVersions = []uint{ETH66}
    43  
    44  // protocolLengths are the number of implemented message corresponding to
    45  // different protocol versions.
    46  var protocolLengths = map[uint]uint64{ETH66: 17}
    47  
    48  // maxMessageSize is the maximum cap on the size of a protocol message.
    49  const maxMessageSize = 10 * 1024 * 1024
    50  
    51  const (
    52  	StatusMsg                     = 0x00
    53  	NewBlockHashesMsg             = 0x01
    54  	TransactionsMsg               = 0x02
    55  	GetBlockHeadersMsg            = 0x03
    56  	BlockHeadersMsg               = 0x04
    57  	GetBlockBodiesMsg             = 0x05
    58  	BlockBodiesMsg                = 0x06
    59  	NewBlockMsg                   = 0x07
    60  	GetNodeDataMsg                = 0x0d
    61  	NodeDataMsg                   = 0x0e
    62  	GetReceiptsMsg                = 0x0f
    63  	ReceiptsMsg                   = 0x10
    64  	NewPooledTransactionHashesMsg = 0x08
    65  	GetPooledTransactionsMsg      = 0x09
    66  	PooledTransactionsMsg         = 0x0a
    67  )
    68  
    69  var (
    70  	errNoStatusMsg             = errors.New("no status message")
    71  	errMsgTooLarge             = errors.New("message too long")
    72  	errDecode                  = errors.New("invalid message")
    73  	errInvalidMsgCode          = errors.New("invalid message code")
    74  	errProtocolVersionMismatch = errors.New("protocol version mismatch")
    75  	errNetworkIDMismatch       = errors.New("network ID mismatch")
    76  	errGenesisMismatch         = errors.New("genesis mismatch")
    77  	errForkIDRejected          = errors.New("fork ID rejected")
    78  )
    79  
    80  // Packet represents a p2p message in the `eth` protocol.
    81  type Packet interface {
    82  	Name() string // Name returns a string corresponding to the message type.
    83  	Kind() byte   // Kind returns the message type.
    84  }
    85  
    86  // StatusPacket is the network packet for the status message for eth/64 and later.
    87  type StatusPacket struct {
    88  	ProtocolVersion uint32
    89  	NetworkID       uint64
    90  	TD              *big.Int
    91  	Head            common.Hash
    92  	Genesis         common.Hash
    93  	ForkID          forkid.ID
    94  }
    95  
    96  // NewBlockHashesPacket is the network packet for the block announcements.
    97  type NewBlockHashesPacket []struct {
    98  	Hash   common.Hash // Hash of one particular block being announced
    99  	Number uint64      // Number of one particular block being announced
   100  }
   101  
   102  // Unpack retrieves the block hashes and numbers from the announcement packet
   103  // and returns them in a split flat format that's more consistent with the
   104  // internal data structures.
   105  func (p *NewBlockHashesPacket) Unpack() ([]common.Hash, []uint64) {
   106  	var (
   107  		hashes  = make([]common.Hash, len(*p))
   108  		numbers = make([]uint64, len(*p))
   109  	)
   110  	for i, body := range *p {
   111  		hashes[i], numbers[i] = body.Hash, body.Number
   112  	}
   113  	return hashes, numbers
   114  }
   115  
   116  // TransactionsPacket is the network packet for broadcasting new transactions.
   117  type TransactionsPacket []*types.Transaction
   118  
   119  // GetBlockHeadersPacket represents a block header query.
   120  type GetBlockHeadersPacket struct {
   121  	Origin  HashOrNumber // Block from which to retrieve headers
   122  	Amount  uint64       // Maximum number of headers to retrieve
   123  	Skip    uint64       // Blocks to skip between consecutive headers
   124  	Reverse bool         // Query direction (false = rising towards latest, true = falling towards genesis)
   125  }
   126  
   127  // GetBlockHeadersPacket66 represents a block header query over eth/66
   128  type GetBlockHeadersPacket66 struct {
   129  	RequestId uint64
   130  	*GetBlockHeadersPacket
   131  }
   132  
   133  // HashOrNumber is a combined field for specifying an origin block.
   134  type HashOrNumber struct {
   135  	Hash   common.Hash // Block hash from which to retrieve headers (excludes Number)
   136  	Number uint64      // Block hash from which to retrieve headers (excludes Hash)
   137  }
   138  
   139  // EncodeRLP is a specialized encoder for HashOrNumber to encode only one of the
   140  // two contained union fields.
   141  func (hn *HashOrNumber) EncodeRLP(w io.Writer) error {
   142  	if hn.Hash == (common.Hash{}) {
   143  		return rlp.Encode(w, hn.Number)
   144  	}
   145  	if hn.Number != 0 {
   146  		return fmt.Errorf("both origin hash (%x) and number (%d) provided", hn.Hash, hn.Number)
   147  	}
   148  	return rlp.Encode(w, hn.Hash)
   149  }
   150  
   151  // DecodeRLP is a specialized decoder for HashOrNumber to decode the contents
   152  // into either a block hash or a block number.
   153  func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error {
   154  	_, size, err := s.Kind()
   155  	switch {
   156  	case err != nil:
   157  		return err
   158  	case size == 32:
   159  		hn.Number = 0
   160  		return s.Decode(&hn.Hash)
   161  	case size <= 8:
   162  		hn.Hash = common.Hash{}
   163  		return s.Decode(&hn.Number)
   164  	default:
   165  		return fmt.Errorf("invalid input size %d for origin", size)
   166  	}
   167  }
   168  
   169  // BlockHeadersPacket represents a block header response.
   170  type BlockHeadersPacket []*types.Header
   171  
   172  // BlockHeadersPacket represents a block header response over eth/66.
   173  type BlockHeadersPacket66 struct {
   174  	RequestId uint64
   175  	BlockHeadersPacket
   176  }
   177  
   178  // NewBlockPacket is the network packet for the block propagation message.
   179  type NewBlockPacket struct {
   180  	Block *types.Block
   181  	TD    *big.Int
   182  }
   183  
   184  // sanityCheck verifies that the values are reasonable, as a DoS protection
   185  func (request *NewBlockPacket) sanityCheck() error {
   186  	if err := request.Block.SanityCheck(); err != nil {
   187  		return err
   188  	}
   189  	//TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
   190  	// larger, it will still fit within 100 bits
   191  	if tdlen := request.TD.BitLen(); tdlen > 100 {
   192  		return fmt.Errorf("too large block TD: bitlen %d", tdlen)
   193  	}
   194  	return nil
   195  }
   196  
   197  // GetBlockBodiesPacket represents a block body query.
   198  type GetBlockBodiesPacket []common.Hash
   199  
   200  // GetBlockBodiesPacket represents a block body query over eth/66.
   201  type GetBlockBodiesPacket66 struct {
   202  	RequestId uint64
   203  	GetBlockBodiesPacket
   204  }
   205  
   206  // BlockBodiesPacket is the network packet for block content distribution.
   207  type BlockBodiesPacket []*BlockBody
   208  
   209  // BlockBodiesPacket is the network packet for block content distribution over eth/66.
   210  type BlockBodiesPacket66 struct {
   211  	RequestId uint64
   212  	BlockBodiesPacket
   213  }
   214  
   215  // BlockBodiesRLPPacket is used for replying to block body requests, in cases
   216  // where we already have them RLP-encoded, and thus can avoid the decode-encode
   217  // roundtrip.
   218  type BlockBodiesRLPPacket []rlp.RawValue
   219  
   220  // BlockBodiesRLPPacket66 is the BlockBodiesRLPPacket over eth/66
   221  type BlockBodiesRLPPacket66 struct {
   222  	RequestId uint64
   223  	BlockBodiesRLPPacket
   224  }
   225  
   226  // BlockBody represents the data content of a single block.
   227  type BlockBody struct {
   228  	Transactions []*types.Transaction // Transactions contained within a block
   229  	Uncles       []*types.Header      // Uncles contained within a block
   230  }
   231  
   232  // Unpack retrieves the transactions and uncles from the range packet and returns
   233  // them in a split flat format that's more consistent with the internal data structures.
   234  func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header) {
   235  	var (
   236  		txset    = make([][]*types.Transaction, len(*p))
   237  		uncleset = make([][]*types.Header, len(*p))
   238  	)
   239  	for i, body := range *p {
   240  		txset[i], uncleset[i] = body.Transactions, body.Uncles
   241  	}
   242  	return txset, uncleset
   243  }
   244  
   245  // GetNodeDataPacket represents a trie node data query.
   246  type GetNodeDataPacket []common.Hash
   247  
   248  // GetNodeDataPacket represents a trie node data query over eth/66.
   249  type GetNodeDataPacket66 struct {
   250  	RequestId uint64
   251  	GetNodeDataPacket
   252  }
   253  
   254  // NodeDataPacket is the network packet for trie node data distribution.
   255  type NodeDataPacket [][]byte
   256  
   257  // NodeDataPacket is the network packet for trie node data distribution over eth/66.
   258  type NodeDataPacket66 struct {
   259  	RequestId uint64
   260  	NodeDataPacket
   261  }
   262  
   263  // GetReceiptsPacket represents a block receipts query.
   264  type GetReceiptsPacket []common.Hash
   265  
   266  // GetReceiptsPacket represents a block receipts query over eth/66.
   267  type GetReceiptsPacket66 struct {
   268  	RequestId uint64
   269  	GetReceiptsPacket
   270  }
   271  
   272  // ReceiptsPacket is the network packet for block receipts distribution.
   273  type ReceiptsPacket [][]*types.Receipt
   274  
   275  // ReceiptsPacket is the network packet for block receipts distribution over eth/66.
   276  type ReceiptsPacket66 struct {
   277  	RequestId uint64
   278  	ReceiptsPacket
   279  }
   280  
   281  // ReceiptsRLPPacket is used for receipts, when we already have it encoded
   282  type ReceiptsRLPPacket []rlp.RawValue
   283  
   284  // ReceiptsPacket66 is the eth-66 version of ReceiptsRLPPacket
   285  type ReceiptsRLPPacket66 struct {
   286  	RequestId uint64
   287  	ReceiptsRLPPacket
   288  }
   289  
   290  // NewPooledTransactionHashesPacket represents a transaction announcement packet.
   291  type NewPooledTransactionHashesPacket []common.Hash
   292  
   293  // GetPooledTransactionsPacket represents a transaction query.
   294  type GetPooledTransactionsPacket []common.Hash
   295  
   296  type GetPooledTransactionsPacket66 struct {
   297  	RequestId uint64
   298  	GetPooledTransactionsPacket
   299  }
   300  
   301  // PooledTransactionsPacket is the network packet for transaction distribution.
   302  type PooledTransactionsPacket []*types.Transaction
   303  
   304  // PooledTransactionsPacket is the network packet for transaction distribution over eth/66.
   305  type PooledTransactionsPacket66 struct {
   306  	RequestId uint64
   307  	PooledTransactionsPacket
   308  }
   309  
   310  // PooledTransactionsPacket is the network packet for transaction distribution, used
   311  // in the cases we already have them in rlp-encoded form
   312  type PooledTransactionsRLPPacket []rlp.RawValue
   313  
   314  // PooledTransactionsRLPPacket66 is the eth/66 form of PooledTransactionsRLPPacket
   315  type PooledTransactionsRLPPacket66 struct {
   316  	RequestId uint64
   317  	PooledTransactionsRLPPacket
   318  }
   319  
   320  func (*StatusPacket) Name() string { return "Status" }
   321  func (*StatusPacket) Kind() byte   { return StatusMsg }
   322  
   323  func (*NewBlockHashesPacket) Name() string { return "NewBlockHashes" }
   324  func (*NewBlockHashesPacket) Kind() byte   { return NewBlockHashesMsg }
   325  
   326  func (*TransactionsPacket) Name() string { return "Transactions" }
   327  func (*TransactionsPacket) Kind() byte   { return TransactionsMsg }
   328  
   329  func (*GetBlockHeadersPacket) Name() string { return "GetBlockHeaders" }
   330  func (*GetBlockHeadersPacket) Kind() byte   { return GetBlockHeadersMsg }
   331  
   332  func (*BlockHeadersPacket) Name() string { return "BlockHeaders" }
   333  func (*BlockHeadersPacket) Kind() byte   { return BlockHeadersMsg }
   334  
   335  func (*GetBlockBodiesPacket) Name() string { return "GetBlockBodies" }
   336  func (*GetBlockBodiesPacket) Kind() byte   { return GetBlockBodiesMsg }
   337  
   338  func (*BlockBodiesPacket) Name() string { return "BlockBodies" }
   339  func (*BlockBodiesPacket) Kind() byte   { return BlockBodiesMsg }
   340  
   341  func (*NewBlockPacket) Name() string { return "NewBlock" }
   342  func (*NewBlockPacket) Kind() byte   { return NewBlockMsg }
   343  
   344  func (*GetNodeDataPacket) Name() string { return "GetNodeData" }
   345  func (*GetNodeDataPacket) Kind() byte   { return GetNodeDataMsg }
   346  
   347  func (*NodeDataPacket) Name() string { return "NodeData" }
   348  func (*NodeDataPacket) Kind() byte   { return NodeDataMsg }
   349  
   350  func (*GetReceiptsPacket) Name() string { return "GetReceipts" }
   351  func (*GetReceiptsPacket) Kind() byte   { return GetReceiptsMsg }
   352  
   353  func (*ReceiptsPacket) Name() string { return "Receipts" }
   354  func (*ReceiptsPacket) Kind() byte   { return ReceiptsMsg }
   355  
   356  func (*NewPooledTransactionHashesPacket) Name() string { return "NewPooledTransactionHashes" }
   357  func (*NewPooledTransactionHashesPacket) Kind() byte   { return NewPooledTransactionHashesMsg }
   358  
   359  func (*GetPooledTransactionsPacket) Name() string { return "GetPooledTransactions" }
   360  func (*GetPooledTransactionsPacket) Kind() byte   { return GetPooledTransactionsMsg }
   361  
   362  func (*PooledTransactionsPacket) Name() string { return "PooledTransactions" }
   363  func (*PooledTransactionsPacket) Kind() byte   { return PooledTransactionsMsg }