github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/codec/codes.go (about)

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