From 95d5b8c9b58c9867563b1093d9155d3dae0d95e7 Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Wed, 10 Apr 2024 16:01:38 +0300 Subject: [PATCH 1/2] Properly setup EVM environment to allow the usage of EVM types in test scripts --- test/test_framework_test.go | 35 +++++++++++++++++++++++++++++++++++ test/test_runner.go | 30 +++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/test/test_framework_test.go b/test/test_framework_test.go index c2e34ffc..d5d782d0 100644 --- a/test/test_framework_test.go +++ b/test/test_framework_test.go @@ -22,7 +22,9 @@ import ( "bytes" "errors" "fmt" + "os" "testing" + "time" "github.com/rs/zerolog" "github.com/stretchr/testify/assert" @@ -5932,3 +5934,36 @@ func TestGetTests(t *testing.T) { assert.ElementsMatch(t, []string{"test1", "test2", "test3"}, tests) } + +func TestEVMContract(t *testing.T) { + t.Parallel() + + const testCode = ` + import Test + import "EVM" + + access(all) + fun testCOACreation() { + let coa <- EVM.createCadenceOwnedAccount() + Test.assertEqual(UInt(0), coa.address().balance().inAttoFLOW()) + + destroy <- coa + } + ` + + importResolver := func(location common.Location) (string, error) { + return "", fmt.Errorf("cannot find import location: %s", location) + } + + output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: time.RFC3339} + log := zerolog.New(output).With().Timestamp().Logger() + runner := NewTestRunner(). + WithImportResolver(importResolver). + WithLogger(log) + + results, err := runner.RunTests(testCode) + require.NoError(t, err) + for _, result := range results { + require.NoError(t, result.Error) + } +} diff --git a/test/test_runner.go b/test/test_runner.go index 77255437..5e84bde7 100644 --- a/test/test_runner.go +++ b/test/test_runner.go @@ -27,6 +27,9 @@ import ( "github.com/rs/zerolog" "github.com/onflow/atree" + "github.com/onflow/flow-go/fvm/environment" + "github.com/onflow/flow-go/fvm/evm" + "github.com/onflow/flow-go/fvm/systemcontracts" "github.com/onflow/flow-go/model/flow" "github.com/onflow/cadence/runtime" @@ -474,8 +477,9 @@ func (r *TestRunner) initializeEnvironment() ( backend.contracts = r.contracts r.backend = backend + fvmEnv := r.backend.blockchain.NewScriptEnvironment() ctx := runtime.Context{ - Interface: r.backend.blockchain.NewScriptEnvironment(), + Interface: fvmEnv, Location: testScriptLocation, Environment: env, } @@ -506,6 +510,11 @@ func (r *TestRunner) initializeEnvironment() ( r.coverageReport, ) + err := setupEVMEnvironment(fvmEnv, env) + if err != nil { + panic(err) + } + return env, ctx } @@ -786,6 +795,11 @@ func (r *TestRunner) parseAndCheckImport( env.CheckerConfig.ContractValueHandler = contractValueHandler + err = setupEVMEnvironment(r.backend.blockchain.NewScriptEnvironment(), env) + if err != nil { + panic(err) + } + code = r.replaceImports(code) program, err := r.testRuntime.ParseAndCheckProgram([]byte(code), ctx) @@ -796,6 +810,20 @@ func (r *TestRunner) parseAndCheckImport( return program.Program, program.Elaboration, nil } +func setupEVMEnvironment( + fvmEnv environment.Environment, + runtimeEnv runtime.Environment, +) error { + sc := systemcontracts.SystemContractsForChain(chain.ChainID()) + return evm.SetupEnvironment( + chain.ChainID(), + fvmEnv, + runtimeEnv, + chain.ServiceAddress(), + sc.FlowToken.Address, + ) +} + func baseContracts() map[string]common.Address { contracts := make(map[string]common.Address, 0) serviceAddress := common.Address(chain.ServiceAddress()) From e0f8a9b1ce76ee8b403e03403c8eaab36494916e Mon Sep 17 00:00:00 2001 From: Ardit Marku Date: Tue, 16 Apr 2024 09:47:28 +0300 Subject: [PATCH 2/2] Re-use environment from runtime.Context argument --- test/test_runner.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test_runner.go b/test/test_runner.go index 5e84bde7..a3a0e977 100644 --- a/test/test_runner.go +++ b/test/test_runner.go @@ -795,7 +795,11 @@ func (r *TestRunner) parseAndCheckImport( env.CheckerConfig.ContractValueHandler = contractValueHandler - err = setupEVMEnvironment(r.backend.blockchain.NewScriptEnvironment(), env) + fvmEnv, ok := startCtx.Interface.(environment.Environment) + if !ok { + panic(fmt.Errorf("failed to retrieve FVM Environment")) + } + err = setupEVMEnvironment(fvmEnv, env) if err != nil { panic(err) }