github.com/koko1123/flow-go-1@v0.29.6/fvm/utils/view.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/koko1123/flow-go-1/fvm/state" 8 "github.com/koko1123/flow-go-1/ledger" 9 "github.com/koko1123/flow-go-1/model/flow" 10 ) 11 12 // SimpleView provides a simple view for testing and migration purposes. 13 type SimpleView struct { 14 Parent *SimpleView 15 Ledger *MapLedger 16 } 17 18 func NewSimpleView() *SimpleView { 19 return &SimpleView{ 20 Ledger: NewMapLedger(), 21 } 22 } 23 24 func NewSimpleViewFromPayloads(payloads []ledger.Payload) *SimpleView { 25 return &SimpleView{ 26 Ledger: NewMapLedgerFromPayloads(payloads), 27 } 28 } 29 30 func (v *SimpleView) NewChild() state.View { 31 ch := NewSimpleView() 32 ch.Parent = v 33 return ch 34 } 35 36 func (v *SimpleView) MergeView(o state.View) error { 37 var other *SimpleView 38 var ok bool 39 if other, ok = o.(*SimpleView); !ok { 40 return fmt.Errorf("can not merge: view type mismatch (given: %T, expected:SimpleView)", o) 41 } 42 43 for key, value := range other.Ledger.Registers { 44 err := v.Ledger.Set(key.Owner, key.Key, value) 45 if err != nil { 46 return fmt.Errorf("can not merge: %w", err) 47 } 48 } 49 50 for k := range other.Ledger.RegisterTouches { 51 v.Ledger.RegisterTouches[k] = struct{}{} 52 } 53 return nil 54 } 55 56 func (v *SimpleView) DropDelta() { 57 v.Ledger.Registers = make(map[flow.RegisterID]flow.RegisterValue) 58 } 59 60 func (v *SimpleView) Set(owner, key string, value flow.RegisterValue) error { 61 return v.Ledger.Set(owner, key, value) 62 } 63 64 func (v *SimpleView) Get(owner, key string) (flow.RegisterValue, error) { 65 value, err := v.Ledger.Get(owner, key) 66 if err != nil { 67 return nil, err 68 } 69 if len(value) > 0 { 70 return value, nil 71 } 72 73 if v.Parent != nil { 74 return v.Parent.Get(owner, key) 75 } 76 77 return nil, nil 78 } 79 80 // returns all the registers that has been touched 81 func (v *SimpleView) AllRegisters() []flow.RegisterID { 82 res := make([]flow.RegisterID, 0, len(v.Ledger.RegisterTouches)) 83 for k := range v.Ledger.RegisterTouches { 84 res = append(res, k) 85 } 86 return res 87 } 88 89 func (v *SimpleView) RegisterUpdates() ([]flow.RegisterID, []flow.RegisterValue) { 90 ids := make([]flow.RegisterID, 0, len(v.Ledger.RegisterUpdated)) 91 values := make([]flow.RegisterValue, 0, len(v.Ledger.RegisterUpdated)) 92 for key := range v.Ledger.RegisterUpdated { 93 ids = append(ids, key) 94 values = append(values, v.Ledger.Registers[key]) 95 } 96 return ids, values 97 } 98 99 func (v *SimpleView) Touch(owner, key string) error { 100 return v.Ledger.Touch(owner, key) 101 } 102 103 func (v *SimpleView) Delete(owner, key string) error { 104 return v.Ledger.Delete(owner, key) 105 } 106 107 func (v *SimpleView) Payloads() []ledger.Payload { 108 return v.Ledger.Payloads() 109 } 110 111 // A MapLedger is a naive ledger storage implementation backed by a simple map. 112 // 113 // This implementation is designed for testing and migration purposes. 114 type MapLedger struct { 115 sync.RWMutex 116 Registers map[flow.RegisterID]flow.RegisterValue 117 RegisterTouches map[flow.RegisterID]struct{} 118 RegisterUpdated map[flow.RegisterID]struct{} 119 } 120 121 // NewMapLedger returns an instance of map ledger (should only be used for 122 // testing and migration) 123 func NewMapLedger() *MapLedger { 124 return &MapLedger{ 125 Registers: make(map[flow.RegisterID]flow.RegisterValue), 126 RegisterTouches: make(map[flow.RegisterID]struct{}), 127 RegisterUpdated: make(map[flow.RegisterID]struct{}), 128 } 129 } 130 131 // NewMapLedger returns an instance of map ledger with entries loaded from 132 // payloads (should only be used for testing and migration) 133 func NewMapLedgerFromPayloads(payloads []ledger.Payload) *MapLedger { 134 ledger := NewMapLedger() 135 for _, entry := range payloads { 136 key, err := entry.Key() 137 if err != nil { 138 panic(err) 139 } 140 141 id := flow.RegisterID{ 142 Owner: string(key.KeyParts[0].Value), 143 Key: string(key.KeyParts[1].Value), 144 } 145 146 ledger.Registers[id] = entry.Value() 147 } 148 149 return ledger 150 } 151 152 func (m *MapLedger) Set(owner, key string, value flow.RegisterValue) error { 153 m.Lock() 154 defer m.Unlock() 155 156 k := flow.RegisterID{Owner: owner, Key: key} 157 m.RegisterTouches[k] = struct{}{} 158 m.RegisterUpdated[k] = struct{}{} 159 m.Registers[k] = value 160 return nil 161 } 162 163 func (m *MapLedger) Get(owner, key string) (flow.RegisterValue, error) { 164 m.Lock() 165 defer m.Unlock() 166 167 k := flow.RegisterID{Owner: owner, Key: key} 168 m.RegisterTouches[k] = struct{}{} 169 return m.Registers[k], nil 170 } 171 172 func (m *MapLedger) Touch(owner, key string) error { 173 m.Lock() 174 defer m.Unlock() 175 176 m.RegisterTouches[flow.RegisterID{Owner: owner, Key: key}] = struct{}{} 177 return nil 178 } 179 180 func (m *MapLedger) Delete(owner, key string) error { 181 m.Lock() 182 defer m.Unlock() 183 184 delete(m.RegisterTouches, flow.RegisterID{Owner: owner, Key: key}) 185 return nil 186 } 187 188 func registerIdToLedgerKey(id flow.RegisterID) ledger.Key { 189 keyParts := []ledger.KeyPart{ 190 ledger.NewKeyPart(0, []byte(id.Owner)), 191 ledger.NewKeyPart(2, []byte(id.Key)), 192 } 193 194 return ledger.NewKey(keyParts) 195 } 196 197 func (m *MapLedger) Payloads() []ledger.Payload { 198 m.RLock() 199 defer m.RUnlock() 200 201 ret := make([]ledger.Payload, 0, len(m.Registers)) 202 for id, val := range m.Registers { 203 key := registerIdToLedgerKey(id) 204 ret = append(ret, *ledger.NewPayload(key, ledger.Value(val))) 205 } 206 207 return ret 208 }