Skip to content

Commit

Permalink
test(evm): evmante validate basic full coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
onikonychev committed Jun 10, 2024
2 parents 032c6ae + 42a8b65 commit c631d4e
Show file tree
Hide file tree
Showing 34 changed files with 1,877 additions and 3,965 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/e2e-evm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:
"**go.mod",
"**go.sum",
"contrib/docker/*",
"**.ts",
"**.js",
"**.json",
]
Expand Down Expand Up @@ -66,17 +67,17 @@ jobs:
with:
node-version: 18

- name: NPM Install
run: npm install
- name: "just install"
run: just install
working-directory: "e2e/evm"

- name: "Launch localnet"
run: |
just localnet --no-build &
sleep 6
- name: Run tests
run: npm test
- name: "Run tests (just test)"
run: just test
working-directory: "e2e/evm"
env:
JSON_RPC_ENDPOINT: http://127.0.0.1:8545
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ ui-debug.log
/public/
.env
firebase-debug.log
**/bun.lockb
out-*
exit-status-*
.DS_Store
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1909](https://github.com/NibiruChain/nibiru/pull/1909) - chore(evm): set is_london true by default and removed from config
- [#1911](https://github.com/NibiruChain/nibiru/pull/1911) - chore(evm): simplified config by removing old eth forks
- [#1912](https://github.com/NibiruChain/nibiru/pull/1912) - test(evm): unit tests for evm_ante_sigverify
- [#1914](https://github.com/NibiruChain/nibiru/pull/1914) - refactor(evm): Remove dead code and document non-EVM ante handler
- [#1914](https://github.com/NibiruChain/nibiru/pull/1914) - refactor(evm): Remove dead code and document non-EVM ante handler- [#1917](https://github.com/NibiruChain/nibiru/pull/1917) - test(e2e-evm): TypeScript support. Type generation from compiled contracts. Formatter for TS code.
- [#1917](https://github.com/NibiruChain/nibiru/pull/1917) - test(e2e-evm): TypeScript support. Type generation from compiled contracts. Formatter for TS code.

#### Dapp modules: perp, spot, oracle, etc

Expand Down
2 changes: 1 addition & 1 deletion app/evmante_gas_wanted_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (s *TestSuite) TestGasWantedDecorator() {
s.Run(tc.name, func() {
deps := evmtest.NewTestDeps()
stateDB := deps.StateDB()
anteDec := app.NewGasWantedDecorator(deps.Chain.AppKeepers)
anteDec := app.AnteDecoratorGasWanted{}

tx := tc.txSetup(&deps)
s.Require().NoError(stateDB.Commit())
Expand Down
221 changes: 210 additions & 11 deletions app/evmante_validate_basic_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
package app_test

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"math/big"

"github.com/NibiruChain/nibiru/app"
"github.com/NibiruChain/nibiru/eth"
"github.com/NibiruChain/nibiru/x/common/testutil"
"github.com/NibiruChain/nibiru/x/evm"
"github.com/NibiruChain/nibiru/x/evm/evmtest"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/ethereum/go-ethereum/common"
)

func (s *TestSuite) TestEthValidateBasicDecorator() {
testCases := []struct {
name string
ctxSetup func(deps *evmtest.TestDeps)
txSetup func(deps *evmtest.TestDeps) sdk.Tx
wantErr string
name string
ctxSetup func(deps *evmtest.TestDeps)
txSetup func(deps *evmtest.TestDeps) sdk.Tx
paramsSetup func(deps *evmtest.TestDeps) evm.Params
wantErr string
}{
{
name: "sad: unsigned уер tx should fail chain id validation",
name: "happy: properly built eth tx",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
return happyCreateContractTx(deps)
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "invalid chain-id",
wantErr: "",
},
{
name: "happy: ctx recheck should ignore validation",
Expand All @@ -32,6 +44,13 @@ func (s *TestSuite) TestEthValidateBasicDecorator() {
},
wantErr: "",
},
{
name: "sad: fail chain id basic validation",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
return happyCreateContractTx(deps)
},
wantErr: "invalid chain-id",
},
{
name: "sad: tx not implementing protoTxProvider",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
Expand All @@ -45,14 +64,153 @@ func (s *TestSuite) TestEthValidateBasicDecorator() {
wantErr: "didn't implement interface protoTxProvider",
},
{
name: "happy: signed ethereum tx should pass validation",
name: "sad: eth tx with memo should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
txBuilder.SetMemo("memo")
tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "",
wantErr: "invalid request",
},
{
name: "sad: eth tx with fee payer should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
txBuilder.SetFeePayer(testutil.AccAddress())
tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "invalid request",
},
{
name: "sad: eth tx with fee granter should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
txBuilder.SetFeeGranter(testutil.AccAddress())
tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "invalid request",
},
{
name: "sad: eth tx with signatures should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
sigV2 := signing.SignatureV2{
PubKey: deps.Sender.PrivKey.PubKey(),
Data: &signing.SingleSignatureData{
SignMode: deps.EncCfg.TxConfig.SignModeHandler().DefaultMode(),
Signature: nil,
},
Sequence: 0,
}
err := txBuilder.SetSignatures(sigV2)
s.Require().NoError(err)
txMsg := happyCreateContractTx(deps)

gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx))
keyringSigner := deps.Sender.KeyringSigner
err = txMsg.Sign(gethSigner, keyringSigner)

Check failure on line 117 in app/evmante_validate_basic_test.go

View workflow job for this annotation

GitHub Actions / lint

ineffectual assignment to err (ineffassign)

tx, err := txMsg.BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "tx AuthInfo SignerInfos should be empty",
},
{
name: "sad: tx for contract creation with param disabled",
paramsSetup: func(deps *evmtest.TestDeps) evm.Params {
params := evm.DefaultParams()
params.EnableCreate = false
return params
},
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
txBuilder := deps.EncCfg.TxConfig.NewTxBuilder()
tx, err := happyCreateContractTx(deps).BuildTx(txBuilder, eth.EthBaseDenom)
s.Require().NoError(err)
return tx
},
wantErr: "EVM Create operation is disabled",
},
{
name: "sad: tx for contract call with param disabled",
paramsSetup: func(deps *evmtest.TestDeps) evm.Params {
params := evm.DefaultParams()
params.EnableCall = false
return params
},
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
chainID := deps.Chain.EvmKeeper.EthChainID(deps.Ctx)
gasLimit := uint64(10)
to := evmtest.NewEthAccInfo().EthAddr
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit)))
msg := buildEthMsg(chainID, gasLimit, "", &to)
return buildTx(deps, true, msg, gasLimit, fees)
},
wantErr: "EVM Call operation is disabled",
},
{
name: "sad: tx without extension options should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
chainID := deps.Chain.EvmKeeper.EthChainID(deps.Ctx)
gasLimit := uint64(10)
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit)))
msg := buildEthMsg(chainID, gasLimit, deps.Sender.NibiruAddr.String(), nil)
return buildTx(deps, false, msg, gasLimit, fees)
},
wantErr: "for eth tx length of ExtensionOptions should be 1",
},
{
name: "sad: tx with non evm message",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
gasLimit := uint64(10)
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit)))
msg := &banktypes.MsgSend{
FromAddress: deps.Sender.NibiruAddr.String(),
ToAddress: evmtest.NewEthAccInfo().NibiruAddr.String(),
Amount: sdk.NewCoins(sdk.NewInt64Coin("unibi", 1)),
}
return buildTx(deps, true, msg, gasLimit, fees)
},
wantErr: "invalid message",
},
{
name: "sad: tx with from value set should fail",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
chainID := deps.Chain.EvmKeeper.EthChainID(deps.Ctx)
gasLimit := uint64(10)
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit)))
msg := buildEthMsg(chainID, gasLimit, deps.Sender.NibiruAddr.String(), nil)
return buildTx(deps, true, msg, gasLimit, fees)
},
wantErr: "invalid From",
},
{
name: "sad: tx with fee <> msg fee",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
chainID := deps.Chain.EvmKeeper.EthChainID(deps.Ctx)
gasLimit := uint64(10)
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", 5))
msg := buildEthMsg(chainID, gasLimit, "", nil)
return buildTx(deps, true, msg, gasLimit, fees)
},
wantErr: "invalid AuthInfo Fee Amount",
},
{
name: "sad: tx with gas limit <> msg gas limit",
txSetup: func(deps *evmtest.TestDeps) sdk.Tx {
chainID := deps.Chain.EvmKeeper.EthChainID(deps.Ctx)
gasLimit := uint64(10)
fees := sdk.NewCoins(sdk.NewInt64Coin("unibi", int64(gasLimit)))
msg := buildEthMsg(chainID, gasLimit, "", nil)
return buildTx(deps, true, msg, 5, fees)
},
wantErr: "invalid AuthInfo Fee GasLimit",
},
}

Expand All @@ -68,7 +226,9 @@ func (s *TestSuite) TestEthValidateBasicDecorator() {
if tc.ctxSetup != nil {
tc.ctxSetup(&deps)
}

if tc.paramsSetup != nil {
deps.K.SetParams(deps.Ctx, tc.paramsSetup(&deps))
}
_, err := anteDec.AnteHandle(
deps.Ctx, tx, false, NextNoOpAnteHandler,
)
Expand All @@ -80,3 +240,42 @@ func (s *TestSuite) TestEthValidateBasicDecorator() {
})
}
}

func buildEthMsg(
chainID *big.Int,
gasLimit uint64,
from string,
to *common.Address,

) *evm.MsgEthereumTx {
ethContractCreationTxParams := &evm.EvmTxArgs{
ChainID: chainID,
Nonce: 1,
Amount: big.NewInt(10),
GasLimit: gasLimit,
GasPrice: big.NewInt(1),
To: to,
}
tx := evm.NewTx(ethContractCreationTxParams)
tx.From = from
return tx
}

func buildTx(
deps *evmtest.TestDeps,
ethExtentions bool,
msg sdk.Msg,
gasLimit uint64,
fees sdk.Coins,
) sdk.Tx {
txBuilder, _ := deps.EncCfg.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if ethExtentions {
option, _ := codectypes.NewAnyWithValue(&evm.ExtensionOptionsEthereumTx{})
txBuilder.SetExtensionOptions(option)
}
txBuilder.SetMsgs(msg)

Check failure on line 276 in app/evmante_validate_basic_test.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `txBuilder.SetMsgs` is not checked (errcheck)
txBuilder.SetGasLimit(gasLimit)
txBuilder.SetFeeAmount(fees)

return txBuilder.GetTx()
}
1 change: 1 addition & 0 deletions e2e/evm/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18
Binary file added e2e/evm/bun.lockb
Binary file not shown.
36 changes: 36 additions & 0 deletions e2e/evm/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Use this justfile by
# (1) installing with "cargo install just"
# (2) running the "just" command.

# Displays available recipes by running `just -l`.
setup:
#!/usr/bin/env bash
just -l

# Install all dependencies
install:
#!/usr/bin/env bash
# Check if the given binary is in the $PATH.
the_cmd="bun"
if which "$the_cmd" >/dev/null 2>&1; then
echo "✅ bun is installed."
else
log_error "$the_cmd is not present in \$PATH"
npm install -g bun@1.1.12
fi

bun install

# Generate types from compiled contracts
gen-types:
bun run typechain --target=ethers-v6 contracts/*Compiled.json

# Runs the E2E tests
test:
bun test

# Format
fmt:
bun run prettier --write "test/**/*.ts"
Loading

0 comments on commit c631d4e

Please sign in to comment.