|
4 | 4 | "bytes" |
5 | 5 | "encoding/binary" |
6 | 6 | "fmt" |
7 | | - "math" |
8 | 7 | "math/big" |
9 | 8 | "testing" |
10 | 9 |
|
@@ -1915,6 +1914,134 @@ func TestCadenceOwnedAccountFunctionalities(t *testing.T) { |
1915 | 1914 | assert.Len(t, state.UpdatedRegisterIDs(), 0) |
1916 | 1915 | }) |
1917 | 1916 | }) |
| 1917 | + |
| 1918 | + t.Run("test coa deploy with max gas limit cap", func(t *testing.T) { |
| 1919 | + RunWithNewEnvironment(t, |
| 1920 | + chain, func( |
| 1921 | + ctx fvm.Context, |
| 1922 | + vm fvm.VM, |
| 1923 | + snapshot snapshot.SnapshotTree, |
| 1924 | + testContract *TestContract, |
| 1925 | + testAccount *EOATestAccount, |
| 1926 | + ) { |
| 1927 | + code := []byte(fmt.Sprintf( |
| 1928 | + ` |
| 1929 | + import EVM from %s |
| 1930 | + import FlowToken from %s |
| 1931 | + access(all) |
| 1932 | + fun main(code: [UInt8]): EVM.Result { |
| 1933 | + let admin = getAuthAccount<auth(Storage) &Account>(%s) |
| 1934 | + .storage.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)! |
| 1935 | + let minter <- admin.createNewMinter(allowedAmount: 2.34) |
| 1936 | + let vault <- minter.mintTokens(amount: 2.34) |
| 1937 | + destroy minter |
| 1938 | + let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount() |
| 1939 | + cadenceOwnedAccount.deposit(from: <-vault) |
| 1940 | + let res = cadenceOwnedAccount.deploy( |
| 1941 | + code: code, |
| 1942 | + gasLimit: 16_777_216, |
| 1943 | + value: EVM.Balance(attoflow: 1230000000000000000) |
| 1944 | + ) |
| 1945 | + destroy cadenceOwnedAccount |
| 1946 | + return res |
| 1947 | + } |
| 1948 | + `, |
| 1949 | + sc.EVMContract.Address.HexWithPrefix(), |
| 1950 | + sc.FlowToken.Address.HexWithPrefix(), |
| 1951 | + sc.FlowServiceAccount.Address.HexWithPrefix(), |
| 1952 | + )) |
| 1953 | + |
| 1954 | + script := fvm.Script(code). |
| 1955 | + WithArguments(json.MustEncode( |
| 1956 | + cadence.NewArray( |
| 1957 | + unittest.BytesToCdcUInt8(testContract.ByteCode), |
| 1958 | + ).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type)), |
| 1959 | + )) |
| 1960 | + |
| 1961 | + _, output, err := vm.Run( |
| 1962 | + ctx, |
| 1963 | + script, |
| 1964 | + snapshot, |
| 1965 | + ) |
| 1966 | + require.NoError(t, err) |
| 1967 | + require.NoError(t, output.Err) |
| 1968 | + |
| 1969 | + res, err := impl.ResultSummaryFromEVMResultValue(output.Value) |
| 1970 | + require.NoError(t, err) |
| 1971 | + require.Equal(t, types.StatusSuccessful, res.Status) |
| 1972 | + require.Equal(t, types.ErrCodeNoError, res.ErrorCode) |
| 1973 | + require.Empty(t, res.ErrorMessage) |
| 1974 | + require.NotNil(t, res.DeployedContractAddress) |
| 1975 | + // we strip away first few bytes because they contain deploy code |
| 1976 | + require.Equal(t, testContract.ByteCode[17:], []byte(res.ReturnedData)) |
| 1977 | + }) |
| 1978 | + }) |
| 1979 | + |
| 1980 | + t.Run("test coa deploy with bigger than max gas limit cap", func(t *testing.T) { |
| 1981 | + RunWithNewEnvironment(t, |
| 1982 | + chain, func( |
| 1983 | + ctx fvm.Context, |
| 1984 | + vm fvm.VM, |
| 1985 | + snapshot snapshot.SnapshotTree, |
| 1986 | + testContract *TestContract, |
| 1987 | + testAccount *EOATestAccount, |
| 1988 | + ) { |
| 1989 | + code := []byte(fmt.Sprintf( |
| 1990 | + ` |
| 1991 | + import EVM from %s |
| 1992 | + import FlowToken from %s |
| 1993 | + access(all) |
| 1994 | + fun main(code: [UInt8]): EVM.Result { |
| 1995 | + let admin = getAuthAccount<auth(Storage) &Account>(%s) |
| 1996 | + .storage.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)! |
| 1997 | + let minter <- admin.createNewMinter(allowedAmount: 2.34) |
| 1998 | + let vault <- minter.mintTokens(amount: 2.34) |
| 1999 | + destroy minter |
| 2000 | + let cadenceOwnedAccount <- EVM.createCadenceOwnedAccount() |
| 2001 | + cadenceOwnedAccount.deposit(from: <-vault) |
| 2002 | + let res = cadenceOwnedAccount.deploy( |
| 2003 | + code: code, |
| 2004 | + gasLimit: 16_777_226, |
| 2005 | + value: EVM.Balance(attoflow: 1230000000000000000) |
| 2006 | + ) |
| 2007 | + destroy cadenceOwnedAccount |
| 2008 | + return res |
| 2009 | + } |
| 2010 | + `, |
| 2011 | + sc.EVMContract.Address.HexWithPrefix(), |
| 2012 | + sc.FlowToken.Address.HexWithPrefix(), |
| 2013 | + sc.FlowServiceAccount.Address.HexWithPrefix(), |
| 2014 | + )) |
| 2015 | + |
| 2016 | + script := fvm.Script(code). |
| 2017 | + WithArguments(json.MustEncode( |
| 2018 | + cadence.NewArray( |
| 2019 | + unittest.BytesToCdcUInt8(testContract.ByteCode), |
| 2020 | + ).WithType(cadence.NewVariableSizedArrayType(cadence.UInt8Type)), |
| 2021 | + )) |
| 2022 | + |
| 2023 | + _, output, err := vm.Run( |
| 2024 | + ctx, |
| 2025 | + script, |
| 2026 | + snapshot, |
| 2027 | + ) |
| 2028 | + require.NoError(t, err) |
| 2029 | + require.NoError(t, output.Err) |
| 2030 | + |
| 2031 | + res, err := impl.ResultSummaryFromEVMResultValue(output.Value) |
| 2032 | + require.NoError(t, err) |
| 2033 | + require.Equal(t, types.StatusInvalid, res.Status) |
| 2034 | + require.Equal(t, types.ValidationErrCodeMisc, res.ErrorCode) |
| 2035 | + require.Equal( |
| 2036 | + t, |
| 2037 | + "transaction gas limit too high (cap: 16777216, tx: 16777226)", |
| 2038 | + res.ErrorMessage, |
| 2039 | + ) |
| 2040 | + require.Nil(t, res.DeployedContractAddress) |
| 2041 | + // we strip away first few bytes because they contain deploy code |
| 2042 | + require.Empty(t, []byte(res.ReturnedData)) |
| 2043 | + }) |
| 2044 | + }) |
1918 | 2045 | } |
1919 | 2046 |
|
1920 | 2047 | func TestDryRun(t *testing.T) { |
@@ -1977,7 +2104,8 @@ func TestDryRun(t *testing.T) { |
1977 | 2104 | ) { |
1978 | 2105 | data := testContract.MakeCallData(t, "store", big.NewInt(1337)) |
1979 | 2106 |
|
1980 | | - limit := uint64(math.MaxUint64 - 1) |
| 2107 | + // EVM.dryRun must not be limited by the `gethParams.MaxTxGas` |
| 2108 | + limit := gethParams.MaxTxGas + 1_000 |
1981 | 2109 | tx := gethTypes.NewTransaction( |
1982 | 2110 | 0, |
1983 | 2111 | testContract.DeployedAt.ToCommon(), |
@@ -2572,6 +2700,22 @@ func TestDryCall(t *testing.T) { |
2572 | 2700 | require.Equal(t, types.ExecutionErrCodeOutOfGas, result.ErrorCode) |
2573 | 2701 | require.Equal(t, types.StatusFailed, result.Status) |
2574 | 2702 | require.Equal(t, result.GasConsumed, limit) |
| 2703 | + |
| 2704 | + // EVM.dryCall must not be limited to `gethParams.MaxTxGas` |
| 2705 | + limit = gethParams.MaxTxGas + 1_000 |
| 2706 | + tx = gethTypes.NewTransaction( |
| 2707 | + 0, |
| 2708 | + testContract.DeployedAt.ToCommon(), |
| 2709 | + big.NewInt(0), |
| 2710 | + limit, |
| 2711 | + big.NewInt(0), |
| 2712 | + data, |
| 2713 | + ) |
| 2714 | + result, _ = dryCall(t, tx, ctx, vm, snapshot) |
| 2715 | + require.Equal(t, types.ErrCodeNoError, result.ErrorCode) |
| 2716 | + require.Equal(t, types.StatusSuccessful, result.Status) |
| 2717 | + require.Greater(t, result.GasConsumed, uint64(0)) |
| 2718 | + require.Less(t, result.GasConsumed, limit) |
2575 | 2719 | }) |
2576 | 2720 | }) |
2577 | 2721 |
|
|
0 commit comments