github.com/onflow/flow-go@v0.33.17/fvm/evm/testutils/backend.go (about) 1 package testutils 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "math" 7 "testing" 8 9 "github.com/onflow/atree" 10 "github.com/onflow/cadence" 11 jsoncdc "github.com/onflow/cadence/encoding/json" 12 "github.com/onflow/cadence/runtime/common" 13 "github.com/stretchr/testify/require" 14 "golang.org/x/exp/maps" 15 16 "github.com/onflow/flow-go/fvm/environment" 17 "github.com/onflow/flow-go/fvm/meter" 18 "github.com/onflow/flow-go/model/flow" 19 ) 20 21 var TestFlowEVMRootAddress = flow.BytesToAddress([]byte("FlowEVM")) 22 var TestComputationLimit = uint(math.MaxUint64 - 1) 23 24 func RunWithTestFlowEVMRootAddress(t testing.TB, backend atree.Ledger, f func(flow.Address)) { 25 as := environment.NewAccountStatus() 26 err := backend.SetValue(TestFlowEVMRootAddress[:], []byte(flow.AccountStatusKey), as.ToBytes()) 27 require.NoError(t, err) 28 f(TestFlowEVMRootAddress) 29 } 30 31 func RunWithTestBackend(t testing.TB, f func(*TestBackend)) { 32 tb := &TestBackend{ 33 TestValueStore: GetSimpleValueStore(), 34 testEventEmitter: getSimpleEventEmitter(), 35 testMeter: getSimpleMeter(), 36 } 37 f(tb) 38 } 39 40 func ConvertToCadence(data []byte) []cadence.Value { 41 ret := make([]cadence.Value, len(data)) 42 for i, v := range data { 43 ret[i] = cadence.UInt8(v) 44 } 45 return ret 46 } 47 48 func fullKey(owner, key []byte) string { 49 return string(owner) + "~" + string(key) 50 } 51 52 func GetSimpleValueStore() *TestValueStore { 53 data := make(map[string][]byte) 54 allocator := make(map[string]uint64) 55 bytesRead := 0 56 bytesWritten := 0 57 return &TestValueStore{ 58 GetValueFunc: func(owner, key []byte) ([]byte, error) { 59 fk := fullKey(owner, key) 60 value := data[fk] 61 bytesRead += len(fk) + len(value) 62 return value, nil 63 }, 64 SetValueFunc: func(owner, key, value []byte) error { 65 fk := fullKey(owner, key) 66 data[fk] = value 67 bytesWritten += len(fk) + len(value) 68 return nil 69 }, 70 ValueExistsFunc: func(owner, key []byte) (bool, error) { 71 fk := fullKey(owner, key) 72 value := data[fk] 73 bytesRead += len(fk) + len(value) 74 return len(value) > 0, nil 75 }, 76 AllocateStorageIndexFunc: func(owner []byte) (atree.StorageIndex, error) { 77 index := allocator[string(owner)] 78 var data [8]byte 79 allocator[string(owner)] = index + 1 80 binary.BigEndian.PutUint64(data[:], index) 81 bytesRead += len(owner) + 8 82 bytesWritten += len(owner) + 8 83 return atree.StorageIndex(data), nil 84 }, 85 TotalStorageSizeFunc: func() int { 86 size := 0 87 for key, item := range data { 88 size += len(item) + len([]byte(key)) 89 } 90 for key := range allocator { 91 size += len(key) + 8 92 } 93 return size 94 }, 95 TotalBytesReadFunc: func() int { 96 return bytesRead 97 }, 98 TotalBytesWrittenFunc: func() int { 99 return bytesWritten 100 }, 101 TotalStorageItemsFunc: func() int { 102 return len(maps.Keys(data)) + len(maps.Keys(allocator)) 103 }, 104 ResetStatsFunc: func() { 105 bytesRead = 0 106 bytesWritten = 0 107 }, 108 } 109 } 110 111 func getSimpleEventEmitter() *testEventEmitter { 112 events := make(flow.EventsList, 0) 113 return &testEventEmitter{ 114 emitEvent: func(event cadence.Event) error { 115 payload, err := jsoncdc.Encode(event) 116 if err != nil { 117 return err 118 } 119 120 events = append(events, flow.Event{Type: flow.EventType(event.EventType.QualifiedIdentifier), Payload: payload}) 121 return nil 122 }, 123 events: func() flow.EventsList { 124 return events 125 }, 126 reset: func() { 127 events = make(flow.EventsList, 0) 128 }, 129 } 130 } 131 132 func getSimpleMeter() *testMeter { 133 computationLimit := TestComputationLimit 134 compUsed := uint(0) 135 return &testMeter{ 136 meterComputation: func(kind common.ComputationKind, intensity uint) error { 137 compUsed += intensity 138 if compUsed > computationLimit { 139 return fmt.Errorf("computation limit has hit %d", computationLimit) 140 } 141 return nil 142 }, 143 hasComputationCapacity: func(kind common.ComputationKind, intensity uint) bool { 144 return compUsed+intensity < computationLimit 145 }, 146 computationUsed: func() (uint64, error) { 147 return uint64(compUsed), nil 148 }, 149 } 150 } 151 152 type TestBackend struct { 153 *TestValueStore 154 *testMeter 155 *testEventEmitter 156 } 157 158 func (tb *TestBackend) TotalStorageSize() int { 159 if tb.TotalStorageSizeFunc == nil { 160 panic("method not set") 161 } 162 return tb.TotalStorageSizeFunc() 163 } 164 165 func (tb *TestBackend) DropEvents() { 166 if tb.reset == nil { 167 panic("method not set") 168 } 169 tb.reset() 170 } 171 172 type TestValueStore struct { 173 GetValueFunc func(owner, key []byte) ([]byte, error) 174 SetValueFunc func(owner, key, value []byte) error 175 ValueExistsFunc func(owner, key []byte) (bool, error) 176 AllocateStorageIndexFunc func(owner []byte) (atree.StorageIndex, error) 177 TotalStorageSizeFunc func() int 178 TotalBytesReadFunc func() int 179 TotalBytesWrittenFunc func() int 180 TotalStorageItemsFunc func() int 181 ResetStatsFunc func() 182 } 183 184 var _ environment.ValueStore = &TestValueStore{} 185 186 func (vs *TestValueStore) GetValue(owner, key []byte) ([]byte, error) { 187 if vs.GetValueFunc == nil { 188 panic("method not set") 189 } 190 return vs.GetValueFunc(owner, key) 191 } 192 193 func (vs *TestValueStore) SetValue(owner, key, value []byte) error { 194 if vs.SetValueFunc == nil { 195 panic("method not set") 196 } 197 return vs.SetValueFunc(owner, key, value) 198 } 199 200 func (vs *TestValueStore) ValueExists(owner, key []byte) (bool, error) { 201 if vs.ValueExistsFunc == nil { 202 panic("method not set") 203 } 204 return vs.ValueExistsFunc(owner, key) 205 } 206 207 func (vs *TestValueStore) AllocateStorageIndex(owner []byte) (atree.StorageIndex, error) { 208 if vs.AllocateStorageIndexFunc == nil { 209 panic("method not set") 210 } 211 return vs.AllocateStorageIndexFunc(owner) 212 } 213 214 func (vs *TestValueStore) TotalBytesRead() int { 215 if vs.TotalBytesReadFunc == nil { 216 panic("method not set") 217 } 218 return vs.TotalBytesReadFunc() 219 } 220 221 func (vs *TestValueStore) TotalBytesWritten() int { 222 if vs.TotalBytesWrittenFunc == nil { 223 panic("method not set") 224 } 225 return vs.TotalBytesWrittenFunc() 226 } 227 228 func (vs *TestValueStore) TotalStorageSize() int { 229 if vs.TotalStorageSizeFunc == nil { 230 panic("method not set") 231 } 232 return vs.TotalStorageSizeFunc() 233 } 234 235 func (vs *TestValueStore) TotalStorageItems() int { 236 if vs.TotalStorageItemsFunc == nil { 237 panic("method not set") 238 } 239 return vs.TotalStorageItemsFunc() 240 } 241 242 func (vs *TestValueStore) ResetStats() { 243 if vs.ResetStatsFunc == nil { 244 panic("method not set") 245 } 246 vs.ResetStatsFunc() 247 } 248 249 type testMeter struct { 250 meterComputation func(common.ComputationKind, uint) error 251 hasComputationCapacity func(common.ComputationKind, uint) bool 252 computationUsed func() (uint64, error) 253 computationIntensities func() meter.MeteredComputationIntensities 254 255 meterMemory func(usage common.MemoryUsage) error 256 memoryUsed func() (uint64, error) 257 258 meterEmittedEvent func(byteSize uint64) error 259 totalEmittedEventBytes func() uint64 260 261 interactionUsed func() (uint64, error) 262 } 263 264 var _ environment.Meter = &testMeter{} 265 266 func (m *testMeter) MeterComputation( 267 kind common.ComputationKind, 268 intensity uint, 269 ) error { 270 if m.meterComputation == nil { 271 panic("method not set") 272 } 273 return m.meterComputation(kind, intensity) 274 } 275 276 func (m *testMeter) ComputationAvailable( 277 kind common.ComputationKind, 278 intensity uint, 279 ) bool { 280 if m.hasComputationCapacity == nil { 281 panic("method not set") 282 } 283 return m.hasComputationCapacity(kind, intensity) 284 } 285 286 func (m *testMeter) ComputationIntensities() meter.MeteredComputationIntensities { 287 if m.computationIntensities == nil { 288 panic("method not set") 289 } 290 return m.computationIntensities() 291 } 292 293 func (m *testMeter) ComputationUsed() (uint64, error) { 294 if m.computationUsed == nil { 295 panic("method not set") 296 } 297 return m.computationUsed() 298 } 299 300 func (m *testMeter) MeterMemory(usage common.MemoryUsage) error { 301 if m.meterMemory == nil { 302 panic("method not set") 303 } 304 return m.meterMemory(usage) 305 } 306 307 func (m *testMeter) MemoryUsed() (uint64, error) { 308 if m.memoryUsed == nil { 309 panic("method not set") 310 } 311 return m.memoryUsed() 312 } 313 314 func (m *testMeter) InteractionUsed() (uint64, error) { 315 if m.interactionUsed == nil { 316 panic("method not set") 317 } 318 return m.interactionUsed() 319 } 320 321 func (m *testMeter) MeterEmittedEvent(byteSize uint64) error { 322 if m.meterEmittedEvent == nil { 323 panic("method not set") 324 } 325 return m.meterEmittedEvent(byteSize) 326 } 327 328 func (m *testMeter) TotalEmittedEventBytes() uint64 { 329 if m.totalEmittedEventBytes == nil { 330 panic("method not set") 331 } 332 return m.totalEmittedEventBytes() 333 } 334 335 type testEventEmitter struct { 336 emitEvent func(event cadence.Event) error 337 events func() flow.EventsList 338 serviceEvents func() flow.EventsList 339 convertedServiceEvents func() flow.ServiceEventList 340 reset func() 341 } 342 343 var _ environment.EventEmitter = &testEventEmitter{} 344 345 func (vs *testEventEmitter) EmitEvent(event cadence.Event) error { 346 if vs.emitEvent == nil { 347 panic("method not set") 348 } 349 return vs.emitEvent(event) 350 } 351 352 func (vs *testEventEmitter) Events() flow.EventsList { 353 if vs.events == nil { 354 panic("method not set") 355 } 356 return vs.events() 357 } 358 359 func (vs *testEventEmitter) ServiceEvents() flow.EventsList { 360 if vs.serviceEvents == nil { 361 panic("method not set") 362 } 363 return vs.serviceEvents() 364 } 365 366 func (vs *testEventEmitter) ConvertedServiceEvents() flow.ServiceEventList { 367 if vs.convertedServiceEvents == nil { 368 panic("method not set") 369 } 370 return vs.convertedServiceEvents() 371 } 372 373 func (vs *testEventEmitter) Reset() { 374 if vs.reset == nil { 375 panic("method not set") 376 } 377 vs.reset() 378 }