Skip to content

Commit

Permalink
test(evm): grpc_query full coverage (#1907)
Browse files Browse the repository at this point in the history
* test(evm): grpc_query full coverage

* chore: changelog update

* chore: refactored eth util methods

* fix: removed hardcoded gas value in grpc_query test

---------

Co-authored-by: Unique Divine <[email protected]>
  • Loading branch information
onikonychev and Unique-Divine authored Jun 6, 2024
1 parent 70ee1bf commit 957c7b2
Show file tree
Hide file tree
Showing 8 changed files with 585 additions and 89 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1889](https://github.com/NibiruChain/nibiru/pull/1889) - feat: implemented basic evm tx methods
- [#1895](https://github.com/NibiruChain/nibiru/pull/1895) - refactor(geth): Reference go-ethereum as a submodule for easier change tracking with upstream
- [#1901](https://github.com/NibiruChain/nibiru/pull/1901) - test(evm): more e2e test contracts for edge cases
- [#1907](https://github.com/NibiruChain/nibiru/pull/1907) - test(evm): grpc_query full coverage
- [#1909](https://github.com/NibiruChain/nibiru/pull/1909) - chore(evm): set is_london true by default and removed from config

#### Dapp modules: perp, spot, oracle, etc
Expand Down
4 changes: 1 addition & 3 deletions app/evmante_fees.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import (
"github.com/NibiruChain/nibiru/x/evm"
)

var (
_ sdk.AnteDecorator = EthMinGasPriceDecorator{}
)
var _ sdk.AnteDecorator = EthMinGasPriceDecorator{}

// EthMinGasPriceDecorator will check if the transaction's fee is at least as large
// as the MinGasPrices param. If fee is too low, decorator returns error and tx
Expand Down
6 changes: 4 additions & 2 deletions gosdk/gosdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import (
// NibiruClientSuite
// --------------------------------------------------

var _ suite.SetupAllSuite = (*TestSuite)(nil)
var _ suite.TearDownAllSuite = (*TestSuite)(nil)
var (
_ suite.SetupAllSuite = (*TestSuite)(nil)
_ suite.TearDownAllSuite = (*TestSuite)(nil)
)

type TestSuite struct {
suite.Suite
Expand Down
2 changes: 1 addition & 1 deletion x/evm/evmtest/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func NewEthAccInfo() EthPrivKeyAcc {
}

func EthAddrToNibiruAddr(ethAddr gethcommon.Address) sdk.AccAddress {
return sdk.AccAddress(ethAddr.Bytes())
return ethAddr.Bytes()
}

type EthPrivKeyAcc struct {
Expand Down
101 changes: 95 additions & 6 deletions x/evm/evmtest/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,25 @@
package evmtest

import (
"encoding/json"
"fmt"
"math/big"
"testing"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gethcore "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
gethparams "github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"

srvconfig "github.com/NibiruChain/nibiru/app/server/config"

"github.com/NibiruChain/nibiru/x/evm"
)

type GethTxType = uint8

var (
GethTxType_LegacyTx GethTxType = gethcore.LegacyTxType
GethTxType_AccessListTx GethTxType = gethcore.AccessListTxType
GethTxType_DynamicFeeTx GethTxType = gethcore.DynamicFeeTxType
)

func NewEthTx(
deps *TestDeps, txData gethcore.TxData, nonce uint64,
) (ethCoreTx *gethcore.Transaction, err error) {
Expand Down Expand Up @@ -131,3 +132,91 @@ func NewEthTxMsgFromTxData(
ethTxMsg.From = deps.Sender.EthAddr.Hex()
return ethTxMsg, ethTxMsg.Sign(deps.GethSigner(), deps.Sender.KeyringSigner)
}

// ExecuteNibiTransfer executes nibi transfer
func ExecuteNibiTransfer(deps *TestDeps, t *testing.T) *evm.MsgEthereumTx {
nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr)
recipient := NewEthAccInfo().EthAddr

txArgs := evm.JsonTxArgs{
From: &deps.Sender.EthAddr,
To: &recipient,
Nonce: (*hexutil.Uint64)(&nonce),
}
ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps)
require.NoError(t, err)

resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg)
require.NoError(t, err)
require.Empty(t, resp.VmError)
return ethTxMsg
}

// ExecuteERC20Transfer deploys contract, executes transfer and returns tx hash
func ExecuteERC20Transfer(deps *TestDeps, t *testing.T) (*evm.MsgEthereumTx, []*evm.MsgEthereumTx) {
// TX 1: Deploy ERC-20 contract
contractData := SmartContract_FunToken.Load(t)
nonce := deps.StateDB().GetNonce(deps.Sender.EthAddr)
txArgs := evm.JsonTxArgs{
From: &deps.Sender.EthAddr,
Nonce: (*hexutil.Uint64)(&nonce),
Data: (*hexutil.Bytes)(&contractData.Bytecode),
}
ethTxMsg, err := GenerateAndSignEthTxMsg(txArgs, deps)
require.NoError(t, err)

resp, err := deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg)
require.NoError(t, err)
require.Empty(t, resp.VmError)

// Contract address is deterministic
contractAddress := crypto.CreateAddress(deps.Sender.EthAddr, nonce)
deps.Chain.Commit()
predecessors := []*evm.MsgEthereumTx{
ethTxMsg,
}

// TX 2: execute ERC-20 contract transfer
input, err := contractData.ABI.Pack(
"transfer", NewEthAccInfo().EthAddr, new(big.Int).SetUint64(1000),
)
require.NoError(t, err)
nonce = deps.StateDB().GetNonce(deps.Sender.EthAddr)
txArgs = evm.JsonTxArgs{
From: &deps.Sender.EthAddr,
To: &contractAddress,
Nonce: (*hexutil.Uint64)(&nonce),
Data: (*hexutil.Bytes)(&input),
}
ethTxMsg, err = GenerateAndSignEthTxMsg(txArgs, deps)
require.NoError(t, err)

resp, err = deps.Chain.EvmKeeper.EthereumTx(deps.GoCtx(), ethTxMsg)
require.NoError(t, err)
require.Empty(t, resp.VmError)

return ethTxMsg, predecessors
}

// GenerateAndSignEthTxMsg estimates gas, sets gas limit and sings the tx
func GenerateAndSignEthTxMsg(txArgs evm.JsonTxArgs, deps *TestDeps) (*evm.MsgEthereumTx, error) {
estimateArgs, err := json.Marshal(&txArgs)
if err != nil {
return nil, err
}
res, err := deps.Chain.EvmKeeper.EstimateGas(deps.GoCtx(), &evm.EthCallRequest{
Args: estimateArgs,
GasCap: srvconfig.DefaultGasCap,
ProposerAddress: []byte{},
ChainId: deps.Chain.EvmKeeper.EthChainID(deps.Ctx).Int64(),
})
if err != nil {
return nil, err
}
txArgs.Gas = (*hexutil.Uint64)(&res.Gas)

txMsg := txArgs.ToTransaction()
gethSigner := deps.Sender.GethSigner(deps.Chain.EvmKeeper.EthChainID(deps.Ctx))
keyringSigner := deps.Sender.KeyringSigner
return txMsg, txMsg.Sign(gethSigner, keyringSigner)
}
Loading

0 comments on commit 957c7b2

Please sign in to comment.