forked from onflow/flow-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconvert.go
126 lines (109 loc) · 3.91 KB
/
convert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package execution
import (
"fmt"
"github.com/onflow/flow-go/model/convert"
"github.com/onflow/flow-go/model/flow"
)
func GenerateExecutionResultAndChunkDataPacks(
prevResultId flow.Identifier,
startState flow.StateCommitment,
result *ComputationResult) (
endState flow.StateCommitment,
chdps []*flow.ChunkDataPack,
executionResult *flow.ExecutionResult,
err error,
) {
// no need to persist the state interactions, since they are used only by state
// syncing, which is currently disabled
block := result.ExecutableBlock.Block
blockID := block.ID()
chunks := make([]*flow.Chunk, len(result.StateCommitments))
chdps = make([]*flow.ChunkDataPack, len(result.StateCommitments))
// TODO: check current state root == startState
endState = startState
for i := range result.StateCommitments {
// TODO: deltas should be applied to a particular state
endState = result.StateCommitments[i]
var chunk *flow.Chunk
// account for system chunk being last
if i < len(result.StateCommitments)-1 {
// non-system chunks
collectionGuarantee := result.ExecutableBlock.Block.Payload.Guarantees[i]
completeCollection := result.ExecutableBlock.CompleteCollections[collectionGuarantee.ID()]
collection := completeCollection.Collection()
chunk = GenerateChunk(i, startState, endState, blockID, result.EventsHashes[i], uint64(len(completeCollection.Transactions)))
chdps[i] = GenerateChunkDataPack(chunk.ID(), startState, &collection, result.Proofs[i])
} else {
// system chunk
// note that system chunk does not have a collection.
// also, number of transactions is one for system chunk.
chunk = GenerateChunk(i, startState, endState, blockID, result.EventsHashes[i], 1)
// system chunk has a nil collection.
chdps[i] = GenerateChunkDataPack(chunk.ID(), startState, nil, result.Proofs[i])
}
// TODO use view.SpockSecret() as an input to spock generator
chunks[i] = chunk
startState = endState
}
executionResult, err = GenerateExecutionResultForBlock(prevResultId, block, chunks, result.ServiceEvents)
if err != nil {
return flow.DummyStateCommitment, nil, nil, fmt.Errorf("could not generate execution result: %w", err)
}
return endState, chdps, executionResult, nil
}
// GenerateExecutionResultForBlock creates new ExecutionResult for a block from
// the provided chunk results.
func GenerateExecutionResultForBlock(
previousErID flow.Identifier,
block *flow.Block,
chunks []*flow.Chunk,
serviceEvents []flow.Event,
) (*flow.ExecutionResult, error) {
// convert Cadence service event representation to flow-go representation
convertedServiceEvents := make([]flow.ServiceEvent, 0, len(serviceEvents))
for _, event := range serviceEvents {
converted, err := convert.ServiceEvent(block.Header.ChainID, event)
if err != nil {
return nil, fmt.Errorf("could not convert service event: %w", err)
}
convertedServiceEvents = append(convertedServiceEvents, *converted)
}
er := &flow.ExecutionResult{
PreviousResultID: previousErID,
BlockID: block.ID(),
Chunks: chunks,
ServiceEvents: convertedServiceEvents,
}
return er, nil
}
// GenerateChunk creates a chunk from the provided computation data.
func GenerateChunk(colIndex int,
startState, endState flow.StateCommitment,
blockID, eventsCollection flow.Identifier, txNumber uint64) *flow.Chunk {
return &flow.Chunk{
ChunkBody: flow.ChunkBody{
CollectionIndex: uint(colIndex),
StartState: startState,
EventCollection: eventsCollection,
BlockID: blockID,
// TODO: record gas used
TotalComputationUsed: 0,
NumberOfTransactions: txNumber,
},
Index: uint64(colIndex),
EndState: endState,
}
}
func GenerateChunkDataPack(
chunkID flow.Identifier,
startState flow.StateCommitment,
collection *flow.Collection,
proof flow.StorageProof,
) *flow.ChunkDataPack {
return &flow.ChunkDataPack{
ChunkID: chunkID,
StartState: startState,
Proof: proof,
Collection: collection,
}
}