github.com/aquanetwork/aquachain@v1.7.8/aqua/protocol.go (about)

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