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 }