github.com/onflow/flow-go@v0.33.17/network/codec/codes.go (about)

     1  // (c) 2019 Dapper Labs - ALL RIGHTS RESERVED
     2  
     3  package codec
     4  
     5  import (
     6  	"fmt"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  	"github.com/onflow/flow-go/model/libp2p/message"
    10  	"github.com/onflow/flow-go/model/messages"
    11  )
    12  
    13  type MessageCode uint8
    14  
    15  func (m MessageCode) Uint8() uint8 {
    16  	return uint8(m)
    17  }
    18  
    19  const (
    20  	CodeMin MessageCode = iota + 1
    21  
    22  	// consensus
    23  	CodeBlockProposal
    24  	CodeBlockVote
    25  	CodeTimeoutObject
    26  
    27  	// protocol state sync
    28  	CodeSyncRequest
    29  	CodeSyncResponse
    30  	CodeRangeRequest
    31  	CodeBatchRequest
    32  	CodeBlockResponse
    33  
    34  	// cluster consensus
    35  	CodeClusterBlockProposal
    36  	CodeClusterBlockVote
    37  	CodeClusterBlockResponse
    38  	CodeClusterTimeoutObject
    39  
    40  	// collections, guarantees & transactions
    41  	CodeCollectionGuarantee
    42  	CodeTransaction
    43  	CodeTransactionBody
    44  
    45  	// core messages for execution & verification
    46  	CodeExecutionReceipt
    47  	CodeResultApproval
    48  
    49  	// data exchange for execution of blocks
    50  	CodeChunkDataRequest
    51  	CodeChunkDataResponse
    52  
    53  	// result approvals
    54  	CodeApprovalRequest
    55  	CodeApprovalResponse
    56  
    57  	// generic entity exchange engines
    58  	CodeEntityRequest
    59  	CodeEntityResponse
    60  
    61  	// testing
    62  	CodeEcho
    63  
    64  	// DKG
    65  	CodeDKGMessage
    66  
    67  	CodeMax
    68  )
    69  
    70  // MessageCodeFromInterface returns the correct Code based on the underlying type of message v.
    71  func MessageCodeFromInterface(v interface{}) (MessageCode, string, error) {
    72  	s := what(v)
    73  	switch v.(type) {
    74  	// consensus
    75  	case *messages.BlockProposal:
    76  		return CodeBlockProposal, s, nil
    77  	case *messages.BlockVote:
    78  		return CodeBlockVote, s, nil
    79  	case *messages.TimeoutObject:
    80  		return CodeTimeoutObject, s, nil
    81  
    82  	// cluster consensus
    83  	case *messages.ClusterBlockProposal:
    84  		return CodeClusterBlockProposal, s, nil
    85  	case *messages.ClusterBlockVote:
    86  		return CodeClusterBlockVote, s, nil
    87  	case *messages.ClusterBlockResponse:
    88  		return CodeClusterBlockResponse, s, nil
    89  	case *messages.ClusterTimeoutObject:
    90  		return CodeClusterTimeoutObject, s, nil
    91  
    92  	// protocol state sync
    93  	case *messages.SyncRequest:
    94  		return CodeSyncRequest, s, nil
    95  	case *messages.SyncResponse:
    96  		return CodeSyncResponse, s, nil
    97  	case *messages.RangeRequest:
    98  		return CodeRangeRequest, s, nil
    99  	case *messages.BatchRequest:
   100  		return CodeBatchRequest, s, nil
   101  	case *messages.BlockResponse:
   102  		return CodeBlockResponse, s, nil
   103  
   104  	// collections, guarantees & transactions
   105  	case *flow.CollectionGuarantee:
   106  		return CodeCollectionGuarantee, s, nil
   107  	case *flow.TransactionBody:
   108  		return CodeTransactionBody, s, nil
   109  	case *flow.Transaction:
   110  		return CodeTransaction, s, nil
   111  
   112  	// core messages for execution & verification
   113  	case *flow.ExecutionReceipt:
   114  		return CodeExecutionReceipt, s, nil
   115  	case *flow.ResultApproval:
   116  		return CodeResultApproval, s, nil
   117  
   118  	// data exchange for execution of blocks
   119  	case *messages.ChunkDataRequest:
   120  		return CodeChunkDataRequest, s, nil
   121  	case *messages.ChunkDataResponse:
   122  		return CodeChunkDataResponse, s, nil
   123  
   124  	// result approvals
   125  	case *messages.ApprovalRequest:
   126  		return CodeApprovalRequest, s, nil
   127  	case *messages.ApprovalResponse:
   128  		return CodeApprovalResponse, s, nil
   129  
   130  	// generic entity exchange engines
   131  	case *messages.EntityRequest:
   132  		return CodeEntityRequest, s, nil
   133  	case *messages.EntityResponse:
   134  		return CodeEntityResponse, s, nil
   135  
   136  	// testing
   137  	case *message.TestMessage:
   138  		return CodeEcho, s, nil
   139  
   140  	// dkg
   141  	case *messages.DKGMessage:
   142  		return CodeDKGMessage, s, nil
   143  
   144  	default:
   145  		return 0, "", fmt.Errorf("invalid encode type (%T)", v)
   146  	}
   147  }
   148  
   149  // InterfaceFromMessageCode returns an interface with the correct underlying go type
   150  // of the message code represents.
   151  // Expected error returns during normal operations:
   152  //   - ErrUnknownMsgCode if message code does not match any of the configured message codes above.
   153  func InterfaceFromMessageCode(code MessageCode) (interface{}, string, error) {
   154  	switch code {
   155  	// consensus
   156  	case CodeBlockProposal:
   157  		return &messages.BlockProposal{}, what(&messages.BlockProposal{}), nil
   158  	case CodeBlockVote:
   159  		return &messages.BlockVote{}, what(&messages.BlockVote{}), nil
   160  	case CodeTimeoutObject:
   161  		return &messages.TimeoutObject{}, what(&messages.TimeoutObject{}), nil
   162  
   163  	// cluster consensus
   164  	case CodeClusterBlockProposal:
   165  		return &messages.ClusterBlockProposal{}, what(&messages.ClusterBlockProposal{}), nil
   166  	case CodeClusterBlockVote:
   167  		return &messages.ClusterBlockVote{}, what(&messages.ClusterBlockVote{}), nil
   168  	case CodeClusterBlockResponse:
   169  		return &messages.ClusterBlockResponse{}, what(&messages.ClusterBlockResponse{}), nil
   170  	case CodeClusterTimeoutObject:
   171  		return &messages.ClusterTimeoutObject{}, what(&messages.ClusterTimeoutObject{}), nil
   172  
   173  	// protocol state sync
   174  	case CodeSyncRequest:
   175  		return &messages.SyncRequest{}, what(&messages.SyncRequest{}), nil
   176  	case CodeSyncResponse:
   177  		return &messages.SyncResponse{}, what(&messages.SyncResponse{}), nil
   178  	case CodeRangeRequest:
   179  		return &messages.RangeRequest{}, what(&messages.RangeRequest{}), nil
   180  	case CodeBatchRequest:
   181  		return &messages.BatchRequest{}, what(&messages.BatchRequest{}), nil
   182  	case CodeBlockResponse:
   183  		return &messages.BlockResponse{}, what(&messages.BlockResponse{}), nil
   184  
   185  	// collections, guarantees & transactions
   186  	case CodeCollectionGuarantee:
   187  		return &flow.CollectionGuarantee{}, what(&flow.CollectionGuarantee{}), nil
   188  	case CodeTransactionBody:
   189  		return &flow.TransactionBody{}, what(&flow.TransactionBody{}), nil
   190  	case CodeTransaction:
   191  		return &flow.Transaction{}, what(&flow.Transaction{}), nil
   192  
   193  	// core messages for execution & verification
   194  	case CodeExecutionReceipt:
   195  		return &flow.ExecutionReceipt{}, what(&flow.ExecutionReceipt{}), nil
   196  	case CodeResultApproval:
   197  		return &flow.ResultApproval{}, what(&flow.ResultApproval{}), nil
   198  
   199  	// data exchange for execution of blocks
   200  	case CodeChunkDataRequest:
   201  		return &messages.ChunkDataRequest{}, what(&messages.ChunkDataRequest{}), nil
   202  	case CodeChunkDataResponse:
   203  		return &messages.ChunkDataResponse{}, what(&messages.ChunkDataResponse{}), nil
   204  
   205  	// result approvals
   206  	case CodeApprovalRequest:
   207  		return &messages.ApprovalRequest{}, what(&messages.ApprovalRequest{}), nil
   208  	case CodeApprovalResponse:
   209  		return &messages.ApprovalResponse{}, what(&messages.ApprovalResponse{}), nil
   210  
   211  	// generic entity exchange engines
   212  	case CodeEntityRequest:
   213  		return &messages.EntityRequest{}, what(&messages.EntityRequest{}), nil
   214  	case CodeEntityResponse:
   215  		return &messages.EntityResponse{}, what(&messages.EntityResponse{}), nil
   216  
   217  	// dkg
   218  	case CodeDKGMessage:
   219  		return &messages.DKGMessage{}, what(&messages.DKGMessage{}), nil
   220  
   221  	// test messages
   222  	case CodeEcho:
   223  		return &message.TestMessage{}, what(&message.TestMessage{}), nil
   224  
   225  	default:
   226  		return nil, "", NewUnknownMsgCodeErr(code)
   227  	}
   228  }
   229  
   230  // MessageCodeFromPayload checks the length of the payload bytes before returning the first byte encoded MessageCode.
   231  // Expected error returns during normal operations:
   232  //   - ErrInvalidEncoding if payload is empty
   233  func MessageCodeFromPayload(payload []byte) (MessageCode, error) {
   234  	if len(payload) == 0 {
   235  		return 0, NewInvalidEncodingErr(fmt.Errorf("empty payload"))
   236  	}
   237  
   238  	return MessageCode(payload[0]), nil
   239  }
   240  
   241  func what(v interface{}) string {
   242  	return fmt.Sprintf("%T", v)
   243  }