github.com/onflow/flow-go@v0.33.17/model/flow/chunk.go (about) 1 package flow 2 3 import ( 4 "github.com/ipfs/go-cid" 5 ) 6 7 type ChunkBody struct { 8 CollectionIndex uint 9 10 // execution info 11 StartState StateCommitment // start state when starting executing this chunk 12 EventCollection Identifier // Events generated by executing results 13 BlockID Identifier // Block id of the execution result this chunk belongs to 14 15 // Computation consumption info 16 TotalComputationUsed uint64 // total amount of computation used by running all txs in this chunk 17 NumberOfTransactions uint64 // number of transactions inside the collection 18 } 19 20 type Chunk struct { 21 ChunkBody 22 23 Index uint64 // chunk index inside the ER (starts from zero) 24 // EndState inferred from next chunk or from the ER 25 EndState StateCommitment 26 } 27 28 func NewChunk( 29 blockID Identifier, 30 collectionIndex int, 31 startState StateCommitment, 32 numberOfTransactions int, 33 eventCollection Identifier, 34 endState StateCommitment, 35 totalComputationUsed uint64, 36 ) *Chunk { 37 return &Chunk{ 38 ChunkBody: ChunkBody{ 39 BlockID: blockID, 40 CollectionIndex: uint(collectionIndex), 41 StartState: startState, 42 NumberOfTransactions: uint64(numberOfTransactions), 43 EventCollection: eventCollection, 44 TotalComputationUsed: totalComputationUsed, 45 }, 46 Index: uint64(collectionIndex), 47 EndState: endState, 48 } 49 } 50 51 // ID returns a unique id for this entity 52 func (ch *Chunk) ID() Identifier { 53 return MakeID(ch.ChunkBody) 54 } 55 56 // Checksum provides a cryptographic commitment for a chunk content 57 func (ch *Chunk) Checksum() Identifier { 58 return MakeID(ch) 59 } 60 61 // ChunkDataPack holds all register touches (any read, or write). 62 // 63 // Note that we have to capture a read proof for each write before updating the registers. 64 // `Proof` includes proofs for all registers read to execute the chunk. 65 // Register proofs order must not be correlated to the order of register reads during 66 // the chunk execution in order to enforce the SPoCK secret high entropy. 67 type ChunkDataPack struct { 68 ChunkID Identifier // ID of the chunk this data pack is for 69 StartState StateCommitment // commitment for starting state 70 Proof StorageProof // proof for all registers read during the chunk execution 71 Collection *Collection // collection executed in this chunk 72 73 // ExecutionDataRoot is the root data structure of an execution_data.BlockExecutionData. 74 // It contains the necessary information for a verification node to validate that the 75 // BlockExecutionData produced is valid. 76 ExecutionDataRoot BlockExecutionDataRoot 77 } 78 79 // NewChunkDataPack returns an initialized chunk data pack. 80 func NewChunkDataPack( 81 chunkID Identifier, 82 startState StateCommitment, 83 proof StorageProof, 84 collection *Collection, 85 execDataRoot BlockExecutionDataRoot, 86 ) *ChunkDataPack { 87 return &ChunkDataPack{ 88 ChunkID: chunkID, 89 StartState: startState, 90 Proof: proof, 91 Collection: collection, 92 ExecutionDataRoot: execDataRoot, 93 } 94 } 95 96 // ID returns the unique identifier for the concrete view, which is the ID of 97 // the chunk the view is for. 98 func (c *ChunkDataPack) ID() Identifier { 99 return c.ChunkID 100 } 101 102 // Checksum returns the checksum of the chunk data pack. 103 func (c *ChunkDataPack) Checksum() Identifier { 104 return MakeID(c) 105 } 106 107 // TODO: This is the basic version of the list, we need to substitute it with something like Merkle tree at some point 108 type ChunkList []*Chunk 109 110 func (cl ChunkList) Fingerprint() Identifier { 111 return MerkleRoot(GetIDs(cl)...) 112 } 113 114 func (cl *ChunkList) Insert(ch *Chunk) { 115 *cl = append(*cl, ch) 116 } 117 118 func (cl ChunkList) Items() []*Chunk { 119 return cl 120 } 121 122 // Empty returns true if the chunk list is empty. Otherwise it returns false. 123 func (cl ChunkList) Empty() bool { 124 return len(cl) == 0 125 } 126 127 func (cl ChunkList) Indices() []uint64 { 128 indices := make([]uint64, len(cl)) 129 for i, chunk := range cl { 130 indices[i] = chunk.Index 131 } 132 133 return indices 134 } 135 136 // ByChecksum returns an entity from the list by entity fingerprint 137 func (cl ChunkList) ByChecksum(cs Identifier) (*Chunk, bool) { 138 for _, ch := range cl { 139 if ch.Checksum() == cs { 140 return ch, true 141 } 142 } 143 return nil, false 144 } 145 146 // ByIndex returns an entity from the list by index 147 // if requested chunk is within range of list, it returns chunk and true 148 // if requested chunk is out of the range, it returns nil and false 149 // boolean return value indicates whether requested chunk is within range 150 func (cl ChunkList) ByIndex(i uint64) (*Chunk, bool) { 151 if i >= uint64(len(cl)) { 152 // index out of range 153 return nil, false 154 } 155 return cl[i], true 156 } 157 158 // Len returns the number of Chunks in the list. It is also part of the sort 159 // interface that makes ChunkList sortable 160 func (cl ChunkList) Len() int { 161 return len(cl) 162 } 163 164 // BlockExecutionDataRoot represents the root of a serialized execution_data.BlockExecutionData. 165 // The hash of the serialized BlockExecutionDataRoot is the ExecutionDataID used within an 166 // flow.ExecutionResult. 167 // Context: 168 // - The trie updates in BlockExecutionDataRoot contain the _mutated_ registers only, which is 169 // helpful for clients to truslessly replicate the state. 170 // - In comparison, the chunk data packs contains all the register values at the chunk's starting 171 // state that were _touched_ (written and/or read). This is necessary for Verification Nodes to 172 // re-run the chunk the computation. 173 type BlockExecutionDataRoot struct { 174 // BlockID is the ID of the block, whose result this execution data is for. 175 BlockID Identifier 176 177 // ChunkExecutionDataIDs is a list of the root CIDs for each serialized execution_data.ChunkExecutionData 178 // associated with this block. 179 ChunkExecutionDataIDs []cid.Cid 180 }