github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/storage/state/storage_state.go (about) 1 package state 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/flow-go/fvm/storage/snapshot" 7 "github.com/onflow/flow-go/model/flow" 8 ) 9 10 type storageState struct { 11 baseStorage snapshot.StorageSnapshot 12 13 // The read set only include reads from the baseStorage 14 readSet map[flow.RegisterID]struct{} 15 16 writeSet map[flow.RegisterID]flow.RegisterValue 17 } 18 19 func newStorageState(base snapshot.StorageSnapshot) *storageState { 20 return &storageState{ 21 baseStorage: base, 22 readSet: map[flow.RegisterID]struct{}{}, 23 writeSet: map[flow.RegisterID]flow.RegisterValue{}, 24 } 25 } 26 27 func (state *storageState) NewChild() *storageState { 28 return newStorageState(snapshot.NewPeekerStorageSnapshot(state)) 29 } 30 31 func (state *storageState) Finalize() *snapshot.ExecutionSnapshot { 32 return &snapshot.ExecutionSnapshot{ 33 ReadSet: state.readSet, 34 WriteSet: state.writeSet, 35 } 36 } 37 38 func (state *storageState) Merge(snapshot *snapshot.ExecutionSnapshot) error { 39 for id := range snapshot.ReadSet { 40 _, ok := state.writeSet[id] 41 if ok { 42 continue 43 } 44 state.readSet[id] = struct{}{} 45 } 46 47 for id, value := range snapshot.WriteSet { 48 state.writeSet[id] = value 49 } 50 51 return nil 52 } 53 54 func (state *storageState) Set( 55 id flow.RegisterID, 56 value flow.RegisterValue, 57 ) error { 58 state.writeSet[id] = value 59 return nil 60 } 61 62 func (state *storageState) get( 63 id flow.RegisterID, 64 ) ( 65 bool, // read from base storage 66 flow.RegisterValue, 67 error, 68 ) { 69 value, ok := state.writeSet[id] 70 if ok { 71 return false, value, nil 72 } 73 74 if state.baseStorage == nil { 75 return true, nil, nil 76 } 77 78 value, err := state.baseStorage.Get(id) 79 if err != nil { 80 return true, nil, fmt.Errorf("get register failed: %w", err) 81 } 82 83 return true, value, nil 84 } 85 86 func (state *storageState) Get( 87 id flow.RegisterID, 88 ) ( 89 flow.RegisterValue, 90 error, 91 ) { 92 readFromBaseStorage, value, err := state.get(id) 93 if err != nil { 94 return nil, err 95 } 96 97 if readFromBaseStorage { 98 state.readSet[id] = struct{}{} 99 } 100 101 return value, nil 102 } 103 104 func (state *storageState) Peek( 105 id flow.RegisterID, 106 ) ( 107 flow.RegisterValue, 108 error, 109 ) { 110 _, value, err := state.get(id) 111 return value, err 112 } 113 114 func (state *storageState) DropChanges() error { 115 state.writeSet = map[flow.RegisterID]flow.RegisterValue{} 116 return nil 117 } 118 119 func (state *storageState) readSetSize() int { 120 return len(state.readSet) 121 } 122 123 func (state *storageState) interimReadSet( 124 accumulator map[flow.RegisterID]struct{}, 125 ) { 126 for id := range state.writeSet { 127 delete(accumulator, id) 128 } 129 130 for id := range state.readSet { 131 accumulator[id] = struct{}{} 132 } 133 }