github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/access/legacy/convert/convert.go (about) 1 package convert 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/onflow/crypto" 8 "github.com/onflow/crypto/hash" 9 accessproto "github.com/onflow/flow/protobuf/go/flow/legacy/access" 10 entitiesproto "github.com/onflow/flow/protobuf/go/flow/legacy/entities" 11 "google.golang.org/protobuf/types/known/timestamppb" 12 13 "github.com/onflow/flow-go/access" 14 "github.com/onflow/flow-go/engine/common/rpc/convert" 15 "github.com/onflow/flow-go/model/flow" 16 ) 17 18 var ErrEmptyMessage = errors.New("protobuf message is empty") 19 20 func MessageToTransaction(m *entitiesproto.Transaction, chain flow.Chain) (flow.TransactionBody, error) { 21 if m == nil { 22 return flow.TransactionBody{}, ErrEmptyMessage 23 } 24 25 t := flow.NewTransactionBody() 26 27 proposalKey := m.GetProposalKey() 28 if proposalKey != nil { 29 proposalAddress, err := convert.Address(proposalKey.GetAddress(), chain) 30 if err != nil { 31 return *t, err 32 } 33 t.SetProposalKey(proposalAddress, uint64(proposalKey.GetKeyId()), proposalKey.GetSequenceNumber()) 34 } 35 36 payer := m.GetPayer() 37 if payer != nil { 38 payerAddress, err := convert.Address(payer, chain) 39 if err != nil { 40 return *t, err 41 } 42 t.SetPayer(payerAddress) 43 } 44 45 for _, authorizer := range m.GetAuthorizers() { 46 authorizerAddress, err := convert.Address(authorizer, chain) 47 if err != nil { 48 return *t, err 49 } 50 t.AddAuthorizer(authorizerAddress) 51 } 52 53 for _, sig := range m.GetPayloadSignatures() { 54 addr, err := convert.Address(sig.GetAddress(), chain) 55 if err != nil { 56 return *t, err 57 } 58 t.AddPayloadSignature(addr, uint64(sig.GetKeyId()), sig.GetSignature()) 59 } 60 61 for _, sig := range m.GetEnvelopeSignatures() { 62 addr, err := convert.Address(sig.GetAddress(), chain) 63 if err != nil { 64 return *t, err 65 } 66 t.AddEnvelopeSignature(addr, uint64(sig.GetKeyId()), sig.GetSignature()) 67 } 68 69 t.SetScript(m.GetScript()) 70 t.SetArguments(m.GetArguments()) 71 t.SetReferenceBlockID(flow.HashToID(m.GetReferenceBlockId())) 72 t.SetComputeLimit(m.GetGasLimit()) 73 74 return *t, nil 75 } 76 77 func TransactionToMessage(tb flow.TransactionBody) *entitiesproto.Transaction { 78 proposalKeyMessage := &entitiesproto.Transaction_ProposalKey{ 79 Address: tb.ProposalKey.Address.Bytes(), 80 KeyId: uint32(tb.ProposalKey.KeyIndex), 81 SequenceNumber: tb.ProposalKey.SequenceNumber, 82 } 83 84 authMessages := make([][]byte, len(tb.Authorizers)) 85 for i, auth := range tb.Authorizers { 86 authMessages[i] = auth.Bytes() 87 } 88 89 payloadSigMessages := make([]*entitiesproto.Transaction_Signature, len(tb.PayloadSignatures)) 90 91 for i, sig := range tb.PayloadSignatures { 92 payloadSigMessages[i] = &entitiesproto.Transaction_Signature{ 93 Address: sig.Address.Bytes(), 94 KeyId: uint32(sig.KeyIndex), 95 Signature: sig.Signature, 96 } 97 } 98 99 envelopeSigMessages := make([]*entitiesproto.Transaction_Signature, len(tb.EnvelopeSignatures)) 100 101 for i, sig := range tb.EnvelopeSignatures { 102 envelopeSigMessages[i] = &entitiesproto.Transaction_Signature{ 103 Address: sig.Address.Bytes(), 104 KeyId: uint32(sig.KeyIndex), 105 Signature: sig.Signature, 106 } 107 } 108 109 return &entitiesproto.Transaction{ 110 Script: tb.Script, 111 Arguments: tb.Arguments, 112 ReferenceBlockId: tb.ReferenceBlockID[:], 113 GasLimit: tb.GasLimit, 114 ProposalKey: proposalKeyMessage, 115 Payer: tb.Payer.Bytes(), 116 Authorizers: authMessages, 117 PayloadSignatures: payloadSigMessages, 118 EnvelopeSignatures: envelopeSigMessages, 119 } 120 } 121 122 func TransactionResultToMessage(result access.TransactionResult) *accessproto.TransactionResultResponse { 123 return &accessproto.TransactionResultResponse{ 124 Status: entitiesproto.TransactionStatus(result.Status), 125 StatusCode: uint32(result.StatusCode), 126 ErrorMessage: result.ErrorMessage, 127 Events: EventsToMessages(result.Events), 128 } 129 } 130 131 func BlockHeaderToMessage(h *flow.Header) (*entitiesproto.BlockHeader, error) { 132 id := h.ID() 133 134 t := timestamppb.New(h.Timestamp) 135 136 return &entitiesproto.BlockHeader{ 137 Id: id[:], 138 ParentId: h.ParentID[:], 139 Height: h.Height, 140 Timestamp: t, 141 }, nil 142 } 143 144 func BlockToMessage(h *flow.Block) (*entitiesproto.Block, error) { 145 id := h.ID() 146 147 parentID := h.Header.ParentID 148 t := timestamppb.New(h.Header.Timestamp) 149 150 cg := make([]*entitiesproto.CollectionGuarantee, len(h.Payload.Guarantees)) 151 for i, g := range h.Payload.Guarantees { 152 cg[i] = collectionGuaranteeToMessage(g) 153 } 154 155 seals := make([]*entitiesproto.BlockSeal, len(h.Payload.Seals)) 156 for i, s := range h.Payload.Seals { 157 seals[i] = blockSealToMessage(s) 158 } 159 160 bh := entitiesproto.Block{ 161 Id: id[:], 162 Height: h.Header.Height, 163 ParentId: parentID[:], 164 Timestamp: t, 165 CollectionGuarantees: cg, 166 BlockSeals: seals, 167 Signatures: [][]byte{h.Header.ParentVoterSigData}, 168 } 169 170 return &bh, nil 171 } 172 173 func collectionGuaranteeToMessage(g *flow.CollectionGuarantee) *entitiesproto.CollectionGuarantee { 174 id := g.ID() 175 176 return &entitiesproto.CollectionGuarantee{ 177 CollectionId: id[:], 178 Signatures: [][]byte{g.Signature}, 179 } 180 } 181 182 func blockSealToMessage(s *flow.Seal) *entitiesproto.BlockSeal { 183 id := s.BlockID 184 result := s.ResultID 185 return &entitiesproto.BlockSeal{ 186 BlockId: id[:], 187 ExecutionReceiptId: result[:], 188 ExecutionReceiptSignatures: [][]byte{}, // filling seals signature with zero 189 } 190 } 191 192 func LightCollectionToMessage(c *flow.LightCollection) (*entitiesproto.Collection, error) { 193 if c == nil || c.Transactions == nil { 194 return nil, fmt.Errorf("invalid collection") 195 } 196 197 collectionID := c.ID() 198 199 return &entitiesproto.Collection{ 200 Id: collectionID[:], 201 TransactionIds: IdentifiersToMessages(c.Transactions), 202 }, nil 203 } 204 205 func EventToMessage(e flow.Event) *entitiesproto.Event { 206 return &entitiesproto.Event{ 207 Type: string(e.Type), 208 TransactionId: e.TransactionID[:], 209 TransactionIndex: e.TransactionIndex, 210 EventIndex: e.EventIndex, 211 Payload: e.Payload, 212 } 213 } 214 215 func AccountToMessage(a *flow.Account) (*entitiesproto.Account, error) { 216 keys := make([]*entitiesproto.AccountKey, len(a.Keys)) 217 for i, k := range a.Keys { 218 messageKey, err := AccountKeyToMessage(k) 219 if err != nil { 220 return nil, err 221 } 222 keys[i] = messageKey 223 } 224 225 return &entitiesproto.Account{ 226 Address: a.Address.Bytes(), 227 Balance: a.Balance, 228 Code: nil, 229 Keys: keys, 230 }, nil 231 } 232 233 func MessageToAccountKey(m *entitiesproto.AccountKey) (*flow.AccountPublicKey, error) { 234 if m == nil { 235 return nil, ErrEmptyMessage 236 } 237 238 sigAlgo := crypto.SigningAlgorithm(m.GetSignAlgo()) 239 hashAlgo := hash.HashingAlgorithm(m.GetHashAlgo()) 240 241 publicKey, err := crypto.DecodePublicKey(sigAlgo, m.GetPublicKey()) 242 if err != nil { 243 return nil, err 244 } 245 246 return &flow.AccountPublicKey{ 247 PublicKey: publicKey, 248 SignAlgo: sigAlgo, 249 HashAlgo: hashAlgo, 250 Weight: int(m.GetWeight()), 251 SeqNumber: uint64(m.GetSequenceNumber()), 252 }, nil 253 } 254 255 func AccountKeyToMessage(a flow.AccountPublicKey) (*entitiesproto.AccountKey, error) { 256 return &entitiesproto.AccountKey{ 257 Index: uint32(a.Index), 258 PublicKey: a.PublicKey.Encode(), 259 SignAlgo: uint32(a.SignAlgo), 260 HashAlgo: uint32(a.HashAlgo), 261 Weight: uint32(a.Weight), 262 SequenceNumber: uint32(a.SeqNumber), 263 }, nil 264 } 265 266 func EventsToMessages(flowEvents []flow.Event) []*entitiesproto.Event { 267 events := make([]*entitiesproto.Event, len(flowEvents)) 268 for i, e := range flowEvents { 269 event := EventToMessage(e) 270 events[i] = event 271 } 272 return events 273 } 274 275 func IdentifierToMessage(i flow.Identifier) []byte { 276 return i[:] 277 } 278 279 func MessageToIdentifier(b []byte) flow.Identifier { 280 return flow.HashToID(b) 281 } 282 283 func IdentifiersToMessages(l []flow.Identifier) [][]byte { 284 results := make([][]byte, len(l)) 285 for i, item := range l { 286 results[i] = IdentifierToMessage(item) 287 } 288 return results 289 } 290 291 func MessagesToIdentifiers(l [][]byte) []flow.Identifier { 292 results := make([]flow.Identifier, len(l)) 293 for i, item := range l { 294 results[i] = MessageToIdentifier(item) 295 } 296 return results 297 }