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  }