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

     1  package convert
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow/protobuf/go/flow/entities"
     7  
     8  	"github.com/onflow/flow-go/model/flow"
     9  )
    10  
    11  // ExecutionResultToMessage converts an execution result to a protobuf message
    12  func ExecutionResultToMessage(er *flow.ExecutionResult) (
    13  	*entities.ExecutionResult,
    14  	error,
    15  ) {
    16  	chunks := make([]*entities.Chunk, len(er.Chunks))
    17  
    18  	for i, chunk := range er.Chunks {
    19  		chunks[i] = ChunkToMessage(chunk)
    20  	}
    21  
    22  	serviceEvents := make([]*entities.ServiceEvent, len(er.ServiceEvents))
    23  	var err error
    24  	for i, serviceEvent := range er.ServiceEvents {
    25  		serviceEvents[i], err = ServiceEventToMessage(serviceEvent)
    26  		if err != nil {
    27  			return nil, fmt.Errorf("error while convering service event %d: %w", i, err)
    28  		}
    29  	}
    30  
    31  	return &entities.ExecutionResult{
    32  		PreviousResultId: IdentifierToMessage(er.PreviousResultID),
    33  		BlockId:          IdentifierToMessage(er.BlockID),
    34  		Chunks:           chunks,
    35  		ServiceEvents:    serviceEvents,
    36  		ExecutionDataId:  IdentifierToMessage(er.ExecutionDataID),
    37  	}, nil
    38  }
    39  
    40  // MessageToExecutionResult converts a protobuf message to an execution result
    41  func MessageToExecutionResult(m *entities.ExecutionResult) (
    42  	*flow.ExecutionResult,
    43  	error,
    44  ) {
    45  	// convert Chunks
    46  	parsedChunks, err := MessagesToChunkList(m.Chunks)
    47  	if err != nil {
    48  		return nil, fmt.Errorf("failed to parse messages to ChunkList: %w", err)
    49  	}
    50  	// convert ServiceEvents
    51  	parsedServiceEvents, err := MessagesToServiceEventList(m.ServiceEvents)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	return &flow.ExecutionResult{
    56  		PreviousResultID: MessageToIdentifier(m.PreviousResultId),
    57  		BlockID:          MessageToIdentifier(m.BlockId),
    58  		Chunks:           parsedChunks,
    59  		ServiceEvents:    parsedServiceEvents,
    60  		ExecutionDataID:  MessageToIdentifier(m.ExecutionDataId),
    61  	}, nil
    62  }
    63  
    64  // ExecutionResultsToMessages converts a slice of execution results to a slice of protobuf messages
    65  func ExecutionResultsToMessages(e []*flow.ExecutionResult) (
    66  	[]*entities.ExecutionResult,
    67  	error,
    68  ) {
    69  	execResults := make([]*entities.ExecutionResult, len(e))
    70  	for i, execRes := range e {
    71  		parsedExecResult, err := ExecutionResultToMessage(execRes)
    72  		if err != nil {
    73  			return nil, err
    74  		}
    75  		execResults[i] = parsedExecResult
    76  	}
    77  	return execResults, nil
    78  }
    79  
    80  // MessagesToExecutionResults converts a slice of protobuf messages to a slice of execution results
    81  func MessagesToExecutionResults(m []*entities.ExecutionResult) (
    82  	[]*flow.ExecutionResult,
    83  	error,
    84  ) {
    85  	execResults := make([]*flow.ExecutionResult, len(m))
    86  	for i, e := range m {
    87  		parsedExecResult, err := MessageToExecutionResult(e)
    88  		if err != nil {
    89  			return nil, fmt.Errorf("failed to convert message at index %d to execution result: %w", i, err)
    90  		}
    91  		execResults[i] = parsedExecResult
    92  	}
    93  	return execResults, nil
    94  }
    95  
    96  // ExecutionResultMetaListToMessages converts an execution result meta list to a slice of protobuf messages
    97  func ExecutionResultMetaListToMessages(e flow.ExecutionReceiptMetaList) []*entities.ExecutionReceiptMeta {
    98  	messageList := make([]*entities.ExecutionReceiptMeta, len(e))
    99  	for i, execMeta := range e {
   100  		messageList[i] = &entities.ExecutionReceiptMeta{
   101  			ExecutorId:        IdentifierToMessage(execMeta.ExecutorID),
   102  			ResultId:          IdentifierToMessage(execMeta.ResultID),
   103  			Spocks:            SignaturesToMessages(execMeta.Spocks),
   104  			ExecutorSignature: MessageToSignature(execMeta.ExecutorSignature),
   105  		}
   106  	}
   107  	return messageList
   108  }
   109  
   110  // MessagesToExecutionResultMetaList converts a slice of protobuf messages to an execution result meta list
   111  func MessagesToExecutionResultMetaList(m []*entities.ExecutionReceiptMeta) flow.ExecutionReceiptMetaList {
   112  	execMetaList := make([]*flow.ExecutionReceiptMeta, len(m))
   113  	for i, message := range m {
   114  		execMetaList[i] = &flow.ExecutionReceiptMeta{
   115  			ExecutorID:        MessageToIdentifier(message.ExecutorId),
   116  			ResultID:          MessageToIdentifier(message.ResultId),
   117  			Spocks:            MessagesToSignatures(message.Spocks),
   118  			ExecutorSignature: MessageToSignature(message.ExecutorSignature),
   119  		}
   120  	}
   121  	return execMetaList[:]
   122  }
   123  
   124  // ChunkToMessage converts a chunk to a protobuf message
   125  func ChunkToMessage(chunk *flow.Chunk) *entities.Chunk {
   126  	return &entities.Chunk{
   127  		CollectionIndex:      uint32(chunk.CollectionIndex),
   128  		StartState:           StateCommitmentToMessage(chunk.StartState),
   129  		EventCollection:      IdentifierToMessage(chunk.EventCollection),
   130  		BlockId:              IdentifierToMessage(chunk.BlockID),
   131  		TotalComputationUsed: chunk.TotalComputationUsed,
   132  		NumberOfTransactions: uint32(chunk.NumberOfTransactions),
   133  		Index:                chunk.Index,
   134  		EndState:             StateCommitmentToMessage(chunk.EndState),
   135  	}
   136  }
   137  
   138  // MessageToChunk converts a protobuf message to a chunk
   139  func MessageToChunk(m *entities.Chunk) (*flow.Chunk, error) {
   140  	startState, err := flow.ToStateCommitment(m.StartState)
   141  	if err != nil {
   142  		return nil, fmt.Errorf("failed to parse Message start state to Chunk: %w", err)
   143  	}
   144  	endState, err := flow.ToStateCommitment(m.EndState)
   145  	if err != nil {
   146  		return nil, fmt.Errorf("failed to parse Message end state to Chunk: %w", err)
   147  	}
   148  	chunkBody := flow.ChunkBody{
   149  		CollectionIndex:      uint(m.CollectionIndex),
   150  		StartState:           startState,
   151  		EventCollection:      MessageToIdentifier(m.EventCollection),
   152  		BlockID:              MessageToIdentifier(m.BlockId),
   153  		TotalComputationUsed: m.TotalComputationUsed,
   154  		NumberOfTransactions: uint64(m.NumberOfTransactions),
   155  	}
   156  	return &flow.Chunk{
   157  		ChunkBody: chunkBody,
   158  		Index:     m.Index,
   159  		EndState:  endState,
   160  	}, nil
   161  }
   162  
   163  // MessagesToChunkList converts a slice of protobuf messages to a chunk list
   164  func MessagesToChunkList(m []*entities.Chunk) (flow.ChunkList, error) {
   165  	parsedChunks := make(flow.ChunkList, len(m))
   166  	for i, chunk := range m {
   167  		parsedChunk, err := MessageToChunk(chunk)
   168  		if err != nil {
   169  			return nil, fmt.Errorf("failed to parse message at index %d to chunk: %w", i, err)
   170  		}
   171  		parsedChunks[i] = parsedChunk
   172  	}
   173  	return parsedChunks, nil
   174  }