-
Notifications
You must be signed in to change notification settings - Fork 177
/
chunk.go
150 lines (128 loc) · 4.02 KB
/
chunk.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package flow
type ChunkBody struct {
CollectionIndex uint
// execution info
StartState StateCommitment // start state when starting executing this chunk
EventCollection Identifier // Events generated by executing results
BlockID Identifier // Block id of the execution result this chunk belongs to
// Computation consumption info
TotalComputationUsed uint64 // total amount of computation used by running all txs in this chunk
NumberOfTransactions uint64 // number of transactions inside the collection
}
type Chunk struct {
ChunkBody
Index uint64 // chunk index inside the ER (starts from zero)
// EndState inferred from next chunk or from the ER
EndState StateCommitment
}
func NewChunk(
blockID Identifier,
collectionIndex int,
startState StateCommitment,
numberOfTransactions int,
eventCollection Identifier,
endState StateCommitment,
) *Chunk {
return &Chunk{
ChunkBody: ChunkBody{
BlockID: blockID,
CollectionIndex: uint(collectionIndex),
StartState: startState,
NumberOfTransactions: uint64(numberOfTransactions),
EventCollection: eventCollection,
TotalComputationUsed: 0, // TODO: record gas used
},
Index: uint64(collectionIndex),
EndState: endState,
}
}
// ID returns a unique id for this entity
func (ch *Chunk) ID() Identifier {
return MakeID(ch.ChunkBody)
}
// Checksum provides a cryptographic commitment for a chunk content
func (ch *Chunk) Checksum() Identifier {
return MakeID(ch)
}
// ChunkDataPack holds all register touches (any read, or write).
//
// Note that we have to capture a read proof for each write before updating the registers.
// `Proof` includes proofs for all registers read to execute the chunck.
// Register proofs order must not be correlated to the order of register reads during
// the chunk execution in order to enforce the SPoCK secret high entropy.
type ChunkDataPack struct {
ChunkID Identifier
StartState StateCommitment
Proof StorageProof
Collection *Collection
}
// NewChunkDataPack returns an initialized chunk data pack.
func NewChunkDataPack(
chunkID Identifier,
startState StateCommitment,
proof StorageProof,
collection *Collection,
) *ChunkDataPack {
return &ChunkDataPack{
ChunkID: chunkID,
StartState: startState,
Proof: proof,
Collection: collection,
}
}
// ID returns the unique identifier for the concrete view, which is the ID of
// the chunk the view is for.
func (c *ChunkDataPack) ID() Identifier {
return c.ChunkID
}
// Checksum returns the checksum of the chunk data pack.
func (c *ChunkDataPack) Checksum() Identifier {
return MakeID(c)
}
// TODO: This is the basic version of the list, we need to substitute it with something like Merkle tree at some point
type ChunkList []*Chunk
func (cl ChunkList) Fingerprint() Identifier {
return MerkleRoot(GetIDs(cl)...)
}
func (cl *ChunkList) Insert(ch *Chunk) {
*cl = append(*cl, ch)
}
func (cl ChunkList) Items() []*Chunk {
return cl
}
// Empty returns true if the chunk list is empty. Otherwise it returns false.
func (cl ChunkList) Empty() bool {
return len(cl) == 0
}
func (cl ChunkList) Indices() []uint64 {
indices := make([]uint64, len(cl))
for i, chunk := range cl {
indices[i] = chunk.Index
}
return indices
}
// ByChecksum returns an entity from the list by entity fingerprint
func (cl ChunkList) ByChecksum(cs Identifier) (*Chunk, bool) {
for _, ch := range cl {
if ch.Checksum() == cs {
return ch, true
}
}
return nil, false
}
// ByIndex returns an entity from the list by index
// if requested chunk is within range of list, it returns chunk and true
// if requested chunk is out of the range, it returns nil and false
// boolean return value indicates whether requested chunk is within range
func (cl ChunkList) ByIndex(i uint64) (*Chunk, bool) {
if i >= uint64(len(cl)) {
// index out of range
return nil, false
}
return cl[i], true
}
// Len returns the number of Chunks in the list. It is also part of the sort
// interface that makes ChunkList sortable
func (cl ChunkList) Len() int {
return len(cl)
}