Skip to content

Commit

Permalink
chore: resolve conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
onikonychev committed May 22, 2024
2 parents a3b7b6b + 75ae7a8 commit 4213a19
Show file tree
Hide file tree
Showing 25 changed files with 923 additions and 151 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#1873](https://github.com/NibiruChain/nibiru/pull/1873) - feat(evm): keeper collections and grpc query impls for EthAccount, NibiruAccount
- [#xxxx](https://github.com/NibiruChain/nibiru/pull/xxxx) - feat(evm): keeper logic for ValidatorAccount, BaseFee, contract bytecode, EthCall, etc.
- [#1889](https://github.com/NibiruChain/nibiru/pull/1889) - feat: implemented basic evm tx methods
- [#1883](https://github.com/NibiruChain/nibiru/pull/1883) - feat(evm): keeper logic, Ante handlers, EthCall, and EVM transactions.
- [#1887](https://github.com/NibiruChain/nibiru/pull/1887) - test(evm): eth api integration test suite

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

Expand Down
13 changes: 11 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"os"
"path/filepath"

"github.com/cosmos/cosmos-sdk/types/mempool"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"

Expand All @@ -20,6 +18,7 @@ import (
abci "github.com/cometbft/cometbft/abci/types"
"github.com/cometbft/cometbft/libs/log"
tmos "github.com/cometbft/cometbft/libs/os"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
Expand All @@ -34,6 +33,7 @@ import (
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/mempool"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
authante "github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand All @@ -42,9 +42,11 @@ import (
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
"github.com/cosmos/cosmos-sdk/x/crisis"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"

ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"
ibctesting "github.com/cosmos/ibc-go/v7/testing"
"github.com/cosmos/ibc-go/v7/testing/types"

"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus"
"github.com/rakyll/statik/fs"
Expand Down Expand Up @@ -139,6 +141,13 @@ func NewNibiruApp(
legacyAmino := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
txConfig := encodingConfig.TxConfig
baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) {
mp := mempool.NoOpMempool{}
app.SetMempool(mp)
handler := baseapp.NewDefaultProposalHandler(mp, app)
app.SetPrepareProposal(handler.PrepareProposalHandler())
app.SetProcessProposal(handler.ProcessProposalHandler())
})

baseAppOptions = append(baseAppOptions, func(app *baseapp.BaseApp) {
mp := mempool.NoOpMempool{}
Expand Down
33 changes: 33 additions & 0 deletions app/appconst/appconst.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,36 @@ func RuntimeVersion() string {
GoArch,
)
}

// EIP 155 Chain IDs exported for tests.
const (
ETH_CHAIN_ID_MAINNET int64 = 420
ETH_CHAIN_ID_LOCAL int64 = 256
ETH_CHAIN_ID_DEVNET int64 = 500
ETH_CHAIN_ID_DEFAULT int64 = 3000
)

var knownEthChainIDMap = map[string]int64{
"cataclysm-1": ETH_CHAIN_ID_MAINNET,
"nibiru-localnet-0": ETH_CHAIN_ID_LOCAL,
"nibiru-localnet-1": ETH_CHAIN_ID_LOCAL,
"nibiru-localnet-2": ETH_CHAIN_ID_LOCAL,
"nibiru-testnet-0": ETH_CHAIN_ID_DEVNET,
"nibiru-testnet-1": ETH_CHAIN_ID_DEVNET,
"nibiru-testnet-2": ETH_CHAIN_ID_DEVNET,
"nibiru-devnet-0": ETH_CHAIN_ID_DEVNET,
"nibiru-devnet-1": ETH_CHAIN_ID_DEVNET,
"nibiru-devnet-2": ETH_CHAIN_ID_DEVNET,
}

// GetEthChainID: Maps the given chain ID from the block's `sdk.Context` to an
// EVM Chain ID (`*big.Int`).
func GetEthChainID(ctxChainID string) (ethChainID *big.Int) {
ethChainIdInt, found := knownEthChainIDMap[ctxChainID]
if !found {
ethChainID = big.NewInt(ETH_CHAIN_ID_DEFAULT)
} else {
ethChainID = big.NewInt(ethChainIdInt)
}
return ethChainID
}
49 changes: 49 additions & 0 deletions app/appconst/appconst_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package appconst_test

import (
"math/big"
"testing"

"github.com/stretchr/testify/suite"

"github.com/NibiruChain/nibiru/app/appconst"
)

type TestSuite struct {
suite.Suite
}

func TestSuite_RunAll(t *testing.T) {
suite.Run(t, new(TestSuite))
}

func (s *TestSuite) TestGetEthChainID() {
s.Run("mainnet", func() {
s.EqualValues(
big.NewInt(appconst.ETH_CHAIN_ID_MAINNET),
appconst.GetEthChainID("cataclysm-1"),
)
})
s.Run("localnet", func() {
s.EqualValues(
big.NewInt(appconst.ETH_CHAIN_ID_LOCAL),
appconst.GetEthChainID("nibiru-localnet-0"),
)
})
s.Run("devnet", func() {
want := big.NewInt(appconst.ETH_CHAIN_ID_DEVNET)
given := "nibiru-testnet-1"
s.EqualValues(want, appconst.GetEthChainID(given))

given = "nibiru-devnet-2"
s.EqualValues(want, appconst.GetEthChainID(given))
})
s.Run("else", func() {
want := big.NewInt(appconst.ETH_CHAIN_ID_DEFAULT)
for _, given := range []string{
"foo", "bloop-blap", "not a chain ID", "", "0x12345",
} {
s.EqualValues(want, appconst.GetEthChainID(given))
}
})
}
44 changes: 22 additions & 22 deletions app/evmante_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ import (
)

var (
_ sdk.AnteDecorator = (*EthGasConsumeDecorator)(nil)
_ sdk.AnteDecorator = (*EthAccountVerificationDecorator)(nil)
_ sdk.AnteDecorator = (*AnteDecEthGasConsume)(nil)
_ sdk.AnteDecorator = (*AnteDecVerifyEthAcc)(nil)
)

// EthAccountVerificationDecorator validates an account balance checks
type EthAccountVerificationDecorator struct {
// AnteDecVerifyEthAcc validates an account balance checks
type AnteDecVerifyEthAcc struct {
AppKeepers
}

// NewEthAccountVerificationDecorator creates a new EthAccountVerificationDecorator
func NewEthAccountVerificationDecorator(k AppKeepers) EthAccountVerificationDecorator {
return EthAccountVerificationDecorator{
// NewAnteDecVerifyEthAcc creates a new EthAccountVerificationDecorator
func NewAnteDecVerifyEthAcc(k AppKeepers) AnteDecVerifyEthAcc {
return AnteDecVerifyEthAcc{
AppKeepers: k,
}
}
Expand All @@ -43,7 +43,7 @@ func NewEthAccountVerificationDecorator(k AppKeepers) EthAccountVerificationDeco
// - any of the msgs is not a MsgEthereumTx
// - from address is empty
// - account balance is lower than the transaction cost
func (avd EthAccountVerificationDecorator) AnteHandle(
func (avd AnteDecVerifyEthAcc) AnteHandle(
ctx sdk.Context,
tx sdk.Tx,
simulate bool,
Expand Down Expand Up @@ -90,9 +90,9 @@ func (avd EthAccountVerificationDecorator) AnteHandle(
return next(ctx, tx, simulate)
}

// EthGasConsumeDecorator validates enough intrinsic gas for the transaction and
// AnteDecEthGasConsume validates enough intrinsic gas for the transaction and
// gas consumption.
type EthGasConsumeDecorator struct {
type AnteDecEthGasConsume struct {
AppKeepers
// bankKeeper anteutils.BankKeeper
// distributionKeeper anteutils.DistributionKeeper
Expand All @@ -101,12 +101,12 @@ type EthGasConsumeDecorator struct {
maxGasWanted uint64
}

// NewEthGasConsumeDecorator creates a new EthGasConsumeDecorator
func NewEthGasConsumeDecorator(
// NewAnteDecEthGasConsume creates a new EthGasConsumeDecorator
func NewAnteDecEthGasConsume(
keepers AppKeepers,
maxGasWanted uint64,
) EthGasConsumeDecorator {
return EthGasConsumeDecorator{
) AnteDecEthGasConsume {
return AnteDecEthGasConsume{
AppKeepers: keepers,
maxGasWanted: maxGasWanted,
}
Expand All @@ -129,7 +129,7 @@ func NewEthGasConsumeDecorator(
// - transaction or block gas meter runs out of gas
// - sets the gas meter limit
// - gas limit is greater than the block gas meter limit
func (egcd EthGasConsumeDecorator) AnteHandle(
func (egcd AnteDecEthGasConsume) AnteHandle(
ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler,
) (sdk.Context, error) {
gasWanted := uint64(0)
Expand Down Expand Up @@ -242,7 +242,7 @@ func (egcd EthGasConsumeDecorator) AnteHandle(

// deductFee checks if the fee payer has enough funds to pay for the fees and deducts them.
// If the spendable balance is not enough, it tries to claim enough staking rewards to cover the fees.
func (egcd EthGasConsumeDecorator) deductFee(ctx sdk.Context, fees sdk.Coins, feePayer sdk.AccAddress) error {
func (egcd AnteDecEthGasConsume) deductFee(ctx sdk.Context, fees sdk.Coins, feePayer sdk.AccAddress) error {
if fees.IsZero() {
return nil
}
Expand Down Expand Up @@ -335,22 +335,22 @@ func (ctd CanTransferDecorator) AnteHandle(
return next(ctx, tx, simulate)
}

// EthIncrementSenderSequenceDecorator increments the sequence of the signers.
type EthIncrementSenderSequenceDecorator struct {
// AnteDecEthIncrementSenderSequence increments the sequence of the signers.
type AnteDecEthIncrementSenderSequence struct {
AppKeepers
}

// NewEthIncrementSenderSequenceDecorator creates a new EthIncrementSenderSequenceDecorator.
func NewEthIncrementSenderSequenceDecorator(k AppKeepers) EthIncrementSenderSequenceDecorator {
return EthIncrementSenderSequenceDecorator{
// NewAnteDecEthIncrementSenderSequence creates a new EthIncrementSenderSequenceDecorator.
func NewAnteDecEthIncrementSenderSequence(k AppKeepers) AnteDecEthIncrementSenderSequence {
return AnteDecEthIncrementSenderSequence{
AppKeepers: k,
}
}

// AnteHandle handles incrementing the sequence of the signer (i.e. sender). If the transaction is a
// contract creation, the nonce will be incremented during the transaction execution and not within
// this AnteHandler decorator.
func (issd EthIncrementSenderSequenceDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
func (issd AnteDecEthIncrementSenderSequence) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evm.MsgEthereumTx)
if !ok {
Expand Down
6 changes: 3 additions & 3 deletions app/evmante_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ func NewAnteHandlerEVM(
NewEthMinGasPriceDecorator(k),
NewEthValidateBasicDecorator(k),
NewEthSigVerificationDecorator(k),
NewEthAccountVerificationDecorator(k),
NewAnteDecVerifyEthAcc(k),
NewCanTransferDecorator(k),
NewEthGasConsumeDecorator(k, options.MaxTxGasWanted),
NewEthIncrementSenderSequenceDecorator(k),
NewAnteDecEthGasConsume(k, options.MaxTxGasWanted),
NewAnteDecEthIncrementSenderSequence(k),
NewGasWantedDecorator(k),
// emit eth tx hash and index at the very last ante handler.
NewEthEmitEventDecorator(k),
Expand Down
101 changes: 101 additions & 0 deletions app/evmante_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package app_test

import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"

gethparams "github.com/ethereum/go-ethereum/params"

"github.com/NibiruChain/nibiru/app"
"github.com/NibiruChain/nibiru/x/evm"
"github.com/NibiruChain/nibiru/x/evm/evmtest"

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

var NextNoOpAnteHandler sdk.AnteHandler = func(
ctx sdk.Context, tx sdk.Tx, simulate bool,
) (newCtx sdk.Context, err error) {
return ctx, nil
}

func (s *TestSuite) TestAnteDecoratorVerifyEthAcc_CheckTx() {
happyCreateContractTx := func(deps *evmtest.TestDeps) *evm.MsgEthereumTx {
ethContractCreationTxParams := &evm.EvmTxArgs{
ChainID: deps.Chain.EvmKeeper.EthChainID(deps.Ctx),
Nonce: 1,
Amount: big.NewInt(10),
GasLimit: 1000,
GasPrice: big.NewInt(1),
}
tx := evm.NewTx(ethContractCreationTxParams)
tx.From = deps.Sender.EthAddr.Hex()
return tx
}

testCases := []struct {
name string
beforeTxSetup func(deps *evmtest.TestDeps, sdb *statedb.StateDB)
txSetup func(deps *evmtest.TestDeps) *evm.MsgEthereumTx
wantErr string
}{
{
name: "happy: sender with funds",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
gasLimit := new(big.Int).SetUint64(
gethparams.TxGasContractCreation + 500,
)
// Force account to be a smart contract
sdb.AddBalance(deps.Sender.EthAddr, gasLimit)
},
txSetup: happyCreateContractTx,
wantErr: "",
},
{
name: "sad: sender has insufficient gas balance",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {},
txSetup: happyCreateContractTx,
wantErr: "sender balance < tx cost",
},
{
name: "sad: sender cannot be a contract -> no contract bytecode",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {
// Force account to be a smart contract
sdb.SetCode(deps.Sender.EthAddr, []byte("evm bytecode stuff"))
},
txSetup: happyCreateContractTx,
wantErr: "sender is not EOA",
},
{
name: "sad: invalid tx",
beforeTxSetup: func(deps *evmtest.TestDeps, sdb *statedb.StateDB) {},
txSetup: func(deps *evmtest.TestDeps) *evm.MsgEthereumTx {
return new(evm.MsgEthereumTx)
},
wantErr: "failed to unpack tx data",
},
}

for _, tc := range testCases {
s.Run(tc.name, func() {
deps := evmtest.NewTestDeps()
stateDB := deps.StateDB()
anteDec := app.NewAnteDecVerifyEthAcc(deps.Chain.AppKeepers)

tc.beforeTxSetup(&deps, stateDB)
tx := tc.txSetup(&deps)
s.Require().NoError(stateDB.Commit())

deps.Ctx = deps.Ctx.WithIsCheckTx(true)
_, err := anteDec.AnteHandle(
deps.Ctx, tx, false, NextNoOpAnteHandler,
)
if tc.wantErr != "" {
s.Require().ErrorContains(err, tc.wantErr)
return
}
s.Require().NoError(err)
})
}
}
14 changes: 11 additions & 3 deletions eth/chain_id.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,20 @@ func IsValidChainID(chainID string) bool {
return nibiruEvmChainId.MatchString(chainID)
}

// TODO: feat(eth): Make ParseEthChainID compatible with existing testnets.

// ParseEthChainID parses a string chain identifier's epoch to an
// Ethereum-compatible chain-id in *big.Int format.
//
// This function uses Nibiru's map of chain IDs defined in Nibiru/app/appconst
// rather than the regex of EIP155, which is implemented by
// ParseEthChainIDStrict.
func ParseEthChainID(chainID string) (*big.Int, error) {
return appconst.GetEthChainID(chainID), nil
}

// ParseEthChainIDStrict parses a string chain identifier's epoch to an
// Ethereum-compatible chain-id in *big.Int format. The function returns an error
// if the chain-id has an invalid format
func ParseEthChainID(chainID string) (*big.Int, error) {
func ParseEthChainIDStrict(chainID string) (*big.Int, error) {
evmChainID, exists := appconst.EVMChainIDs[chainID]
if exists {
return evmChainID, nil
Expand Down
Loading

0 comments on commit 4213a19

Please sign in to comment.