diff --git a/cmd/emulator/start/start.go b/cmd/emulator/start/start.go index a119dcaa..d14d7dc0 100644 --- a/cmd/emulator/start/start.go +++ b/cmd/emulator/start/start.go @@ -200,6 +200,7 @@ func Cmd(getServiceKey serviceKeyFunc) *cobra.Command { ContractRemovalEnabled: conf.ContractRemovalEnabled, SqliteURL: conf.SqliteURL, CoverageReportingEnabled: conf.CoverageReportingEnabled, + EVMEnabled: conf.EVMEnabled, // todo temporarily disabled until remote register endpoint is re-enabled // StartBlockHeight: conf.StartBlockHeight, } diff --git a/emulator/blockchain.go b/emulator/blockchain.go index e4142837..620da9b0 100644 --- a/emulator/blockchain.go +++ b/emulator/blockchain.go @@ -39,19 +39,18 @@ import ( "sync" "time" - "github.com/onflow/flow-core-contracts/lib/go/templates" - "github.com/onflow/flow-go/engine" - "github.com/logrusorgru/aurora" "github.com/onflow/cadence" "github.com/onflow/cadence/runtime" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/flow-core-contracts/lib/go/templates" flowsdk "github.com/onflow/flow-go-sdk" sdkcrypto "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flow-go/access" "github.com/onflow/flow-go/crypto" "github.com/onflow/flow-go/crypto/hash" + "github.com/onflow/flow-go/engine" "github.com/onflow/flow-go/fvm" fvmcrypto "github.com/onflow/flow-go/fvm/crypto" "github.com/onflow/flow-go/fvm/environment" @@ -621,6 +620,11 @@ func configureFVM(blockchain *Blockchain, conf config, blocks *blocks) (*fvm.Vir fvm.WithSequenceNumberCheckAndIncrementEnabled(false)) } + // todo temporary fix because the EVM storage account doesn't have sufficient funds + if conf.EVMEnabled { + fvmOptions = append(fvmOptions, fvm.WithAccountStorageLimit(false)) + } + ctx := fvm.NewContext( fvmOptions..., ) diff --git a/emulator/script_test.go b/emulator/script_test.go index e7189a5a..273a46b5 100644 --- a/emulator/script_test.go +++ b/emulator/script_test.go @@ -23,18 +23,18 @@ import ( "fmt" "testing" - "github.com/onflow/flow-emulator/adapters" - "github.com/onflow/flow-emulator/emulator" - "github.com/rs/zerolog" - "github.com/onflow/cadence" jsoncdc "github.com/onflow/cadence/encoding/json" flowsdk "github.com/onflow/flow-go-sdk" fvmerrors "github.com/onflow/flow-go/fvm/errors" "github.com/onflow/flow-go/fvm/evm/stdlib" flowgo "github.com/onflow/flow-go/model/flow" + "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/onflow/flow-emulator/adapters" + "github.com/onflow/flow-emulator/emulator" ) func TestExecuteScript(t *testing.T) { @@ -269,17 +269,17 @@ func TestScriptWithCadenceRandom(t *testing.T) { // TestEVM checks evm functionality func TestEVM(t *testing.T) { - + serviceAddr := flowgo.Emulator.Chain().ServiceAddress() code := []byte(fmt.Sprintf( ` - import EVM from %s + import EVM from 0x%s access(all) fun main(bytes: [UInt8; 20]) { - EVM.EVMAddress(bytes: bytes) + log(EVM.EVMAddress(bytes: bytes)) } `, - flowgo.Emulator.Chain().ServiceAddress().HexWithPrefix(), + serviceAddr, )) gasLimit := uint64(100_000) @@ -303,8 +303,10 @@ func TestEVM(t *testing.T) { cadence.UInt8(10), cadence.UInt8(10), }).WithType(stdlib.EVMAddressBytesCadenceType) - result, err := b.ExecuteScript([]byte(code), [][]byte{jsoncdc.MustEncode(addressBytesArray)}) + result, err := b.ExecuteScript(code, [][]byte{jsoncdc.MustEncode(addressBytesArray)}) require.NoError(t, err) require.NoError(t, result.Error) + require.Len(t, result.Logs, 1) + require.Equal(t, result.Logs[0], fmt.Sprintf("A.%s.EVM.EVMAddress(bytes: %s)", serviceAddr, addressBytesArray.String())) } diff --git a/emulator/transaction_test.go b/emulator/transaction_test.go index f641e4a1..5a13f86a 100644 --- a/emulator/transaction_test.go +++ b/emulator/transaction_test.go @@ -29,25 +29,24 @@ import ( "strings" "testing" - "github.com/onflow/flow-emulator/adapters" - "github.com/onflow/flow-emulator/convert" - "github.com/onflow/flow-emulator/emulator" - "github.com/onflow/flow-go-sdk" - - "github.com/rs/zerolog" - "github.com/onflow/cadence" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/flow-go-sdk" flowsdk "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flow-go-sdk/templates" "github.com/onflow/flow-go-sdk/test" fvmerrors "github.com/onflow/flow-go/fvm/errors" + "github.com/onflow/flow-go/fvm/evm/stdlib" flowgo "github.com/onflow/flow-go/model/flow" + "github.com/rs/zerolog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/flow-emulator/adapters" + "github.com/onflow/flow-emulator/convert" + "github.com/onflow/flow-emulator/emulator" "github.com/onflow/flow-emulator/types" ) @@ -2151,3 +2150,54 @@ func TestTransactionWithCadenceRandom(t *testing.T) { _, err = b.CommitBlock() assert.NoError(t, err) } + +func TestEVMTransaction(t *testing.T) { + serviceAddr := flowgo.Emulator.Chain().ServiceAddress() + code := []byte(fmt.Sprintf( + ` + import EVM from %s + + transaction(bytes: [UInt8; 20]) { + execute { + let addr = EVM.EVMAddress(bytes: bytes) + log(addr) + } + } + `, + serviceAddr.HexWithPrefix(), + )) + + b, adapter := setupTransactionTests(t, emulator.WithEVMEnabled(true)) + + // generate random address + genArr := make([]cadence.Value, 20) + for i := range genArr { + genArr[i] = cadence.UInt8(i) + } + addressBytesArray := cadence.NewArray(genArr).WithType(stdlib.EVMAddressBytesCadenceType) + + tx := flowsdk.NewTransaction(). + SetScript(code). + SetGasLimit(flowgo.DefaultMaxTransactionGasLimit). + SetProposalKey(b.ServiceKey().Address, b.ServiceKey().Index, b.ServiceKey().SequenceNumber). + SetPayer(b.ServiceKey().Address) + + err := tx.AddArgument(addressBytesArray) + assert.NoError(t, err) + + signer, err := b.ServiceKey().Signer() + require.NoError(t, err) + + err = tx.SignEnvelope(b.ServiceKey().Address, b.ServiceKey().Index, signer) + require.NoError(t, err) + + err = adapter.SendTransaction(context.Background(), *tx) + assert.NoError(t, err) + + result, err := b.ExecuteNextTransaction() + require.NoError(t, err) + AssertTransactionSucceeded(t, result) + + require.Len(t, result.Logs, 1) + require.Equal(t, result.Logs[0], fmt.Sprintf("A.%s.EVM.EVMAddress(bytes: %s)", serviceAddr, addressBytesArray.String())) +}