github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/common/rpc/convert/blocks.go (about)

     1  package convert
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"google.golang.org/protobuf/types/known/timestamppb"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  
    10  	"github.com/onflow/flow/protobuf/go/flow/entities"
    11  )
    12  
    13  // BlockToMessage converts a flow.Block to a protobuf Block message.
    14  // signerIDs is a precomputed list of signer IDs for the block based on the block's signer indicies.
    15  func BlockToMessage(h *flow.Block, signerIDs flow.IdentifierList) (
    16  	*entities.Block,
    17  	error,
    18  ) {
    19  	id := h.ID()
    20  
    21  	parentID := h.Header.ParentID
    22  	t := timestamppb.New(h.Header.Timestamp)
    23  	cg := CollectionGuaranteesToMessages(h.Payload.Guarantees)
    24  
    25  	seals := BlockSealsToMessages(h.Payload.Seals)
    26  
    27  	execResults, err := ExecutionResultsToMessages(h.Payload.Results)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	blockHeader, err := BlockHeaderToMessage(h.Header, signerIDs)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	bh := entities.Block{
    38  		Id:                       IdentifierToMessage(id),
    39  		Height:                   h.Header.Height,
    40  		ParentId:                 IdentifierToMessage(parentID),
    41  		Timestamp:                t,
    42  		CollectionGuarantees:     cg,
    43  		BlockSeals:               seals,
    44  		Signatures:               [][]byte{h.Header.ParentVoterSigData},
    45  		ExecutionReceiptMetaList: ExecutionResultMetaListToMessages(h.Payload.Receipts),
    46  		ExecutionResultList:      execResults,
    47  		ProtocolStateId:          IdentifierToMessage(h.Payload.ProtocolStateID),
    48  		BlockHeader:              blockHeader,
    49  	}
    50  
    51  	return &bh, nil
    52  }
    53  
    54  // BlockToMessageLight converts a flow.Block to the light form of a protobuf Block message.
    55  func BlockToMessageLight(h *flow.Block) *entities.Block {
    56  	id := h.ID()
    57  
    58  	parentID := h.Header.ParentID
    59  	t := timestamppb.New(h.Header.Timestamp)
    60  	cg := CollectionGuaranteesToMessages(h.Payload.Guarantees)
    61  
    62  	return &entities.Block{
    63  		Id:                   id[:],
    64  		Height:               h.Header.Height,
    65  		ParentId:             parentID[:],
    66  		Timestamp:            t,
    67  		CollectionGuarantees: cg,
    68  		Signatures:           [][]byte{h.Header.ParentVoterSigData},
    69  	}
    70  }
    71  
    72  // MessageToBlock converts a protobuf Block message to a flow.Block.
    73  func MessageToBlock(m *entities.Block) (*flow.Block, error) {
    74  	payload, err := PayloadFromMessage(m)
    75  	if err != nil {
    76  		return nil, fmt.Errorf("failed to extract payload data from message: %w", err)
    77  	}
    78  	header, err := MessageToBlockHeader(m.BlockHeader)
    79  	if err != nil {
    80  		return nil, fmt.Errorf("failed to convert block header: %w", err)
    81  	}
    82  	return &flow.Block{
    83  		Header:  header,
    84  		Payload: payload,
    85  	}, nil
    86  }
    87  
    88  // BlockSealToMessage converts a flow.Seal to a protobuf BlockSeal message.
    89  func BlockSealToMessage(s *flow.Seal) *entities.BlockSeal {
    90  	id := s.BlockID
    91  	result := s.ResultID
    92  	return &entities.BlockSeal{
    93  		BlockId:                    id[:],
    94  		ExecutionReceiptId:         result[:],
    95  		ExecutionReceiptSignatures: [][]byte{}, // filling seals signature with zero
    96  		FinalState:                 StateCommitmentToMessage(s.FinalState),
    97  		AggregatedApprovalSigs:     AggregatedSignaturesToMessages(s.AggregatedApprovalSigs),
    98  		ResultId:                   IdentifierToMessage(s.ResultID),
    99  	}
   100  }
   101  
   102  // MessageToBlockSeal converts a protobuf BlockSeal message to a flow.Seal.
   103  func MessageToBlockSeal(m *entities.BlockSeal) (*flow.Seal, error) {
   104  	finalState, err := MessageToStateCommitment(m.FinalState)
   105  	if err != nil {
   106  		return nil, fmt.Errorf("failed to convert message to block seal: %w", err)
   107  	}
   108  	return &flow.Seal{
   109  		BlockID:                MessageToIdentifier(m.BlockId),
   110  		ResultID:               MessageToIdentifier(m.ResultId),
   111  		FinalState:             finalState,
   112  		AggregatedApprovalSigs: MessagesToAggregatedSignatures(m.AggregatedApprovalSigs),
   113  	}, nil
   114  }
   115  
   116  // BlockSealsToMessages converts a slice of flow.Seal to a slice of protobuf BlockSeal messages.
   117  func BlockSealsToMessages(b []*flow.Seal) []*entities.BlockSeal {
   118  	seals := make([]*entities.BlockSeal, len(b))
   119  	for i, s := range b {
   120  		seals[i] = BlockSealToMessage(s)
   121  	}
   122  	return seals
   123  }
   124  
   125  // MessagesToBlockSeals converts a slice of protobuf BlockSeal messages to a slice of flow.Seal.
   126  func MessagesToBlockSeals(m []*entities.BlockSeal) ([]*flow.Seal, error) {
   127  	seals := make([]*flow.Seal, len(m))
   128  	for i, s := range m {
   129  		msg, err := MessageToBlockSeal(s)
   130  		if err != nil {
   131  			return nil, err
   132  		}
   133  		seals[i] = msg
   134  	}
   135  	return seals, nil
   136  }
   137  
   138  // PayloadFromMessage converts a protobuf Block message to a flow.Payload.
   139  func PayloadFromMessage(m *entities.Block) (*flow.Payload, error) {
   140  	cgs := MessagesToCollectionGuarantees(m.CollectionGuarantees)
   141  	seals, err := MessagesToBlockSeals(m.BlockSeals)
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  	receipts := MessagesToExecutionResultMetaList(m.ExecutionReceiptMetaList)
   146  	results, err := MessagesToExecutionResults(m.ExecutionResultList)
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  	return &flow.Payload{
   151  		Guarantees:      cgs,
   152  		Seals:           seals,
   153  		Receipts:        receipts,
   154  		Results:         results,
   155  		ProtocolStateID: MessageToIdentifier(m.ProtocolStateId),
   156  	}, nil
   157  }
   158  
   159  // MessageToBlockStatus converts a protobuf BlockStatus message to a flow.BlockStatus.
   160  func MessageToBlockStatus(status entities.BlockStatus) flow.BlockStatus {
   161  	switch status {
   162  	case entities.BlockStatus_BLOCK_UNKNOWN:
   163  		return flow.BlockStatusUnknown
   164  	case entities.BlockStatus_BLOCK_FINALIZED:
   165  		return flow.BlockStatusFinalized
   166  	case entities.BlockStatus_BLOCK_SEALED:
   167  		return flow.BlockStatusSealed
   168  	}
   169  	return flow.BlockStatusUnknown
   170  }