From 3159973d115836ceb80581bd1865166e13da87fe Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Fri, 10 May 2024 02:41:42 -0500 Subject: [PATCH 01/11] feat(evm): module wiring --- app/keepers.go | 22 +++- eth/chain_id.go | 5 +- x/common/error.go | 8 ++ x/evm/cli/cli.go | 50 ++++++++ x/evm/codec.go | 5 - x/evm/const.go | 14 +++ x/evm/deps.go | 36 ++++++ x/evm/evmmodule/genesis.go | 30 +++++ x/evm/evmmodule/module.go | 170 ++++++++++++++++++++++++++ x/evm/keeper/grpc_query.go | 238 ++++++++++++++++++++++++++++++++++++ x/evm/keeper/hooks.go | 21 ++++ x/evm/keeper/keeper.go | 36 ++++++ x/evm/keeper/keeper_test.go | 99 +++++++++++++++ x/evm/keeper/msg_server.go | 25 ++++ 14 files changed, 751 insertions(+), 8 deletions(-) create mode 100644 x/evm/cli/cli.go create mode 100644 x/evm/deps.go create mode 100644 x/evm/evmmodule/genesis.go create mode 100644 x/evm/evmmodule/module.go create mode 100644 x/evm/keeper/grpc_query.go create mode 100644 x/evm/keeper/hooks.go create mode 100644 x/evm/keeper/keeper.go create mode 100644 x/evm/keeper/keeper_test.go create mode 100644 x/evm/keeper/msg_server.go diff --git a/app/keepers.go b/app/keepers.go index 7cea4eea4..e5cefbf9b 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -111,6 +111,9 @@ import ( "github.com/NibiruChain/nibiru/x/epochs" epochskeeper "github.com/NibiruChain/nibiru/x/epochs/keeper" epochstypes "github.com/NibiruChain/nibiru/x/epochs/types" + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/evm/evmmodule" + evmkeeper "github.com/NibiruChain/nibiru/x/evm/keeper" "github.com/NibiruChain/nibiru/x/genmsg" "github.com/NibiruChain/nibiru/x/inflation" inflationkeeper "github.com/NibiruChain/nibiru/x/inflation/keeper" @@ -182,6 +185,7 @@ type AppKeepers struct { SudoKeeper keeper.Keeper DevGasKeeper devgaskeeper.Keeper TokenFactoryKeeper tokenfactorykeeper.Keeper + EvmKeeper evmkeeper.Keeper // WASM keepers WasmKeeper wasmkeeper.Keeper @@ -224,6 +228,8 @@ func initStoreKeys() ( wasmtypes.StoreKey, devgastypes.StoreKey, tokenfactorytypes.StoreKey, + + evm.StoreKey, ) tkeys = sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys = sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -384,6 +390,13 @@ func (app *NibiruApp) InitKeepers( ), ) + app.EvmKeeper = evmkeeper.NewKeeper( + appCodec, + keys[evm.StoreKey], + tkeys[evm.TransientKey], + authtypes.NewModuleAddress(govtypes.ModuleName), + ) + // ---------------------------------- IBC keepers app.ibcKeeper = ibckeeper.NewKeeper( @@ -622,6 +635,8 @@ func (app *NibiruApp) initAppModules( ibcfee.NewAppModule(app.ibcFeeKeeper), ica.NewAppModule(&app.icaControllerKeeper, &app.icaHostKeeper), + evmmodule.NewAppModule(&app.EvmKeeper, app.AccountKeeper), + // wasm wasm.NewAppModule( appCodec, &app.WasmKeeper, app.stakingKeeper, app.AccountKeeper, @@ -691,13 +706,16 @@ func orderedModuleNames() []string { ibcfeetypes.ModuleName, icatypes.ModuleName, + // -------------------------------------------------------------------- + evm.ModuleName, + // -------------------------------------------------------------------- // CosmWasm wasmtypes.ModuleName, devgastypes.ModuleName, tokenfactorytypes.ModuleName, - // Should be before genmsg + // Everything else should be before genmsg genmsg.ModuleName, } } @@ -794,6 +812,7 @@ func ModuleBasicManager() module.BasicManager { ibctm.AppModuleBasic{}, ica.AppModuleBasic{}, // native x/ + evmmodule.AppModuleBasic{}, oracle.AppModuleBasic{}, epochs.AppModuleBasic{}, inflation.AppModuleBasic{}, @@ -819,6 +838,7 @@ func ModuleAccPerms() map[string][]string { ibcfeetypes.ModuleName: {}, icatypes.ModuleName: {}, + evm.ModuleName: {authtypes.Minter, authtypes.Burner}, epochstypes.ModuleName: {}, sudotypes.ModuleName: {}, common.TreasuryPoolModuleAccount: {}, diff --git a/eth/chain_id.go b/eth/chain_id.go index a77039453..8ed1c920f 100644 --- a/eth/chain_id.go +++ b/eth/chain_id.go @@ -33,8 +33,9 @@ func IsValidChainID(chainID string) bool { return nibiruEvmChainId.MatchString(chainID) } -// ParseChainID 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 +// ParseChainID 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 ParseChainID(chainID string) (*big.Int, error) { chainID = strings.TrimSpace(chainID) if len(chainID) > 48 { diff --git a/x/common/error.go b/x/common/error.go index a7c9ba9d3..4fa0a171f 100644 --- a/x/common/error.go +++ b/x/common/error.go @@ -187,3 +187,11 @@ func CombineErrorsFromStrings(strs ...string) (err error) { func ErrNilMsg() error { return grpcstatus.Errorf(grpccodes.InvalidArgument, "nil msg") } + +// ErrNotImplemented: Represents an function error value. +func ErrNotImplemented() error { return fmt.Errorf("fn not implemented yet") } + +// ErrNotImplementedGprc: Represents an unimplemented gRPC method. +func ErrNotImplementedGprc() error { + return grpcstatus.Error(grpccodes.Unimplemented, ErrNotImplemented().Error()) +} diff --git a/x/evm/cli/cli.go b/x/evm/cli/cli.go new file mode 100644 index 000000000..2fe7b80b8 --- /dev/null +++ b/x/evm/cli/cli.go @@ -0,0 +1,50 @@ +package cli + +import ( + "fmt" + + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/sudo/types" + + "github.com/cosmos/cosmos-sdk/client" + + "github.com/spf13/cobra" +) + +// GetTxCmd returns a cli command for this module's transactions +func GetTxCmd() *cobra.Command { + txCmd := &cobra.Command{ + Use: evm.ModuleName, + Short: fmt.Sprintf("x/%s transaction subcommands", evm.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmds := []*cobra.Command{} + for _, cmd := range cmds { + txCmd.AddCommand(cmd) + } + + return txCmd +} + +// GetQueryCmd returns a cli command for this module's queries +func GetQueryCmd() *cobra.Command { + moduleQueryCmd := &cobra.Command{ + Use: evm.ModuleName, + Short: fmt.Sprintf( + "Query commands for the x/%s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + // Add subcommands + cmds := []*cobra.Command{} + for _, cmd := range cmds { + moduleQueryCmd.AddCommand(cmd) + } + + return moduleQueryCmd +} diff --git a/x/evm/codec.go b/x/evm/codec.go index 3f895b5b4..e2453a4dd 100644 --- a/x/evm/codec.go +++ b/x/evm/codec.go @@ -22,11 +22,6 @@ var ( AminoCdc = codec.NewAminoCodec(amino) ) -const ( - // Amino names - updateParamsName = "evm/MsgUpdateParams" -) - // NOTE: This is required for the GetSignBytes function func init() { RegisterLegacyAminoCodec(amino) diff --git a/x/evm/const.go b/x/evm/const.go index e2379d707..ee7ba2230 100644 --- a/x/evm/const.go +++ b/x/evm/const.go @@ -60,3 +60,17 @@ func PrefixAccStateEthAddr(address common.Address) []byte { func StateKey(address common.Address, key []byte) []byte { return append(PrefixAccStateEthAddr(address), key...) } + +const ( + // Amino names + updateParamsName = "evm/MsgUpdateParams" +) + +type CallType int + +const ( + // CallTypeRPC call type is used on requests to eth_estimateGas rpc API endpoint + CallTypeRPC CallType = iota + 1 + // CallTypeSmart call type is used in case of smart contract methods calls + CallTypeSmart +) diff --git a/x/evm/deps.go b/x/evm/deps.go new file mode 100644 index 000000000..b76eb37ac --- /dev/null +++ b/x/evm/deps.go @@ -0,0 +1,36 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package evm + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// AccountKeeper defines the expected account keeper interface +type AccountKeeper interface { + NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI + GetModuleAddress(moduleName string) sdk.AccAddress + GetAllAccounts(ctx sdk.Context) (accounts []authtypes.AccountI) + IterateAccounts(ctx sdk.Context, cb func(account authtypes.AccountI) bool) + GetSequence(sdk.Context, sdk.AccAddress) (uint64, error) + GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI + SetAccount(ctx sdk.Context, account authtypes.AccountI) + RemoveAccount(ctx sdk.Context, account authtypes.AccountI) + GetParams(ctx sdk.Context) (params authtypes.Params) +} + +// BankKeeper defines the expected interface needed to retrieve account balances. +type BankKeeper interface { + authtypes.BankKeeper + GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + MintCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error +} + +// StakingKeeper returns the historical headers kept in store. +type StakingKeeper interface { + GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool) + GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) (validator stakingtypes.Validator, found bool) +} diff --git a/x/evm/evmmodule/genesis.go b/x/evm/evmmodule/genesis.go new file mode 100644 index 000000000..2ad0ee06a --- /dev/null +++ b/x/evm/evmmodule/genesis.go @@ -0,0 +1,30 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package evmmodule + +import ( + abci "github.com/cometbft/cometbft/abci/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/evm/keeper" +) + +// InitGenesis initializes genesis state based on exported genesis +func InitGenesis( + ctx sdk.Context, + k *keeper.Keeper, + accountKeeper evm.AccountKeeper, + data evm.GenesisState, +) []abci.ValidatorUpdate { + // TODO: impl InitGenesis + return []abci.ValidatorUpdate{} +} + +// ExportGenesis exports genesis state of the EVM module +func ExportGenesis(ctx sdk.Context, k *keeper.Keeper, ak evm.AccountKeeper) *evm.GenesisState { + // TODO: impl ExportGenesis + return &evm.GenesisState{ + Accounts: []evm.GenesisAccount{}, + Params: evm.Params{}, + } +} diff --git a/x/evm/evmmodule/module.go b/x/evm/evmmodule/module.go new file mode 100644 index 000000000..8b9f94ecc --- /dev/null +++ b/x/evm/evmmodule/module.go @@ -0,0 +1,170 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package evmmodule + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/evm/cli" + "github.com/NibiruChain/nibiru/x/evm/keeper" +) + +// consensusVersion: EVM module consensus version for upgrades. +const consensusVersion = 1 + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.EndBlockAppModule = AppModule{} + _ module.BeginBlockAppModule = AppModule{} +) + +// AppModuleBasic defines the basic application module used by the evm module. +type AppModuleBasic struct{} + +// Name returns the evm module's name. +func (AppModuleBasic) Name() string { + return evm.ModuleName +} + +// RegisterLegacyAminoCodec registers the module's types with the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + evm.RegisterLegacyAminoCodec(cdc) +} + +// ConsensusVersion returns the consensus state-breaking version for the module. +func (AppModuleBasic) ConsensusVersion() uint64 { + return consensusVersion +} + +// DefaultGenesis returns default genesis state as raw bytes for the evm +// module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(evm.DefaultGenesisState()) +} + +// ValidateGenesis is the validation check of the Genesis +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var genesisState evm.GenesisState + if err := cdc.UnmarshalJSON(bz, &genesisState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", evm.ModuleName, err) + } + + return genesisState.Validate() +} + +// RegisterRESTRoutes performs a no-op as the EVM module doesn't expose REST +// endpoints +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +func (b AppModuleBasic) RegisterGRPCGatewayRoutes(c client.Context, serveMux *runtime.ServeMux) { + if err := evm.RegisterQueryHandlerClient(context.Background(), serveMux, evm.NewQueryClient(c)); err != nil { + panic(err) + } +} + +// GetTxCmd returns the root tx command for the evm module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns no root query command for the evm module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// RegisterInterfaces registers interfaces and implementations of the evm module. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + evm.RegisterInterfaces(registry) +} + +// ____________________________________________________________________________ + +// AppModule implements an application module for the evm module. +type AppModule struct { + AppModuleBasic + keeper *keeper.Keeper + ak evm.AccountKeeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule(k *keeper.Keeper, ak evm.AccountKeeper) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{}, + keeper: k, + ak: ak, + } +} + +// Name returns the evm module's name. +func (AppModule) Name() string { + return evm.ModuleName +} + +// RegisterInvariants interface for registering invariants. Performs a no-op +// as the evm module doesn't expose invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) { +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + evm.RegisterMsgServer(cfg.MsgServer(), am.keeper) + evm.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// BeginBlock returns the begin block for the evm module. +func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { + am.keeper.BeginBlock(ctx, req) +} + +// EndBlock returns the end blocker for the evm module. It returns no validator +// updates. +func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate { + return am.keeper.EndBlock(ctx, req) +} + +// InitGenesis performs genesis initialization for the evm module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState evm.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + InitGenesis(ctx, am.keeper, am.ak, genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the evm +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := ExportGenesis(ctx, am.keeper, am.ak) + return cdc.MustMarshalJSON(gs) +} + +// RegisterStoreDecoder registers a decoder for evm module's types +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { +} + +// GenerateGenesisState creates a randomized GenState of the evm module. +func (AppModule) GenerateGenesisState(_ *module.SimulationState) { +} + +// WeightedOperations returns the all the evm module operations with their respective weights. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go new file mode 100644 index 000000000..b8850d963 --- /dev/null +++ b/x/evm/keeper/grpc_query.go @@ -0,0 +1,238 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + "context" + + sdkmath "cosmossdk.io/math" + + "github.com/NibiruChain/nibiru/x/common" + "github.com/NibiruChain/nibiru/x/evm" +) + +// Compile-time interface assertion +var _ evm.QueryServer = Keeper{} + +// Account: Implements the gRPC query for "/eth.evm.v1.Query/Account". +// Account retrieves the account details for a given Ethereum hex address. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryAccountRequest object containing the Ethereum address. +// +// Returns: +// - A pointer to the QueryAccountResponse object containing the account details. +// - An error if the account retrieval process encounters any issues. +func (k Keeper) Account( + goCtx context.Context, req *evm.QueryAccountRequest, +) (*evm.QueryAccountResponse, error) { + // TODO: feat(evm): impl query Account + return &evm.QueryAccountResponse{ + Balance: "", + CodeHash: "", + Nonce: 0, + }, common.ErrNotImplementedGprc() +} + +// CosmosAccount: Implements the gRPC query for "/eth.evm.v1.Query/CosmosAccount". +// CosmosAccount retrieves the Cosmos account details for a given Ethereum address. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryCosmosAccountRequest object containing the Ethereum address. +// +// Returns: +// - A pointer to the QueryCosmosAccountResponse object containing the Cosmos account details. +// - An error if the account retrieval process encounters any issues. +func (k Keeper) CosmosAccount( + goCtx context.Context, req *evm.QueryCosmosAccountRequest, +) (*evm.QueryCosmosAccountResponse, error) { + // TODO: feat(evm): impl query CosmosAccount + return &evm.QueryCosmosAccountResponse{ + CosmosAddress: "", + Sequence: 0, + AccountNumber: 0, + }, common.ErrNotImplementedGprc() +} + +// ValidatorAccount: Implements the gRPC query for "/eth.evm.v1.Query/ValidatorAccount". +// ValidatorAccount retrieves the account details for a given validator consensus address. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryValidatorAccountRequest object containing the validator consensus address. +// +// Returns: +// - A pointer to the QueryValidatorAccountResponse object containing the account details. +// - An error if the account retrieval process encounters any issues. +func (k Keeper) ValidatorAccount( + goCtx context.Context, req *evm.QueryValidatorAccountRequest, +) (*evm.QueryValidatorAccountResponse, error) { + // TODO: feat(evm): impl query ValidatorAccount + return &evm.QueryValidatorAccountResponse{ + AccountAddress: "", + Sequence: 0, + AccountNumber: 0, + }, common.ErrNotImplementedGprc() +} + +// Balance: Implements the gRPC query for "/eth.evm.v1.Query/Balance". +// Balance retrieves the balance of an Ethereum address in "Ether", which +// actually refers to NIBI tokens on Nibiru EVM. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryBalanceRequest object containing the Ethereum address. +// +// Returns: +// - A pointer to the QueryBalanceResponse object containing the balance. +// - An error if the balance retrieval process encounters any issues. +func (k Keeper) Balance(goCtx context.Context, req *evm.QueryBalanceRequest) (*evm.QueryBalanceResponse, error) { + // TODO: feat(evm): impl query Balance + return &evm.QueryBalanceResponse{ + Balance: "", + }, common.ErrNotImplementedGprc() +} + +// BaseFee implements the Query/BaseFee gRPC method +func (k Keeper) BaseFee( + goCtx context.Context, _ *evm.QueryBaseFeeRequest, +) (*evm.QueryBaseFeeResponse, error) { + // TODO: feat(evm): impl query BaseFee + return &evm.QueryBaseFeeResponse{ + BaseFee: &sdkmath.Int{}, + }, common.ErrNotImplementedGprc() +} + +// Storage: Implements the gRPC query for "/eth.evm.v1.Query/Storage". +// Storage retrieves the storage value for a given Ethereum address and key. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryStorageRequest object containing the Ethereum address and key. +// +// Returns: +// - A pointer to the QueryStorageResponse object containing the storage value. +// - An error if the storage retrieval process encounters any issues. +func (k Keeper) Storage(goCtx context.Context, req *evm.QueryStorageRequest) (*evm.QueryStorageResponse, error) { + // TODO: feat(evm): impl query Storage + return &evm.QueryStorageResponse{ + Value: "", + }, common.ErrNotImplementedGprc() +} + +// Code: Implements the gRPC query for "/eth.evm.v1.Query/Code". +// Code retrieves the smart contract bytecode associated with a given Ethereum +// address. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryCodeRequest object containing the Ethereum address. +// +// Returns: +// - A pointer to the QueryCodeResponse object containing the code. +// - An error if the code retrieval process encounters any issues. +func (k Keeper) Code(goCtx context.Context, req *evm.QueryCodeRequest) (*evm.QueryCodeResponse, error) { + // TODO: feat(evm): impl query Code + return &evm.QueryCodeResponse{ + Code: []byte{}, + }, common.ErrNotImplementedGprc() +} + +// Params: Implements the gRPC query for "/eth.evm.v1.Query/Params". +// Params retrieves the EVM module parameters. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The QueryParamsRequest object (unused). +// +// Returns: +// - A pointer to the QueryParamsResponse object containing the EVM module parameters. +// - An error if the parameter retrieval process encounters any issues. +func (k Keeper) Params(goCtx context.Context, _ *evm.QueryParamsRequest) (*evm.QueryParamsResponse, error) { + // TODO: feat(evm): impl query Params + return &evm.QueryParamsResponse{ + Params: evm.Params{}, + }, common.ErrNotImplementedGprc() +} + +// EthCall: Implements the gRPC query for "/eth.evm.v1.Query/EthCall". +// EthCall performs a smart contract call using the eth_call JSON-RPC method. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The EthCallRequest object containing the call parameters. +// +// Returns: +// - A pointer to the MsgEthereumTxResponse object containing the result of the eth_call. +// - An error if the eth_call process encounters any issues. +func (k Keeper) EthCall( + goCtx context.Context, req *evm.EthCallRequest, +) (*evm.MsgEthereumTxResponse, error) { + // TODO: feat(evm): impl query EthCall + return &evm.MsgEthereumTxResponse{ + Hash: "", + Logs: []*evm.Log{}, + Ret: []byte{}, + VmError: "", + GasUsed: 0, + }, common.ErrNotImplementedGprc() +} + +// EstimateGas: Implements the gRPC query for "/eth.evm.v1.Query/EstimateGas". +// EstimateGas implements eth_estimateGas rpc api. +func (k Keeper) EstimateGas( + goCtx context.Context, req *evm.EthCallRequest, +) (*evm.EstimateGasResponse, error) { + // TODO: feat(evm): impl query EstimateGas + return k.EstimateGasForEvmCallType(goCtx, req, evm.CallTypeRPC) +} + +// EstimateGas estimates the gas cost of a transaction. This can be called with +// the "eth_estimateGas" JSON-RPC method or an smart contract query. +// +// When [EstimateGas] is called from the JSON-RPC client, we need to reset the +// gas meter before simulating the transaction (tx) to have an accurate gas estimate +// txs using EVM extensions. +// +// Parameters: +// - goCtx: The context.Context object representing the request context. +// - req: The EthCallRequest object containing the transaction parameters. +// +// Returns: +// - A pointer to the EstimateGasResponse object containing the estimated gas cost. +// - An error if the gas estimation process encounters any issues. +func (k Keeper) EstimateGasForEvmCallType( + goCtx context.Context, req *evm.EthCallRequest, fromType evm.CallType, +) (*evm.EstimateGasResponse, error) { + // TODO: feat(evm): impl query EstimateGasForEvmCallType + return &evm.EstimateGasResponse{ + Gas: 0, + }, common.ErrNotImplementedGprc() +} + +// TraceTx configures a new tracer according to the provided configuration, and +// executes the given message in the provided environment. The return value will +// be tracer dependent. +func (k Keeper) TraceTx( + goCtx context.Context, req *evm.QueryTraceTxRequest, +) (*evm.QueryTraceTxResponse, error) { + // TODO: feat(evm): impl query TraceTx + return &evm.QueryTraceTxResponse{ + Data: []byte{}, + }, common.ErrNotImplementedGprc() +} + +// TraceBlock: Implements the gRPC query for "/eth.evm.v1.Query/TraceBlock". +// Configures a Nibiru EVM tracer that is used to "trace" and analyze +// the execution of transactions within a given block. Block information is read +// from the context (goCtx). [TraceBlock] is responsible iterates over each Eth +// transacion message and calls [TraceEthTxMsg] on it. +func (k Keeper) TraceBlock( + goCtx context.Context, req *evm.QueryTraceBlockRequest, +) (*evm.QueryTraceBlockResponse, error) { + // TODO: feat(evm): impl query TraceBlock + return &evm.QueryTraceBlockResponse{ + Data: []byte{}, + }, common.ErrNotImplementedGprc() +} diff --git a/x/evm/keeper/hooks.go b/x/evm/keeper/hooks.go new file mode 100644 index 000000000..d3c3cfdf3 --- /dev/null +++ b/x/evm/keeper/hooks.go @@ -0,0 +1,21 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + abci "github.com/cometbft/cometbft/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// BeginBlock sets the sdk Context and EIP155 chain id to the Keeper. +func (k *Keeper) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + // TODO: feat(evm): impl BeginBlock +} + +// EndBlock also retrieves the bloom filter value from the transient store and commits it to the +// KVStore. The EVM end block logic doesn't update the validator set, thus it returns +// an empty slice. +func (k *Keeper) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + // TODO: feat(evm): impl EndBlock + return []abci.ValidatorUpdate{} +} diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go new file mode 100644 index 000000000..3d64d8e19 --- /dev/null +++ b/x/evm/keeper/keeper.go @@ -0,0 +1,36 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + // "github.com/NibiruChain/nibiru/x/evm" + "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type Keeper struct { + cdc codec.BinaryCodec + // storeKey: For persistent storage of EVM state. + storeKey storetypes.StoreKey + // transientKey: Store key that resets every block during Commit + transientKey storetypes.StoreKey + + // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. + authority sdk.AccAddress +} + +func NewKeeper( + cdc codec.BinaryCodec, + storeKey, transientKey storetypes.StoreKey, + authority sdk.AccAddress, +) Keeper { + if err := sdk.VerifyAddressFormat(authority); err != nil { + panic(err) + } + return Keeper{ + cdc: cdc, + storeKey: storeKey, + transientKey: transientKey, + authority: authority, + } +} diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go new file mode 100644 index 000000000..3a0460ea3 --- /dev/null +++ b/x/evm/keeper/keeper_test.go @@ -0,0 +1,99 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" + + "github.com/NibiruChain/nibiru/x/common" + "github.com/NibiruChain/nibiru/x/common/testutil/testapp" +) + +type KeeperSuite struct { + suite.Suite +} + +// TestKeeperSuite: Runs all of the tests in the suite. +func TestKeeperSuite(t *testing.T) { + s := new(KeeperSuite) + suite.Run(t, s) +} + +func (s *KeeperSuite) TestMsgServer() { + chain, ctx := testapp.NewNibiruTestAppAndContext() + goCtx := sdk.WrapSDKContext(ctx) + k := chain.EvmKeeper + for _, testCase := range []func() error{ + func() error { + _, err := k.EthereumTx(goCtx, nil) + return err + }, + func() error { + _, err := k.UpdateParams(goCtx, nil) + return err + }, + } { + err := testCase() + s.Require().ErrorContains(err, common.ErrNotImplemented().Error()) + } +} + +func (s *KeeperSuite) TestQuerier() { + chain, ctx := testapp.NewNibiruTestAppAndContext() + goCtx := sdk.WrapSDKContext(ctx) + k := chain.EvmKeeper + for _, testCase := range []func() error{ + func() error { + _, err := k.Account(goCtx, nil) + return err + }, + func() error { + _, err := k.CosmosAccount(goCtx, nil) + return err + }, + func() error { + _, err := k.ValidatorAccount(goCtx, nil) + return err + }, + func() error { + _, err := k.Balance(goCtx, nil) + return err + }, + func() error { + _, err := k.BaseFee(goCtx, nil) + return err + }, + func() error { + _, err := k.Storage(goCtx, nil) + return err + }, + func() error { + _, err := k.Code(goCtx, nil) + return err + }, + func() error { + _, err := k.Params(goCtx, nil) + return err + }, + func() error { + _, err := k.EthCall(goCtx, nil) + return err + }, + func() error { + _, err := k.EstimateGas(goCtx, nil) + return err + }, + func() error { + _, err := k.TraceTx(goCtx, nil) + return err + }, + func() error { + _, err := k.TraceBlock(goCtx, nil) + return err + }, + } { + err := testCase() + s.Require().ErrorContains(err, common.ErrNotImplemented().Error()) + } +} diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go new file mode 100644 index 000000000..ec94c9e4a --- /dev/null +++ b/x/evm/keeper/msg_server.go @@ -0,0 +1,25 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + "context" + + "github.com/NibiruChain/nibiru/x/common" + "github.com/NibiruChain/nibiru/x/evm" +) + +var _ evm.MsgServer = &Keeper{} + +func (k *Keeper) EthereumTx( + goCtx context.Context, msg *evm.MsgEthereumTx, +) (resp *evm.MsgEthereumTxResponse, err error) { + // TODO: feat(evm): EthereumTx impl + return resp, common.ErrNotImplemented() +} + +func (k *Keeper) UpdateParams( + goCtx context.Context, msg *evm.MsgUpdateParams, +) (resp *evm.MsgUpdateParamsResponse, err error) { + // TODO: feat(evm): UpdateParams impl + return resp, common.ErrNotImplemented() +} From 0dbba9e179a10dc9cc1fb8892cce563c41def9e1 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Mon, 13 May 2024 11:12:42 -0500 Subject: [PATCH 02/11] quicksave wip! --- app/appconst/appconst.go | 2 +- eth/chain_id.go | 14 ++--- eth/chain_id_test.go | 102 ++++++++++++++++++++++++------------- eth/rpc/rpcapi/web3_api.go | 2 +- go.mod | 1 + x/evm/const.go | 4 +- 6 files changed, 81 insertions(+), 44 deletions(-) diff --git a/app/appconst/appconst.go b/app/appconst/appconst.go index 9e8810da4..595ba94fb 100644 --- a/app/appconst/appconst.go +++ b/app/appconst/appconst.go @@ -32,7 +32,7 @@ func init() { GoArch = runtime.GOARCH } -func Version() string { +func RuntimeVersion() string { return fmt.Sprintf( "Version %s (%s)\nCompiled at %s using Go %s (%s)", AppVersion, diff --git a/eth/chain_id.go b/eth/chain_id.go index 8ed1c920f..60dfaa880 100644 --- a/eth/chain_id.go +++ b/eth/chain_id.go @@ -6,8 +6,6 @@ import ( "math/big" "regexp" "strings" - - errorsmod "cosmossdk.io/errors" ) var ( @@ -24,7 +22,8 @@ var ( regexEpoch)) ) -// IsValidChainID returns false if the given chain identifier is incorrectly formatted. +// IsValidChainID returns false if the given chain identifier is incorrectly +// formatted. func IsValidChainID(chainID string) bool { if len(chainID) > 48 { return false @@ -39,18 +38,21 @@ func IsValidChainID(chainID string) bool { func ParseChainID(chainID string) (*big.Int, error) { chainID = strings.TrimSpace(chainID) if len(chainID) > 48 { - return nil, errorsmod.Wrapf(ErrInvalidChainID, "chain-id '%s' cannot exceed 48 chars", chainID) + return nil, ErrInvalidChainID.Wrapf( + `chain-id input "%s" cannot exceed 48 chars`, chainID) } matches := nibiruEvmChainId.FindStringSubmatch(chainID) if matches == nil || len(matches) != 4 || matches[1] == "" { - return nil, errorsmod.Wrapf(ErrInvalidChainID, "%s: %v", chainID, matches) + return nil, ErrInvalidChainID.Wrapf( + `chain-id input "%s", matches "%v"`, chainID, matches) } // verify that the chain-id entered is a base 10 integer chainIDInt, ok := new(big.Int).SetString(matches[2], 10) if !ok { - return nil, errorsmod.Wrapf(ErrInvalidChainID, "epoch %s must be base-10 integer format", matches[2]) + return nil, ErrInvalidChainID.Wrapf( + `epoch "%s" must be base-10 integer format`, matches[2]) } return chainIDInt, nil diff --git a/eth/chain_id_test.go b/eth/chain_id_test.go index 5fe4989f9..ccddc17f2 100644 --- a/eth/chain_id_test.go +++ b/eth/chain_id_test.go @@ -5,86 +5,120 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestParseChainID(t *testing.T) { +func TestParseChainID_Happy(t *testing.T) { testCases := []struct { - name string - chainID string - expError bool - expInt *big.Int + name string + chainID string + expInt *big.Int }{ { - "valid chain-id, single digit", "nibiru_1-1", false, big.NewInt(1), + chainID: "nibiru_1-1", + name: "valid chain-id, single digit", + expInt: big.NewInt(1), }, { - "valid chain-id, multiple digits", "aragonchain_256-1", false, big.NewInt(256), + chainID: "aragonchain_256-1", + name: "valid chain-id, multiple digits", + expInt: big.NewInt(256), }, + } + + for _, tc := range testCases { + chainIDEpoch, err := ParseChainID(tc.chainID) + require.NoError(t, err, tc.name) + var errMsg string = "" + if err != nil { + errMsg = err.Error() + } + assert.NoError(t, err, tc.name, errMsg) + require.Equal(t, tc.expInt, chainIDEpoch, tc.name) + require.True(t, IsValidChainID(tc.chainID)) + } +} + +func TestParseChainID_Sad(t *testing.T) { + testCases := []struct { + name string + chainID string + }{ { - "invalid chain-id, double dash", "aragonchain-1-1", true, nil, + chainID: "aragonchain-1-1", + name: "invalid chain-id, double dash", }, { - "invalid chain-id, double underscore", "aragonchain_1_1", true, nil, + chainID: "aragonchain_1_1", + name: "invalid chain-id, double underscore", }, { - "invalid chain-id, dash only", "-", true, nil, + chainID: "-", + name: "invalid chain-id, dash only", }, { - "invalid chain-id, undefined identifier and EIP155", "-1", true, nil, + chainID: "-1", + name: "invalid chain-id, undefined identifier and EIP155", }, { - "invalid chain-id, undefined identifier", "_1-1", true, nil, + chainID: "_1-1", + name: "invalid chain-id, undefined identifier", }, { - "invalid chain-id, uppercases", "NIBIRU_1-1", true, nil, + chainID: "NIBIRU_1-1", + name: "invalid chain-id, uppercases", }, { - "invalid chain-id, mixed cases", "Nibiru_1-1", true, nil, + chainID: "Nibiru_1-1", + name: "invalid chain-id, mixed cases", }, { - "invalid chain-id, special chars", "$&*#!_1-1", true, nil, + chainID: "$&*#!_1-1", + name: "invalid chain-id, special chars", }, { - "invalid eip155 chain-id, cannot start with 0", "nibiru_001-1", true, nil, + chainID: "nibiru_001-1", + name: "invalid eip155 chain-id, cannot start with 0", }, { - "invalid eip155 chain-id, cannot invalid base", "nibiru_0x212-1", true, nil, + chainID: "nibiru_0x212-1", + name: "invalid eip155 chain-id, cannot invalid base", }, { - "invalid eip155 chain-id, cannot invalid base", "nibiru_1-0x212", true, nil, + chainID: "nibiru_1-0x212", + name: "invalid eip155 chain-id, cannot invalid base", }, { - "invalid eip155 chain-id, non-integer", "nibiru_nibiru_9000-1", true, nil, + chainID: "nibiru_nibiru_9000-1", + name: "invalid eip155 chain-id, non-integer", }, { - "invalid epoch, undefined", "nibiru_-", true, nil, + chainID: "nibiru_-", + name: "invalid epoch, undefined", }, { - "blank chain ID", " ", true, nil, + chainID: " ", + name: "blank chain ID", }, { - "empty chain ID", "", true, nil, + chainID: "", + name: "empty chain ID", }, { - "empty content for chain id, eip155 and epoch numbers", "_-", true, nil, + chainID: "_-", + name: "empty content for chain id, eip155 and epoch numbers", }, { - "long chain-id", "nibiru_" + strings.Repeat("1", 45) + "-1", true, nil, + chainID: "nibiru_" + strings.Repeat("1", 45) + "-1", + name: "long chain-id", }, } for _, tc := range testCases { chainIDEpoch, err := ParseChainID(tc.chainID) - if tc.expError { - require.Error(t, err, tc.name) - require.Nil(t, chainIDEpoch) - - require.False(t, IsValidChainID(tc.chainID), tc.name) - } else { - require.NoError(t, err, tc.name) - require.Equal(t, tc.expInt, chainIDEpoch, tc.name) - require.True(t, IsValidChainID(tc.chainID)) - } + require.Error(t, err, tc.name) + require.Nil(t, chainIDEpoch) + require.False(t, IsValidChainID(tc.chainID), tc.name) } } diff --git a/eth/rpc/rpcapi/web3_api.go b/eth/rpc/rpcapi/web3_api.go index 1a2c521d6..1cdc3030b 100644 --- a/eth/rpc/rpcapi/web3_api.go +++ b/eth/rpc/rpcapi/web3_api.go @@ -18,7 +18,7 @@ func NewImplWeb3API() *APIWeb3 { // ClientVersion returns the client version in the Web3 user agent format. func (a *APIWeb3) ClientVersion() string { - return appconst.Version() + return appconst.RuntimeVersion() } // Sha3 returns the keccak-256 hash of the passed-in input. diff --git a/go.mod b/go.mod index 1e2344fdc..e0ac4b572 100644 --- a/go.mod +++ b/go.mod @@ -235,4 +235,5 @@ replace ( // pin version! 126854af5e6d has issues with the store so that queries fail github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/NibiruChain/collections => ../nibi-collections ) diff --git a/x/evm/const.go b/x/evm/const.go index ee7ba2230..55c9f06bf 100644 --- a/x/evm/const.go +++ b/x/evm/const.go @@ -10,8 +10,8 @@ const ( // ModuleName string name of module ModuleName = "evm" - // StoreKey: Persistent storage key for ethereum storage data, account code (StateDB) or block - // related data for the Eth Web3 API. + // StoreKey: Persistent storage key for ethereum storage data, account code + // (StateDB) or block related data for the Eth Web3 API. StoreKey = ModuleName // TransientKey is the key to access the EVM transient store, that is reset From 0c5cffb0096246bda0af083138bc8efb133aaa4f Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 10:53:46 -0500 Subject: [PATCH 03/11] chore(deps): use collections v0.5 --- go.mod | 2 +- go.sum | 4 +- x/common/error.go | 2 +- x/evm/const.go | 20 ++----- x/evm/evmmodule/genesis.go | 2 + x/evm/keeper/evm_state.go | 87 +++++++++++++++++++++++++++++ x/evm/keeper/keeper.go | 3 + x/tokenfactory/keeper/msg_server.go | 2 +- 8 files changed, 103 insertions(+), 19 deletions(-) create mode 100644 x/evm/keeper/evm_state.go diff --git a/go.mod b/go.mod index 1e2344fdc..d9081cc22 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/CosmWasm/wasmd v0.44.0 github.com/CosmWasm/wasmvm v1.5.0 github.com/MakeNowJust/heredoc/v2 v2.0.1 - github.com/NibiruChain/collections v0.4.0 + github.com/NibiruChain/collections v0.5.0 github.com/armon/go-metrics v0.4.1 // EVM-specific deps diff --git a/go.sum b/go.sum index 6834666e6..2a4764b74 100644 --- a/go.sum +++ b/go.sum @@ -238,8 +238,8 @@ github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZ github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= -github.com/NibiruChain/collections v0.4.0 h1:KNJj+CJyqOT/Q33kcVzT2uLYIiwhiFAeZMhGLPge5Og= -github.com/NibiruChain/collections v0.4.0/go.mod h1:tKTlBL+Cs1oJnS4tT9MIaFWr7BWsUXrc7KPzP1LxRBo= +github.com/NibiruChain/collections v0.5.0 h1:33pXpVTe1PK/tfdZlAJF1JF7AdzGNARG+iL9G/z3X7k= +github.com/NibiruChain/collections v0.5.0/go.mod h1:43L6yjuF0BMre/mw4gqn/kUOZz1c2Y3huZ/RQfBFrOQ= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= diff --git a/x/common/error.go b/x/common/error.go index 4fa0a171f..2f640ce50 100644 --- a/x/common/error.go +++ b/x/common/error.go @@ -184,7 +184,7 @@ func CombineErrorsFromStrings(strs ...string) (err error) { return CombineErrors(errs...) } -func ErrNilMsg() error { +func ErrNilGrpcMsg() error { return grpcstatus.Errorf(grpccodes.InvalidArgument, "nil msg") } diff --git a/x/evm/const.go b/x/evm/const.go index ee7ba2230..792e34f74 100644 --- a/x/evm/const.go +++ b/x/evm/const.go @@ -30,27 +30,19 @@ const ( KeyPrefixEthAddrIndex ) -// prefix bytes for the EVM transient store +// KVStore transient prefix namespaces for the EVM Module. Transient stores only +// remain for current block, and have more gas efficient read and write access. const ( - prefixTransientBloom collections.Namespace = iota + 1 - prefixTransientTxIndex - prefixTransientLogSize - prefixTransientGasUsed + NamespaceBlockBloom collections.Namespace = iota + 1 + NamespaceBlockTxIndex + NamespaceBlockLogSize + NamespaceBlockGasUsed ) -// KVStore key prefixes var ( KeyPrefixBzAccState = KeyPrefixAccState.Prefix() ) -// Transient Store key prefixes -var ( - KeyPrefixTransientBloom = prefixTransientBloom.Prefix() - KeyPrefixTransientTxIndex = prefixTransientTxIndex.Prefix() - KeyPrefixTransientLogSize = prefixTransientLogSize.Prefix() - KeyPrefixTransientGasUsed = prefixTransientGasUsed.Prefix() -) - // PrefixAccStateEthAddr returns a prefix to iterate over a given account storage. func PrefixAccStateEthAddr(address common.Address) []byte { return append(KeyPrefixBzAccState, address.Bytes()...) diff --git a/x/evm/evmmodule/genesis.go b/x/evm/evmmodule/genesis.go index 2ad0ee06a..8f146110d 100644 --- a/x/evm/evmmodule/genesis.go +++ b/x/evm/evmmodule/genesis.go @@ -16,6 +16,8 @@ func InitGenesis( accountKeeper evm.AccountKeeper, data evm.GenesisState, ) []abci.ValidatorUpdate { + k.BeginBlock(ctx, abci.RequestBeginBlock{}) + k.EvmState.ModuleParams.Set(ctx, data.Params) // TODO: impl InitGenesis return []abci.ValidatorUpdate{} } diff --git a/x/evm/keeper/evm_state.go b/x/evm/keeper/evm_state.go new file mode 100644 index 000000000..9fb7e009c --- /dev/null +++ b/x/evm/keeper/evm_state.go @@ -0,0 +1,87 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + "github.com/NibiruChain/collections" + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/evm" + "github.com/cosmos/cosmos-sdk/codec" + sdkstore "github.com/cosmos/cosmos-sdk/store/types" + gethcommon "github.com/ethereum/go-ethereum/common" +) + +type AccStatePrimaryKey = collections.Pair[gethcommon.Address, gethcommon.Hash] +type CodeHash = []byte + +// EvmState isolates the key-value stores (collections) for the x/evm module. +type EvmState struct { + ModuleParams collections.Item[evm.Params] + + // ContractBytecode: Map from (byte)code hash -> contract bytecode + ContractBytecode collections.Map[CodeHash, []byte] + + // AccState: Map from eth address (account) and hash of a state key -> smart + // contract state. Each contract essentially has its own key-value store. + // + // - primary key (PK): (EthAddr+EthHash). The contract is the primary key + // because there's exactly one deployer and withdrawer. + // - value (V): State value bytes. + AccState collections.Map[ + AccStatePrimaryKey, // account (EthAddr) + state key (EthHash) + []byte, + ] + + // BlockGasUsed: Gas used by Ethereum txs in the block (transient). + BlockGasUsed collections.ItemTransient[uint64] + // BlockLogSize: EVM tx log size for the block (transient). + BlockLogSize collections.ItemTransient[uint64] + // BlockTxIndex: EVM tx index for the block (transient). + BlockTxIndex collections.ItemTransient[uint64] + // BlockBloom: Bloom filters. + BlockBloom collections.ItemTransient[[]byte] +} + +func (k *Keeper) EVMState() EvmState { return k.EvmState } + +func NewEvmState( + cdc codec.BinaryCodec, + storeKey sdkstore.StoreKey, + storeKeyTransient sdkstore.StoreKey, +) EvmState { + return EvmState{ + ModuleParams: collections.NewItem( + storeKey, evm.KeyPrefixParams, + collections.ProtoValueEncoder[evm.Params](cdc), + ), + ContractBytecode: collections.NewMap( + storeKey, evm.KeyPrefixAccCodes, + eth.KeyEncoderBytes, + eth.ValueEncoderBytes, + ), + AccState: collections.NewMap( + storeKey, evm.KeyPrefixAccState, + collections.PairKeyEncoder(eth.KeyEncoderEthAddr, eth.KeyEncoderEthHash), + eth.ValueEncoderBytes, + ), + BlockGasUsed: collections.NewItemTransient( + storeKeyTransient, + evm.NamespaceBlockGasUsed, + collections.Uint64ValueEncoder, + ), + BlockLogSize: collections.NewItemTransient( + storeKeyTransient, + evm.NamespaceBlockLogSize, + collections.Uint64ValueEncoder, + ), + BlockBloom: collections.NewItemTransient( + storeKeyTransient, + evm.NamespaceBlockBloom, + eth.ValueEncoderBytes, + ), + BlockTxIndex: collections.NewItemTransient( + storeKeyTransient, + evm.NamespaceBlockTxIndex, + collections.Uint64ValueEncoder, + ), + } +} diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 3d64d8e19..9c5a81719 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -15,6 +15,9 @@ type Keeper struct { // transientKey: Store key that resets every block during Commit transientKey storetypes.StoreKey + // EvmState isolates the key-value stores (collections) for the x/evm module. + EvmState EvmState + // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. authority sdk.AccAddress } diff --git a/x/tokenfactory/keeper/msg_server.go b/x/tokenfactory/keeper/msg_server.go index e804d6fa1..5a56b5c50 100644 --- a/x/tokenfactory/keeper/msg_server.go +++ b/x/tokenfactory/keeper/msg_server.go @@ -13,7 +13,7 @@ import ( var _ types.MsgServer = (*Keeper)(nil) -var errNilMsg error = common.ErrNilMsg() +var errNilMsg error = common.ErrNilGrpcMsg() func (k Keeper) CreateDenom( goCtx context.Context, txMsg *types.MsgCreateDenom, From fc5f463cbd2525a2bf91a53bdd877f0debdbe5de Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 10:55:30 -0500 Subject: [PATCH 04/11] eth: query type validation --- x/evm/keeper/keeper.go | 1 + x/evm/query.go | 138 +++++++++++++++++++++++++++++++++++++++++ x/evm/query_test.go | 58 +++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 x/evm/query.go create mode 100644 x/evm/query_test.go diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 9c5a81719..f0c34f6ab 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -35,5 +35,6 @@ func NewKeeper( storeKey: storeKey, transientKey: transientKey, authority: authority, + EvmState: NewEvmState(cdc, storeKey, transientKey), } } diff --git a/x/evm/query.go b/x/evm/query.go new file mode 100644 index 000000000..0b80e94e5 --- /dev/null +++ b/x/evm/query.go @@ -0,0 +1,138 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package evm + +import ( + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/common" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (m QueryTraceTxRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + for _, msg := range m.Predecessors { + if err := msg.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return m.Msg.UnpackInterfaces(unpacker) +} + +func (m QueryTraceBlockRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { + for _, msg := range m.Txs { + if err := msg.UnpackInterfaces(unpacker); err != nil { + return err + } + } + return nil +} + +func (req *QueryAccountRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + if err := eth.ValidateAddress(req.Address); err != nil { + return status.Error( + codes.InvalidArgument, err.Error(), + ) + } + return nil +} + +func (req *QueryCosmosAccountRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + + if err := eth.ValidateAddress(req.Address); err != nil { + return status.Error( + codes.InvalidArgument, err.Error(), + ) + } + return nil +} + +func (req *QueryValidatorAccountRequest) Validate() ( + consAddr sdk.ConsAddress, err error, +) { + if req == nil { + return consAddr, status.Error(codes.InvalidArgument, "empty request") + } + + consAddr, err = sdk.ConsAddressFromBech32(req.ConsAddress) + if err != nil { + return consAddr, status.Error( + codes.InvalidArgument, err.Error(), + ) + } + return consAddr, nil +} +func (req *QueryBalanceRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + + if err := eth.ValidateAddress(req.Address); err != nil { + return status.Error( + codes.InvalidArgument, + ErrZeroAddress.Error(), + ) + } + return nil +} +func (req *QueryStorageRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + if err := eth.ValidateAddress(req.Address); err != nil { + return status.Error( + codes.InvalidArgument, + ErrZeroAddress.Error(), + ) + } + return nil +} + +func (req *QueryCodeRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + + if err := eth.ValidateAddress(req.Address); err != nil { + return status.Error( + codes.InvalidArgument, + ErrZeroAddress.Error(), + ) + } + return nil +} + +func (req *EthCallRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + return nil +} + +func (req *QueryTraceTxRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + + if req.TraceConfig != nil && req.TraceConfig.Limit < 0 { + return status.Errorf(codes.InvalidArgument, "output limit cannot be negative, got %d", req.TraceConfig.Limit) + } + return nil +} + +func (req *QueryTraceBlockRequest) Validate() error { + if req == nil { + return common.ErrNilGrpcMsg() + } + + if req.TraceConfig != nil && req.TraceConfig.Limit < 0 { + return status.Errorf(codes.InvalidArgument, "output limit cannot be negative, got %d", req.TraceConfig.Limit) + } + return nil +} diff --git a/x/evm/query_test.go b/x/evm/query_test.go new file mode 100644 index 000000000..0c0d9debe --- /dev/null +++ b/x/evm/query_test.go @@ -0,0 +1,58 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package evm + +import ( + "github.com/NibiruChain/nibiru/x/common" + "github.com/stretchr/testify/suite" +) + +type TestSuite struct { + suite.Suite +} + +// TestNilQueries: Checks that all expected sad paths for nil msgs error +func (s *TestSuite) TestNilQueries() { + + for _, testCase := range []func() error{ + func() error { + var req *QueryAccountRequest = nil + return req.Validate() + }, + func() error { + var req *QueryCosmosAccountRequest = nil + return req.Validate() + }, + func() error { + var req *QueryValidatorAccountRequest = nil + _, err := req.Validate() + return err + }, + func() error { + var req *QueryBalanceRequest = nil + return req.Validate() + }, + func() error { + var req *QueryStorageRequest = nil + return req.Validate() + }, + func() error { + var req *QueryCodeRequest = nil + return req.Validate() + }, + func() error { + var req *EthCallRequest = nil + return req.Validate() + }, + func() error { + var req *QueryTraceTxRequest = nil + return req.Validate() + }, + func() error { + var req *QueryTraceBlockRequest = nil + return req.Validate() + }, + } { + err := testCase() + s.Require().ErrorContains(err, common.ErrNilGrpcMsg().Error()) + } +} From 289b1d7ebe1c6c1f00821e0bcc940c66bfed4f69 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 11:30:15 -0500 Subject: [PATCH 05/11] fix(deps): remove local collections replace statement --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index fa77841d3..d9081cc22 100644 --- a/go.mod +++ b/go.mod @@ -235,5 +235,4 @@ replace ( // pin version! 126854af5e6d has issues with the store so that queries fail github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/NibiruChain/collections => ../nibi-collections ) From f874b87930beaa4094f549d24f9da99c51d99795 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 11:54:19 -0500 Subject: [PATCH 06/11] query Balance --- x/evm/keeper/grpc_query.go | 12 +++++++++--- x/evm/keeper/keeper.go | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index b8850d963..f9dc9a1ac 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -8,6 +8,8 @@ import ( "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/evm" + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" ) // Compile-time interface assertion @@ -88,10 +90,14 @@ func (k Keeper) ValidatorAccount( // - A pointer to the QueryBalanceResponse object containing the balance. // - An error if the balance retrieval process encounters any issues. func (k Keeper) Balance(goCtx context.Context, req *evm.QueryBalanceRequest) (*evm.QueryBalanceResponse, error) { - // TODO: feat(evm): impl query Balance + if err := req.Validate(); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) + balanceInt := k.GetEvmGasBalance(ctx, gethcommon.HexToAddress(req.Address)) return &evm.QueryBalanceResponse{ - Balance: "", - }, common.ErrNotImplementedGprc() + Balance: balanceInt.String(), + }, nil } // BaseFee implements the Query/BaseFee gRPC method diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index f0c34f6ab..739c9e78c 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -3,9 +3,13 @@ package keeper import ( // "github.com/NibiruChain/nibiru/x/evm" + "math/big" + + "github.com/NibiruChain/nibiru/x/evm" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" ) type Keeper struct { @@ -20,6 +24,8 @@ type Keeper struct { // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. authority sdk.AccAddress + + bankKeeper evm.BankKeeper } func NewKeeper( @@ -38,3 +44,24 @@ func NewKeeper( EvmState: NewEvmState(cdc, storeKey, transientKey), } } + +// GetEvmGasBalance: Implements `evm.EVMKeeper` from +// "github.com/NibiruChain/nibiru/app/ante/evm": Load account's balance of gas +// tokens for EVM execution +func (k *Keeper) GetEvmGasBalance(ctx sdk.Context, addr gethcommon.Address) *big.Int { + cosmosAddr := sdk.AccAddress(addr.Bytes()) + evmParams := k.GetParams(ctx) + evmDenom := evmParams.GetEvmDenom() + // if node is pruned, params is empty. Return invalid value + if evmDenom == "" { + return big.NewInt(-1) + } + coin := k.bankKeeper.GetBalance(ctx, cosmosAddr, evmDenom) + return coin.Amount.BigInt() +} + +// GetParams returns the total set of evm parameters. +func (k Keeper) GetParams(ctx sdk.Context) (params evm.Params) { + params, _ = k.EvmState.ModuleParams.Get(ctx) + return params +} From 69865eccaa6bad0be99abbd2bcfd4178e49ff281 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 12:01:32 -0500 Subject: [PATCH 07/11] linter + changelog --- CHANGELOG.md | 1 + x/evm/keeper/evm_state.go | 5 +++-- x/evm/keeper/grpc_query.go | 5 +++-- x/evm/keeper/keeper.go | 3 ++- x/evm/query.go | 5 +++-- x/evm/query_test.go | 4 ++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b75a5d237..f9c77970d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1856](https://github.com/NibiruChain/nibiru/pull/1856) - feat(eth-rpc): Conversion types and functions between Ethereum txs and blocks and Tendermint ones. - [#1861](https://github.com/NibiruChain/nibiru/pull/1861) - feat(eth-rpc): RPC backend, Ethereum tracer, KV indexer, and RPC APIs - [#1869](https://github.com/NibiruChain/nibiru/pull/1869) - feat(eth): Module and start of keeper tests +- [#1873](https://github.com/NibiruChain/nibiru/pull/1873) - feat(evm): keeper grpc query impls and collection start #### Dapp modules: perp, spot, oracle, etc diff --git a/x/evm/keeper/evm_state.go b/x/evm/keeper/evm_state.go index 9fb7e009c..862323fd1 100644 --- a/x/evm/keeper/evm_state.go +++ b/x/evm/keeper/evm_state.go @@ -3,11 +3,12 @@ package keeper import ( "github.com/NibiruChain/collections" - "github.com/NibiruChain/nibiru/eth" - "github.com/NibiruChain/nibiru/x/evm" "github.com/cosmos/cosmos-sdk/codec" sdkstore "github.com/cosmos/cosmos-sdk/store/types" gethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/evm" ) type AccStatePrimaryKey = collections.Pair[gethcommon.Address, gethcommon.Hash] diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index f9dc9a1ac..d259f8cad 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -6,10 +6,11 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/NibiruChain/nibiru/x/common" - "github.com/NibiruChain/nibiru/x/evm" sdk "github.com/cosmos/cosmos-sdk/types" gethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/NibiruChain/nibiru/x/common" + "github.com/NibiruChain/nibiru/x/evm" ) // Compile-time interface assertion diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 739c9e78c..09c38ae19 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -5,11 +5,12 @@ import ( // "github.com/NibiruChain/nibiru/x/evm" "math/big" - "github.com/NibiruChain/nibiru/x/evm" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" gethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/NibiruChain/nibiru/x/evm" ) type Keeper struct { diff --git a/x/evm/query.go b/x/evm/query.go index 0b80e94e5..f04cc4d14 100644 --- a/x/evm/query.go +++ b/x/evm/query.go @@ -2,12 +2,13 @@ package evm import ( - "github.com/NibiruChain/nibiru/eth" - "github.com/NibiruChain/nibiru/x/common" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/common" ) func (m QueryTraceTxRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { diff --git a/x/evm/query_test.go b/x/evm/query_test.go index 0c0d9debe..cadcd5818 100644 --- a/x/evm/query_test.go +++ b/x/evm/query_test.go @@ -2,8 +2,9 @@ package evm import ( - "github.com/NibiruChain/nibiru/x/common" "github.com/stretchr/testify/suite" + + "github.com/NibiruChain/nibiru/x/common" ) type TestSuite struct { @@ -12,7 +13,6 @@ type TestSuite struct { // TestNilQueries: Checks that all expected sad paths for nil msgs error func (s *TestSuite) TestNilQueries() { - for _, testCase := range []func() error{ func() error { var req *QueryAccountRequest = nil From 7d96d1c8af181f4a171e12ada4b4e8829e918e59 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 12:14:54 -0500 Subject: [PATCH 08/11] fix test --- x/evm/keeper/keeper_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index 3a0460ea3..a9c4ede8e 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -56,10 +56,6 @@ func (s *KeeperSuite) TestQuerier() { _, err := k.ValidatorAccount(goCtx, nil) return err }, - func() error { - _, err := k.Balance(goCtx, nil) - return err - }, func() error { _, err := k.BaseFee(goCtx, nil) return err From 5187d0f8266d0066409d11c2d7f4b246c7b0a66d Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 23:14:52 -0500 Subject: [PATCH 09/11] test(evm): QueryEthAccount tests --- CHANGELOG.md | 2 - app/ante.go | 47 +- app/ante/fixed_gas_test.go | 2 +- app/ante/testutil_test.go | 2 +- app/app.go | 2 +- app/codec/codec.go | 4 +- app/ibc_test.go | 2 +- app/keepers.go | 8 +- app/modules_test.go | 10 +- cmd/nibid/cmd/decode_base64_test.go | 2 +- cmd/nibid/cmd/genaccounts_test.go | 2 +- cmd/nibid/cmd/root.go | 2 +- cmd/nibid/cmd/testnet_test.go | 6 +- eth/codec.go | 6 + eth/codec_test.go | 4 +- eth/encoding/config.go | 2 +- eth/eth_account.go | 84 ++++ eth/indexer/kv_indexer_test.go | 3 +- eth/rpc/backend/account_info.go | 4 +- eth/rpc/backend/evm_query_client_test.go | 4 +- eth/rpc/backend/mocks/evm_query_client.go | 24 +- proto/eth/evm/v1/query.proto | 34 +- proto/nibiru/perp/v2/event.proto | 262 ----------- proto/nibiru/perp/v2/genesis.proto | 102 ----- proto/nibiru/perp/v2/query.proto | 163 ------- proto/nibiru/perp/v2/state.proto | 250 ----------- proto/nibiru/perp/v2/tx.proto | 472 -------------------- proto/nibiru/spot/v1/event.proto | 86 ---- proto/nibiru/spot/v1/genesis.proto | 18 - proto/nibiru/spot/v1/params.proto | 27 -- proto/nibiru/spot/v1/pool.proto | 97 ---- proto/nibiru/spot/v1/query.proto | 282 ------------ proto/nibiru/spot/v1/tx.proto | 120 ----- x/common/testutil/cli/network.go | 2 +- x/common/testutil/cli/network_test.go | 2 +- x/common/testutil/cli/util.go | 2 +- x/common/testutil/genesis/genesis.go | 2 +- x/common/testutil/genesis/oracle_genesis.go | 2 +- x/common/testutil/genesis/sudo_genesis.go | 2 +- x/common/testutil/testapp/testapp.go | 12 +- x/epochs/genesis_test.go | 2 +- x/evm/codec.go | 6 + x/evm/evmmodule/genesis.go | 50 ++- x/evm/evmmodule/module.go | 2 + x/evm/evmtest/eth.go | 21 +- x/evm/keeper/evm_state.go | 57 +++ x/evm/keeper/grpc_query.go | 109 +++-- x/evm/keeper/grpc_query_test.go | 192 ++++++++ x/evm/keeper/keeper.go | 23 +- x/evm/keeper/keeper_test.go | 16 - x/evm/keeper/statedb.go | 77 ++++ x/evm/msg.go | 3 + x/evm/query.go | 4 +- x/evm/query.pb.go | 466 +++++++++---------- x/evm/query.pb.gw.go | 56 +-- x/evm/query_test.go | 4 +- x/evm/statedb/interfaces.go | 15 +- x/genmsg/integration_test.go | 6 +- x/oracle/types/genesis_test.go | 2 +- x/sudo/cli/cli_test.go | 2 +- x/tokenfactory/keeper/wasm_test.go | 4 +- 61 files changed, 958 insertions(+), 2318 deletions(-) create mode 100644 eth/eth_account.go delete mode 100644 proto/nibiru/perp/v2/event.proto delete mode 100644 proto/nibiru/perp/v2/genesis.proto delete mode 100644 proto/nibiru/perp/v2/query.proto delete mode 100644 proto/nibiru/perp/v2/state.proto delete mode 100644 proto/nibiru/perp/v2/tx.proto delete mode 100644 proto/nibiru/spot/v1/event.proto delete mode 100644 proto/nibiru/spot/v1/genesis.proto delete mode 100644 proto/nibiru/spot/v1/params.proto delete mode 100644 proto/nibiru/spot/v1/pool.proto delete mode 100644 proto/nibiru/spot/v1/query.proto delete mode 100644 proto/nibiru/spot/v1/tx.proto create mode 100644 x/evm/keeper/grpc_query_test.go create mode 100644 x/evm/keeper/statedb.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 1313229a5..86be6cd09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,10 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1855](https://github.com/NibiruChain/nibiru/pull/1855) - feat(eth-pubsub): Implement in-memory EventBus for real-time topic management and event distribution - [#1856](https://github.com/NibiruChain/nibiru/pull/1856) - feat(eth-rpc): Conversion types and functions between Ethereum txs and blocks and Tendermint ones. - [#1861](https://github.com/NibiruChain/nibiru/pull/1861) - feat(eth-rpc): RPC backend, Ethereum tracer, KV indexer, and RPC APIs -<<<<<<< HEAD - [#1869](https://github.com/NibiruChain/nibiru/pull/1869) - feat(eth): Module and start of keeper tests - [#1873](https://github.com/NibiruChain/nibiru/pull/1873) - feat(evm): keeper grpc query impls and collection start -- [#1869](https://github.com/NibiruChain/nibiru/pull/1869) - feat(eth): Module and start of keeper tests #### Dapp modules: perp, spot, oracle, etc diff --git a/app/ante.go b/app/ante.go index a4d4a7861..a0d70a1bc 100644 --- a/app/ante.go +++ b/app/ante.go @@ -30,26 +30,8 @@ type AnteHandlerOptions struct { // numbers, checks signatures and account numbers, and deducts fees from the // first signer. func NewAnteHandler(options AnteHandlerOptions) (sdk.AnteHandler, error) { - if options.AccountKeeper == nil { - return nil, AnteHandlerError("account keeper") - } - if options.BankKeeper == nil { - return nil, AnteHandlerError("bank keeper") - } - if options.SignModeHandler == nil { - return nil, AnteHandlerError("sign mode handler") - } - if options.SigGasConsumer == nil { - options.SigGasConsumer = sdkante.DefaultSigVerificationGasConsumer - } - if options.WasmConfig == nil { - return nil, AnteHandlerError("wasm config") - } - if options.DevGasKeeper == nil { - return nil, AnteHandlerError("devgas keeper") - } - if options.IBCKeeper == nil { - return nil, AnteHandlerError("ibc keeper") + if err := options.ValidateAndClean(); err != nil { + return nil, err } anteDecorators := []sdk.AnteDecorator{ @@ -80,6 +62,31 @@ func NewAnteHandler(options AnteHandlerOptions) (sdk.AnteHandler, error) { return sdk.ChainAnteDecorators(anteDecorators...), nil } +func (opts *AnteHandlerOptions) ValidateAndClean() error { + if opts.AccountKeeper == nil { + return AnteHandlerError("account keeper") + } + if opts.BankKeeper == nil { + return AnteHandlerError("bank keeper") + } + if opts.SignModeHandler == nil { + return AnteHandlerError("sign mode handler") + } + if opts.SigGasConsumer == nil { + opts.SigGasConsumer = sdkante.DefaultSigVerificationGasConsumer + } + if opts.WasmConfig == nil { + return AnteHandlerError("wasm config") + } + if opts.DevGasKeeper == nil { + return AnteHandlerError("devgas keeper") + } + if opts.IBCKeeper == nil { + return AnteHandlerError("ibc keeper") + } + return nil +} + func AnteHandlerError(shortDesc string) error { return sdkerrors.Wrapf(errors.ErrLogic, "%s is required for AnteHandler", shortDesc) } diff --git a/app/ante/fixed_gas_test.go b/app/ante/fixed_gas_test.go index dac98dc74..264a66ab6 100644 --- a/app/ante/fixed_gas_test.go +++ b/app/ante/fixed_gas_test.go @@ -197,7 +197,7 @@ func (suite *AnteTestSuite) TestOraclePostPriceTransactionsHaveFixedPrice() { Amount: sdk.NewCoins(sdk.NewInt64Coin(appconst.BondDenom, 200)), }, }, - expectedGas: 62288, + expectedGas: 67193, expectedErr: nil, }, } diff --git a/app/ante/testutil_test.go b/app/ante/testutil_test.go index 9e6d50edc..071415826 100644 --- a/app/ante/testutil_test.go +++ b/app/ante/testutil_test.go @@ -39,7 +39,7 @@ func (suite *AnteTestSuite) SetupTest() { // Set up base app and ctx testapp.EnsureNibiruPrefix() encodingConfig := app.MakeEncodingConfig() - suite.app = testapp.NewNibiruTestApp(app.NewDefaultGenesisState(encodingConfig.Marshaler)) + suite.app = testapp.NewNibiruTestApp(app.NewDefaultGenesisState(encodingConfig.Codec)) chainId := "test-chain-id" ctx := suite.app.NewContext(true, tmproto.Header{ Height: 1, diff --git a/app/app.go b/app/app.go index f580830f7..8245208cf 100644 --- a/app/app.go +++ b/app/app.go @@ -130,7 +130,7 @@ func NewNibiruApp( appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp), ) *NibiruApp { - appCodec := encodingConfig.Marshaler + appCodec := encodingConfig.Codec legacyAmino := encodingConfig.Amino interfaceRegistry := encodingConfig.InterfaceRegistry txConfig := encodingConfig.TxConfig diff --git a/app/codec/codec.go b/app/codec/codec.go index 9de4fb1d6..a80f74525 100644 --- a/app/codec/codec.go +++ b/app/codec/codec.go @@ -11,7 +11,7 @@ import ( // This is provided for compatibility between protobuf and amino implementations. type EncodingConfig struct { InterfaceRegistry types.InterfaceRegistry - Marshaler codec.Codec + Codec codec.Codec TxConfig client.TxConfig Amino *codec.LegacyAmino } @@ -25,7 +25,7 @@ func MakeEncodingConfig() EncodingConfig { return EncodingConfig{ InterfaceRegistry: interfaceRegistry, - Marshaler: marshaler, + Codec: marshaler, TxConfig: txCfg, Amino: amino, } diff --git a/app/ibc_test.go b/app/ibc_test.go index 3932e09bd..5e16338c1 100644 --- a/app/ibc_test.go +++ b/app/ibc_test.go @@ -34,7 +34,7 @@ func SetupNibiruTestingApp() ( // Create genesis state encCdc := app.MakeEncodingConfig() - genesisState := app.NewDefaultGenesisState(encCdc.Marshaler) + genesisState := app.NewDefaultGenesisState(encCdc.Codec) testapp.SetDefaultSudoGenesis(genesisState) return nibiruApp, genesisState diff --git a/app/keepers.go b/app/keepers.go index dd0d2b2da..1f3b9d6cd 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -105,6 +105,7 @@ import ( // --------------------------------------------------------------- // Nibiru Custom Modules + "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/common" "github.com/NibiruChain/nibiru/x/devgas/v1" devgaskeeper "github.com/NibiruChain/nibiru/x/devgas/v1/keeper" @@ -280,11 +281,12 @@ func (app *NibiruApp) InitKeepers( // seal capability keeper after scoping modules // app.capabilityKeeper.Seal() - // add keepers + // TODO: chore(upgrade): Potential breaking change on AccountKeeper dur + // to ProtoBaseAccount replacement. app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], - authtypes.ProtoBaseAccount, + eth.ProtoBaseAccount, maccPerms, sdk.GetConfig().GetBech32AccountAddrPrefix(), govModuleAddr, @@ -396,6 +398,8 @@ func (app *NibiruApp) InitKeepers( keys[evm.StoreKey], tkeys[evm.TransientKey], authtypes.NewModuleAddress(govtypes.ModuleName), + app.AccountKeeper, + app.BankKeeper, ) // ---------------------------------- IBC keepers diff --git a/app/modules_test.go b/app/modules_test.go index b411c9289..4fe32f3ce 100644 --- a/app/modules_test.go +++ b/app/modules_test.go @@ -25,14 +25,14 @@ func (s *TestSuite) SetupSuite() { } func (s *TestSuite) DefaultGenesisCopy() app.GenesisState { - return app.NewDefaultGenesisState(s.encCfg.Marshaler) + return app.NewDefaultGenesisState(s.encCfg.Codec) } func (s *TestSuite) TestGenesis() { getDefaultStakingGenesis := func() *stakingtypes.GenesisState { genStaking := new(stakingtypes.GenesisState) - s.encCfg.Marshaler.MustUnmarshalJSON( - app.StakingModule{}.DefaultGenesis(s.encCfg.Marshaler), + s.encCfg.Codec.MustUnmarshalJSON( + app.StakingModule{}.DefaultGenesis(s.encCfg.Codec), genStaking, ) return genStaking @@ -61,9 +61,9 @@ func (s *TestSuite) TestGenesis() { }, } { s.T().Run(tc.name, func(t *testing.T) { - genStakingJson := s.encCfg.Marshaler.MustMarshalJSON(tc.gen) + genStakingJson := s.encCfg.Codec.MustMarshalJSON(tc.gen) err := app.StakingModule{}.ValidateGenesis( - s.encCfg.Marshaler, + s.encCfg.Codec, s.encCfg.TxConfig, genStakingJson, ) diff --git a/cmd/nibid/cmd/decode_base64_test.go b/cmd/nibid/cmd/decode_base64_test.go index c5e3c1e4e..5711d8cf6 100644 --- a/cmd/nibid/cmd/decode_base64_test.go +++ b/cmd/nibid/cmd/decode_base64_test.go @@ -31,7 +31,7 @@ func TestBase64Decode(t *testing.T) { cfg, err := genutiltest.CreateDefaultTendermintConfig(home) require.NoError(t, err) - appCodec := app.MakeEncodingConfig().Marshaler + appCodec := app.MakeEncodingConfig().Codec err = genutiltest.ExecInitCmd( testModuleBasicManager, home, appCodec) require.NoError(t, err) diff --git a/cmd/nibid/cmd/genaccounts_test.go b/cmd/nibid/cmd/genaccounts_test.go index 3846fc2f3..d451673bd 100644 --- a/cmd/nibid/cmd/genaccounts_test.go +++ b/cmd/nibid/cmd/genaccounts_test.go @@ -41,7 +41,7 @@ func TestAddGenesisAccountCmd(t *testing.T) { cfg, err := genutiltest.CreateDefaultTendermintConfig(home) require.NoError(t, err) - appCodec := app.MakeEncodingConfig().Marshaler + appCodec := app.MakeEncodingConfig().Codec err = genutiltest.ExecInitCmd( testModuleBasicManager, home, appCodec) require.NoError(t, err) diff --git a/cmd/nibid/cmd/root.go b/cmd/nibid/cmd/root.go index c739b9a71..52861101a 100644 --- a/cmd/nibid/cmd/root.go +++ b/cmd/nibid/cmd/root.go @@ -39,7 +39,7 @@ func NewRootCmd() (*cobra.Command, app.EncodingConfig) { app.SetPrefixes(appconst.AccountAddressPrefix) initClientCtx := client.Context{}. - WithCodec(encodingConfig.Marshaler). + WithCodec(encodingConfig.Codec). WithInterfaceRegistry(encodingConfig.InterfaceRegistry). WithTxConfig(encodingConfig.TxConfig). WithLegacyAmino(encodingConfig.Amino). diff --git a/cmd/nibid/cmd/testnet_test.go b/cmd/nibid/cmd/testnet_test.go index 2054580f9..fa2892689 100644 --- a/cmd/nibid/cmd/testnet_test.go +++ b/cmd/nibid/cmd/testnet_test.go @@ -25,12 +25,12 @@ func Test_TestnetCmd(t *testing.T) { cfg, err := genutiltest.CreateDefaultTendermintConfig(home) require.NoError(t, err) - err = genutiltest.ExecInitCmd(app.ModuleBasics, home, encodingConfig.Marshaler) + err = genutiltest.ExecInitCmd(app.ModuleBasics, home, encodingConfig.Codec) require.NoError(t, err) serverCtx := server.NewContext(viper.New(), cfg, logger) clientCtx := client.Context{}. - WithCodec(encodingConfig.Marshaler). + WithCodec(encodingConfig.Codec). WithHomeDir(home). WithTxConfig(encodingConfig.TxConfig) @@ -49,6 +49,6 @@ func Test_TestnetCmd(t *testing.T) { appState, _, err := genutiltypes.GenesisStateFromGenFile(genFile) require.NoError(t, err) - bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Marshaler, appState) + bankGenState := banktypes.GetGenesisStateFromAppState(encodingConfig.Codec, appState) require.NotEmpty(t, bankGenState.Supply.String()) } diff --git a/eth/codec.go b/eth/codec.go index 2a45817a6..75be8cae2 100644 --- a/eth/codec.go +++ b/eth/codec.go @@ -31,6 +31,12 @@ const ( ProtocolVersion = 65 ) +// Transaction extension protobuf type URLs +const ( + TYPE_URL_WEB3_TX = "/eth.types.v1.ExtensionOptionsWeb3Tx" + TYPE_URL_DYNAMIC_FEE_TX = "/eth.types.v1.ExtensionOptionDynamicFeeTx" +) + // RegisterInterfaces registers the tendermint concrete client-related // implementations and interfaces. func RegisterInterfaces(registry codectypes.InterfaceRegistry) { diff --git a/eth/codec_test.go b/eth/codec_test.go index e9ad81bec..18a7cea36 100644 --- a/eth/codec_test.go +++ b/eth/codec_test.go @@ -48,8 +48,8 @@ func (suite *CodecTestSuite) TestRegisterInterfaces() { ProtoName: "cosmos.tx.v1beta1.TxExtensionOptionI", Interface: new(sdktx.TxExtensionOptionI), WantImpls: []string{ - "/eth.types.v1.ExtensionOptionsWeb3Tx", - "/eth.types.v1.ExtensionOptionDynamicFeeTx", + TYPE_URL_WEB3_TX, + TYPE_URL_DYNAMIC_FEE_TX, }, }, } diff --git a/eth/encoding/config.go b/eth/encoding/config.go index 80833e7f4..ac8962c31 100644 --- a/eth/encoding/config.go +++ b/eth/encoding/config.go @@ -25,8 +25,8 @@ func MakeConfig(mb module.BasicManager) params.EncodingConfig { } enccodec.RegisterLegacyAminoCodec(encodingConfig.Amino) - mb.RegisterLegacyAminoCodec(encodingConfig.Amino) enccodec.RegisterInterfaces(encodingConfig.InterfaceRegistry) + mb.RegisterLegacyAminoCodec(encodingConfig.Amino) mb.RegisterInterfaces(encodingConfig.InterfaceRegistry) return encodingConfig } diff --git a/eth/eth_account.go b/eth/eth_account.go new file mode 100644 index 000000000..781f09f06 --- /dev/null +++ b/eth/eth_account.go @@ -0,0 +1,84 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package eth + +import ( + "bytes" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +var ( + _ authtypes.AccountI = (*EthAccount)(nil) + _ EthAccountI = (*EthAccount)(nil) + _ authtypes.GenesisAccount = (*EthAccount)(nil) + _ codectypes.UnpackInterfacesMessage = (*EthAccount)(nil) +) + +// EthAccType: Enum for Ethereum account types. +type EthAccType = int8 + +const ( + // EthAccType_EOA: For externally owned accounts (EOAs) + EthAccType_EOA EthAccType = iota + 1 + // EthAccType_Contract: For smart contracts accounts. + EthAccType_Contract +) + +// EthAccountI represents the interface of an EVM compatible account +type EthAccountI interface { //revive:disable-line:exported + authtypes.AccountI + // EthAddress returns the ethereum Address representation of the AccAddress + EthAddress() common.Address + // CodeHash is the keccak256 hash of the contract code (if any) + GetCodeHash() common.Hash + // SetCodeHash sets the code hash to the account fields + SetCodeHash(code common.Hash) error + // Type returns the type of Ethereum Account (EOA or Contract) + Type() EthAccType +} + +func (acc EthAccount) GetBaseAccount() *authtypes.BaseAccount { + return acc.BaseAccount +} + +// EthAddress returns the account address ethereum format. +func (acc EthAccount) EthAddress() common.Address { + return common.BytesToAddress(acc.GetAddress().Bytes()) +} + +func (acc EthAccount) GetCodeHash() common.Hash { + return common.HexToHash(acc.CodeHash) +} + +func (acc *EthAccount) SetCodeHash(codeHash common.Hash) error { + acc.CodeHash = codeHash.Hex() + return nil +} + +// Type returns the type of Ethereum Account (EOA or Contract) +func (acc EthAccount) Type() EthAccType { + if bytes.Equal( + emptyCodeHash, common.HexToHash(acc.CodeHash).Bytes(), + ) { + return EthAccType_EOA + } + return EthAccType_Contract +} + +var emptyCodeHash = crypto.Keccak256(nil) + +// ProtoBaseAccount: Implementation of `BaseAccount` for the `AccountI` interface +// used in the AccountKeeper from the Auth Module. [ProtoBaseAccount] is a +// drop-in replacement for the `auth.ProtoBaseAccount` from +// "cosmos-sdk/auth/types" extended to fit the the `EthAccountI` interface for +// Ethereum accounts. +func ProtoBaseAccount() authtypes.AccountI { + return &EthAccount{ + BaseAccount: &authtypes.BaseAccount{}, + CodeHash: common.BytesToHash(emptyCodeHash).String(), + } +} diff --git a/eth/indexer/kv_indexer_test.go b/eth/indexer/kv_indexer_test.go index 98033dff1..bb446aa71 100644 --- a/eth/indexer/kv_indexer_test.go +++ b/eth/indexer/kv_indexer_test.go @@ -42,7 +42,8 @@ func TestKVIndexer(t *testing.T) { require.NoError(t, tx.Sign(ethSigner, signer)) txHash := tx.AsTransaction().Hash() - encCfg := MakeEncodingConfig() + // encCfg := MakeEncodingConfig() + encCfg := app.MakeEncodingConfig() eth.RegisterInterfaces(encCfg.InterfaceRegistry) evm.RegisterInterfaces(encCfg.InterfaceRegistry) clientCtx := client.Context{}. diff --git a/eth/rpc/backend/account_info.go b/eth/rpc/backend/account_info.go index c4f09b608..a3340983d 100644 --- a/eth/rpc/backend/account_info.go +++ b/eth/rpc/backend/account_info.go @@ -95,11 +95,11 @@ func (b *Backend) GetProof( } // query EVM account - req := &evm.QueryAccountRequest{ + req := &evm.QueryEthAccountRequest{ Address: address.String(), } - res, err := b.queryClient.Account(ctx, req) + res, err := b.queryClient.EthAccount(ctx, req) if err != nil { return nil, err } diff --git a/eth/rpc/backend/evm_query_client_test.go b/eth/rpc/backend/evm_query_client_test.go index 3e1b31624..112cc8a07 100644 --- a/eth/rpc/backend/evm_query_client_test.go +++ b/eth/rpc/backend/evm_query_client_test.go @@ -284,8 +284,8 @@ func RegisterStorageAtError( func RegisterAccount( queryClient *mocks.EVMQueryClient, addr common.Address, height int64, ) { - queryClient.On("Account", rpc.NewContextWithHeight(height), &evm.QueryAccountRequest{Address: addr.String()}). - Return(&evm.QueryAccountResponse{ + queryClient.On("EthAccount", rpc.NewContextWithHeight(height), &evm.QueryEthAccountRequest{Address: addr.String()}). + Return(&evm.QueryEthAccountResponse{ Balance: "0", CodeHash: "", Nonce: 0, diff --git a/eth/rpc/backend/mocks/evm_query_client.go b/eth/rpc/backend/mocks/evm_query_client.go index 3e06374e6..e018a93a2 100644 --- a/eth/rpc/backend/mocks/evm_query_client.go +++ b/eth/rpc/backend/mocks/evm_query_client.go @@ -17,8 +17,8 @@ type EVMQueryClient struct { mock.Mock } -// Account provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) Account(ctx context.Context, in *evm.QueryAccountRequest, opts ...grpc.CallOption) (*evm.QueryAccountResponse, error) { +// EthAccount provides a mock function with given fields: ctx, in, opts +func (_m *EVMQueryClient) EthAccount(ctx context.Context, in *evm.QueryEthAccountRequest, opts ...grpc.CallOption) (*evm.QueryEthAccountResponse, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -28,17 +28,17 @@ func (_m *EVMQueryClient) Account(ctx context.Context, in *evm.QueryAccountReque _ca = append(_ca, _va...) ret := _m.Called(_ca...) - var r0 *evm.QueryAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryAccountRequest, ...grpc.CallOption) *evm.QueryAccountResponse); ok { + var r0 *evm.QueryEthAccountResponse + if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryEthAccountRequest, ...grpc.CallOption) *evm.QueryEthAccountResponse); ok { r0 = rf(ctx, in, opts...) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryAccountResponse) + r0 = ret.Get(0).(*evm.QueryEthAccountResponse) } } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryAccountRequest, ...grpc.CallOption) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryEthAccountRequest, ...grpc.CallOption) error); ok { r1 = rf(ctx, in, opts...) } else { r1 = ret.Error(1) @@ -137,8 +137,8 @@ func (_m *EVMQueryClient) Code(ctx context.Context, in *evm.QueryCodeRequest, op return r0, r1 } -// CosmosAccount provides a mock function with given fields: ctx, in, opts -func (_m *EVMQueryClient) CosmosAccount(ctx context.Context, in *evm.QueryCosmosAccountRequest, opts ...grpc.CallOption) (*evm.QueryCosmosAccountResponse, error) { +// NibiruAccount provides a mock function with given fields: ctx, in, opts +func (_m *EVMQueryClient) NibiruAccount(ctx context.Context, in *evm.QueryNibiruAccountRequest, opts ...grpc.CallOption) (*evm.QueryNibiruAccountResponse, error) { _va := make([]interface{}, len(opts)) for _i := range opts { _va[_i] = opts[_i] @@ -148,17 +148,17 @@ func (_m *EVMQueryClient) CosmosAccount(ctx context.Context, in *evm.QueryCosmos _ca = append(_ca, _va...) ret := _m.Called(_ca...) - var r0 *evm.QueryCosmosAccountResponse - if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryCosmosAccountRequest, ...grpc.CallOption) *evm.QueryCosmosAccountResponse); ok { + var r0 *evm.QueryNibiruAccountResponse + if rf, ok := ret.Get(0).(func(context.Context, *evm.QueryNibiruAccountRequest, ...grpc.CallOption) *evm.QueryNibiruAccountResponse); ok { r0 = rf(ctx, in, opts...) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*evm.QueryCosmosAccountResponse) + r0 = ret.Get(0).(*evm.QueryNibiruAccountResponse) } } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryCosmosAccountRequest, ...grpc.CallOption) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, *evm.QueryNibiruAccountRequest, ...grpc.CallOption) error); ok { r1 = rf(ctx, in, opts...) } else { r1 = ret.Error(1) diff --git a/proto/eth/evm/v1/query.proto b/proto/eth/evm/v1/query.proto index 007c85de4..00f211e22 100644 --- a/proto/eth/evm/v1/query.proto +++ b/proto/eth/evm/v1/query.proto @@ -13,14 +13,14 @@ option go_package = "github.com/NibiruChain/nibiru/x/evm"; // Query defines the gRPC querier service. service Query { - // Account queries an Ethereum account. - rpc Account(QueryAccountRequest) returns (QueryAccountResponse) { - option (google.api.http).get = "/nibiru/evm/v1/account/{address}"; + // EthAccount queries an Ethereum account. + rpc EthAccount(QueryEthAccountRequest) returns (QueryEthAccountResponse) { + option (google.api.http).get = "/nibiru/evm/v1/eth_account/{address}"; } - // CosmosAccount queries an Ethereum account's Cosmos Address. - rpc CosmosAccount(QueryCosmosAccountRequest) returns (QueryCosmosAccountResponse) { - option (google.api.http).get = "/nibiru/evm/v1/cosmos_account/{address}"; + // NibiruAccount queries the Bech32 Nibiru address corresponding to Nibiru EVM account. + rpc NibiruAccount(QueryNibiruAccountRequest) returns (QueryNibiruAccountResponse) { + option (google.api.http).get = "/nibiru/evm/v1/nibiru_account/{address}"; } // ValidatorAccount queries an Ethereum account's from a validator consensus @@ -77,8 +77,8 @@ service Query { } } -// QueryAccountRequest is the request type for the Query/Account RPC method. -message QueryAccountRequest { +// QueryEthAccountRequest is the request type for the Query/Account RPC method. +message QueryEthAccountRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -86,8 +86,8 @@ message QueryAccountRequest { string address = 1; } -// QueryAccountResponse is the response type for the Query/Account RPC method. -message QueryAccountResponse { +// QueryEthAccountResponse is the response type for the Query/Account RPC method. +message QueryEthAccountResponse { // balance is the balance of the EVM denomination. string balance = 1; // code_hash is the hex-formatted code bytes from the EOA. @@ -96,9 +96,9 @@ message QueryAccountResponse { uint64 nonce = 3; } -// QueryCosmosAccountRequest is the request type for the Query/CosmosAccount RPC +// QueryNibiruAccountRequest is the request type for the Query/NibiruAccount RPC // method. -message QueryCosmosAccountRequest { +message QueryNibiruAccountRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; @@ -106,11 +106,11 @@ message QueryCosmosAccountRequest { string address = 1; } -// QueryCosmosAccountResponse is the response type for the Query/CosmosAccount +// QueryNibiruAccountResponse is the response type for the Query/NibiruAccount // RPC method. -message QueryCosmosAccountResponse { - // cosmos_address is the cosmos address of the account. - string cosmos_address = 1; +message QueryNibiruAccountResponse { + // Nibiru bech32 account "address" + string address = 1; // sequence is the account's sequence number. uint64 sequence = 2; // account_number is the account number @@ -130,7 +130,7 @@ message QueryValidatorAccountRequest { // QueryValidatorAccountResponse is the response type for the // Query/ValidatorAccount RPC method. message QueryValidatorAccountResponse { - // account_address is the cosmos address of the account in bech32 format. + // account_address is the Nibiru address of the account in bech32 format. string account_address = 1; // sequence is the account's sequence number. uint64 sequence = 2; diff --git a/proto/nibiru/perp/v2/event.proto b/proto/nibiru/perp/v2/event.proto deleted file mode 100644 index 3e1b3d915..000000000 --- a/proto/nibiru/perp/v2/event.proto +++ /dev/null @@ -1,262 +0,0 @@ -syntax = "proto3"; - -package nibiru.perp.v2; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "nibiru/perp/v2/state.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; - -// Emitted when a position changes. -message PositionChangedEvent { - nibiru.perp.v2.Position final_position = 1 [ (gogoproto.nullable) = false ]; - - // Position notional (in quote units) after the change. In general, - // 'notional = baseAmount * priceQuotePerBase', where size is the baseAmount. - string position_notional = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // Transaction fee paid. A "taker" fee. - cosmos.base.v1beta1.Coin transaction_fee = 3 [ - (gogoproto.moretags) = "yaml:\"transaction_fee\"", - (gogoproto.nullable) = false - ]; - - // realize profits and losses after the change - string realized_pnl = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // Amount of bad debt cleared by the PerpEF during the change. - // Bad debt is negative net margin past the liquidation point of a position. - cosmos.base.v1beta1.Coin bad_debt = 5 [ (gogoproto.nullable) = false ]; - - /* A funding payment made or received by the trader on the current position. - 'fundingPayment' is positive if 'owner' is the sender and negative if 'owner' - is the receiver of the payment. Its magnitude is abs(size * fundingRate). - Funding payments act to converge the mark price and index price - (average price on major exchanges). - */ - string funding_payment = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The block number at which this position was changed. - int64 block_height = 7; - - // margin_to_user is the amount of collateral received by the trader during - // the position change. A positve value indicates that the trader received - // funds, while a negative value indicates that the trader spent funds. - string margin_to_user = 8 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - - // change_reason describes the reason for why the position resulted in a - // change. Change type can take the following values: - // - // - CHANGE_REASON_UNSPECIFIED: Unspecified change reason. - // - CHANGE_REASON_ADD_MARGIN: Margin was added to the position. - // - CHANGE_REASON_REMOVE_MARGIN: Margin was removed from the position. - // - CHANGE_REASON_OPEN_POSITION: A new position was opened. - // - CHANGE_REASON_CLOSE_POSITION: An existing position was closed. - string change_reason = 9 - [ (gogoproto.customtype) = "ChangeReason", (gogoproto.nullable) = false ]; - - // exchanged_size represent the change in size for an existing position - // after the change. A positive value indicates that the position size - // increased, while a negative value indicates that the position size - // decreased. - string exchanged_size = 10 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // exchanged_notional represent the change in notional for an existing - // position after the change. A positive value indicates that the position - // notional increased, while a negative value indicates that the position - // notional decreased. - string exchanged_notional = 11 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// Emitted when a position is liquidated. Wraps a PositionChanged event since a -// liquidation causes position changes. -message PositionLiquidatedEvent { - nibiru.perp.v2.PositionChangedEvent position_changed_event = 1 - [ (gogoproto.nullable) = false ]; - - // Address of the account that executed the tx. - string liquidator_address = 2; - - // Commission (in margin units) received by 'liquidator'. - cosmos.base.v1beta1.Coin fee_to_liquidator = 3 [ - (gogoproto.moretags) = "yaml:\"fee_to_liquidator\"", - (gogoproto.nullable) = false - ]; - - // Commission (in margin units) given to the ecosystem fund. - cosmos.base.v1beta1.Coin fee_to_ecosystem_fund = 4 [ - (gogoproto.moretags) = "yaml:\"fee_to_ecosystem_fund\"", - (gogoproto.nullable) = false - ]; -} - -// Emitted when a position is settled. -message PositionSettledEvent { - // Identifier for the virtual pool of the position. - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // Owner of the position. - string trader_address = 2; - - // Settled coin as dictated by the settlement price of the perp.amm. - repeated cosmos.base.v1beta1.Coin settled_coins = 3 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"settled_coins\"", - (gogoproto.nullable) = false - ]; -} - -// Emitted when the funding rate changes for a market. -message FundingRateChangedEvent { - // The pair for which the funding rate was calculated. - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // The mark price of the pair. - string mark_price_twap = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The oracle index price of the pair. - string index_price_twap = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The latest premium fraction just calculated. - string premium_fraction = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The market's latest cumulative premium fraction. - // The funding payment a position will pay is the difference between this - // value and the latest cumulative premium fraction on the position, - // multiplied by the position size. - string cumulative_premium_fraction = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// Emitted when liquidation fails. -message LiquidationFailedEvent { - // The pair for which we are trying to liquidate. - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // owner of the position. - string trader = 2; - - // Address of the account that executed the tx. - string liquidator = 3; - - enum LiquidationFailedReason { - UNSPECIFIED = 0; - - // the position is healthy and does not need to be liquidated. - POSITION_HEALTHY = 1; - - // the pair does not exist. - NONEXISTENT_PAIR = 2; - - // the position does not exist. - NONEXISTENT_POSITION = 3; - } - // Reason for the liquidation failure. - LiquidationFailedReason reason = 4; -} - -// This event is emitted when the amm is updated, which can be triggered by -// the following events: -// -// - swap -// - edit price multiplier -// - edit depth -message AmmUpdatedEvent { - // the final state of the AMM - nibiru.perp.v2.AMM final_amm = 1 [ (gogoproto.nullable) = false ]; - - // The mark price of the pair. - string mark_price_twap = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The oracle index price of the pair. - string index_price_twap = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// This event is emitted at the end of every block for persisting market changes -// off-chain -// -// Market changes are triggered by the following actions: -// -// - disabling market -// - changing market fees -// - bad debt is prepaid by the ecosystem fund -message MarketUpdatedEvent { - // the final state of the market - nibiru.perp.v2.Market final_market = 1 [ (gogoproto.nullable) = false ]; -} - -// EventShiftPegMultiplier: ABCI event emitted from MsgShiftPegMultiplier -message EventShiftPegMultiplier { - string old_peg_multiplier = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - string new_peg_multiplier = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - cosmos.base.v1beta1.Coin cost_paid = 3 [ (gogoproto.nullable) = false ]; -} - -// EventShiftSwapInvariant: ABCI event emitted from MsgShiftSwapInvariant -message EventShiftSwapInvariant { - string old_swap_invariant = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - string new_swap_invariant = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - cosmos.base.v1beta1.Coin cost_paid = 3 [ (gogoproto.nullable) = false ]; -} diff --git a/proto/nibiru/perp/v2/genesis.proto b/proto/nibiru/perp/v2/genesis.proto deleted file mode 100644 index d0e921cc0..000000000 --- a/proto/nibiru/perp/v2/genesis.proto +++ /dev/null @@ -1,102 +0,0 @@ -syntax = "proto3"; - -package nibiru.perp.v2; - -import "cosmos/base/v1beta1/coin.proto"; -import "google/api/annotations.proto"; -import "gogoproto/gogo.proto"; -import "nibiru/perp/v2/state.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; - -// GenesisState defines the perp module's genesis state. -// Thge genesis state is used not only to start the network but also useful for -// exporting and importing state during network upgrades. -message GenesisState { - repeated nibiru.perp.v2.Market markets = 2 [ (gogoproto.nullable) = false ]; - - repeated nibiru.perp.v2.AMM amms = 3 [ (gogoproto.nullable) = false ]; - - repeated GenesisPosition positions = 4 [ (gogoproto.nullable) = false ]; - - repeated nibiru.perp.v2.ReserveSnapshot reserve_snapshots = 5 - [ (gogoproto.nullable) = false ]; - - uint64 dnr_epoch = 6; - - message TraderVolume { - string trader = 1; - uint64 epoch = 2; - string volume = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - } - - // For testing purposes, we allow the collateral to be set at genesis - string collateral_denom = 11; - - repeated TraderVolume trader_volumes = 7 [ (gogoproto.nullable) = false ]; - - message Discount { - string fee = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - string volume = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - } - - repeated Discount global_discount = 8 [ (gogoproto.nullable) = false ]; - - repeated CustomDiscount custom_discounts = 9 [ (gogoproto.nullable) = false ]; - - message CustomDiscount { - string trader = 1; - Discount discount = 2; - } - - repeated nibiru.perp.v2.GenesisMarketLastVersion market_last_versions = 10 - [ (gogoproto.nullable) = false ]; - - repeated GlobalVolume global_volumes = 13 [ (gogoproto.nullable) = false ]; - - repeated DNRAllocation rebates_allocations = 12 - [ (gogoproto.nullable) = false ]; - - string dnr_epoch_name = 14; - - message GlobalVolume { - uint64 epoch = 1; - string volume = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - } -} - -// GenesisMarketLastVersion is the last version including pair only used for -// genesis -message GenesisMarketLastVersion { - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - uint64 version = 2; -} - -message GenesisPosition { - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - uint64 version = 2; - - Position position = 3 [ (gogoproto.nullable) = false ]; -} diff --git a/proto/nibiru/perp/v2/query.proto b/proto/nibiru/perp/v2/query.proto deleted file mode 100644 index 70f9234b2..000000000 --- a/proto/nibiru/perp/v2/query.proto +++ /dev/null @@ -1,163 +0,0 @@ -syntax = "proto3"; - -package nibiru.perp.v2; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "nibiru/perp/v2/state.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; - -// Query defines the gRPC querier service. -service Query { - // QueryPosition: Query one position on the given market for a user - rpc QueryPosition(QueryPositionRequest) returns (QueryPositionResponse) { - option (google.api.http).get = "/nibiru/perp/v2/position"; - } - - // QueryPositions: Query all positions for a user - rpc QueryPositions(QueryPositionsRequest) returns (QueryPositionsResponse) { - option (google.api.http).get = "/nibiru/perp/v2/positions"; - } - - // QueryPositionStore queries all of the positions in the KV store. - rpc QueryPositionStore(QueryPositionStoreRequest) - returns (QueryPositionStoreResponse) { - option (google.api.http).get = "/nibiru/perp/v2/position_store"; - } - - // Queries the module accounts for x/perp - rpc ModuleAccounts(QueryModuleAccountsRequest) - returns (QueryModuleAccountsResponse) { - option (google.api.http).get = "/nibiru/perp/v2/module_accounts"; - } - - // QueryMarkets: Query all markets - rpc QueryMarkets(QueryMarketsRequest) returns (QueryMarketsResponse) { - option (google.api.http).get = "/nibiru/perp/v2/markets"; - } - - // QueryCollateral: Queries info about the collateral - rpc QueryCollateral(QueryCollateralRequest) - returns (QueryCollateralResponse) { - option (google.api.http).get = "/nibiru/perp/v2/collateral"; - } -} - -// ---------------------------------------- Positions - -// QueryPositionsRequest: Request type for the -// "nibiru.perp.v2.Query/Positions" gRPC service method -message QueryPositionsRequest { string trader = 1; } - -// QueryPositionsResponse: Response type for the -// "nibiru.perp.v2.Query/Positions" gRPC service method -message QueryPositionsResponse { - repeated nibiru.perp.v2.QueryPositionResponse positions = 1 - [ (gogoproto.nullable) = false ]; -} - -// QueryPositionStoreRequest: Request type for the -// "nibiru.perp.v2.Query/PositionStore" gRPC service method -message QueryPositionStoreRequest { - // pagination defines a paginated request - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} - -// QueryPositionStoreResponse: Response type for the -// "nibiru.perp.v2.Query/PositionStore" gRPC service method -message QueryPositionStoreResponse { - // Position responses: collection of all stored positions (with pagination) - repeated nibiru.perp.v2.Position positions = 1 - [ (gogoproto.nullable) = false ]; - - // pagination defines a paginated response - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -// ---------------------------------------- Position - -// QueryPositionRequest: Request type for the -// "nibiru.perp.v2.Query/Position" gRPC service method -message QueryPositionRequest { - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - string trader = 2; -} - -// QueryPositionResponse: Response type for the -// "nibiru.perp.v2.Query/Position" gRPC service method -message QueryPositionResponse { - // The position as it exists in the blockchain state - nibiru.perp.v2.Position position = 1 [ (gogoproto.nullable) = false ]; - - // The position's current notional value, if it were to be entirely closed (in - // margin units). - string position_notional = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The position's unrealized PnL. - string unrealized_pnl = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // margin ratio of the position based on the spot price - string margin_ratio = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// ---------------------------------------- QueryModuleAccounts - -// QueryModuleAccountsRequest: Request type for the -// "nibiru.perp.v2.Query/ModuleAccounts" gRPC service method -message QueryModuleAccountsRequest {} - -// QueryModuleAccountsResponse: Response type for the -// "nibiru.perp.v2.Query/ModuleAccounts" gRPC service method -message QueryModuleAccountsResponse { - repeated nibiru.perp.v2.AccountWithBalance accounts = 1 - [ (gogoproto.nullable) = false ]; -} - -message AccountWithBalance { - string name = 1; - string address = 2; - - repeated cosmos.base.v1beta1.Coin balance = 3 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -message AmmMarket { - nibiru.perp.v2.Market market = 1 [ (gogoproto.nullable) = false ]; - nibiru.perp.v2.AMM amm = 2 [ (gogoproto.nullable) = false ]; -} - -message QueryMarketsRequest { bool versioned = 1; } - -message QueryMarketsResponse { - repeated nibiru.perp.v2.AmmMarket amm_markets = 1 - [ (gogoproto.nullable) = false ]; -} - -// ---------------------------------------- QueryCollateral - -// QueryCollateralRequest: Request type for the -// "nibiru.perp.v2.Query/Collateral" gRPC service method -message QueryCollateralRequest {} - -// QueryCollateralRequest: Response type for the -// "nibiru.perp.v2.Query/Collateral" gRPC service method -message QueryCollateralResponse { string collateral_denom = 1; } diff --git a/proto/nibiru/perp/v2/state.proto b/proto/nibiru/perp/v2/state.proto deleted file mode 100644 index 2d4d60abf..000000000 --- a/proto/nibiru/perp/v2/state.proto +++ /dev/null @@ -1,250 +0,0 @@ -syntax = "proto3"; - -package nibiru.perp.v2; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos_proto/cosmos.proto"; -import "google/protobuf/duration.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; - -// The direction that the user is trading in -// LONG means the user is going long the base asset (e.g. buy BTC) -// SHORT means the user is shorting the base asset (e.g. sell BTC) -enum Direction { - DIRECTION_UNSPECIFIED = 0; - LONG = 1; - SHORT = 2; -} - -// Enumerates different options of calculating twap. -enum TwapCalcOption { - TWAP_CALC_OPTION_UNSPECIFIED = 0; - - // Spot price from quote asset reserve / base asset reserve - SPOT = 1; - - // Swapping with quote assets, output denominated in base assets - QUOTE_ASSET_SWAP = 2; - - // Swapping with base assets, output denominated in quote assets - BASE_ASSET_SWAP = 3; -} - -message Market { - // the trading pair represented by this market - // always BASE:QUOTE, e.g. BTC:NUSD or ETH:NUSD - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // whether or not the market is enabled - bool enabled = 2; - - // the version of the Market, only one market can exist per pair, when one is - // closed it cannot be reactivated, so a new market must be created, this is - // the version of the market - uint64 version = 14; - - // the minimum margin ratio which a user must maintain on this market - string maintenance_margin_ratio = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the maximum leverage a user is able to be taken on this market - string max_leverage = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // Latest cumulative premium fraction for a given pair. - // Calculated once per funding rate interval. - // A premium fraction is the difference between mark and index, divided by the - // number of payments per day. (mark - index) / # payments in a day - string latest_cumulative_premium_fraction = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the percentage of the notional given to the exchange when trading - string exchange_fee_ratio = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the percentage of the notional transferred to the ecosystem fund when - // trading - string ecosystem_fund_fee_ratio = 7 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the percentage of liquidated position that will be - // given to out as a reward. Half of the liquidation fee is given to the - // liquidator, and the other half is given to the ecosystem fund. - string liquidation_fee_ratio = 8 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the portion of the position size we try to liquidate if the available - // margin is higher than liquidation fee - string partial_liquidation_ratio = 9 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // specifies the interval on which the funding rate is updated - string funding_rate_epoch_id = 10; - - // amount of time to look back for TWAP calculations - google.protobuf.Duration twap_lookback_window = 11 - [ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; - - // the amount of collateral already credited from the ecosystem fund - cosmos.base.v1beta1.Coin prepaid_bad_debt = 12 - [ (gogoproto.nullable) = false ]; - - // the maximum funding rate payment per epoch, this represents the maximum - // amount of funding that can be paid out per epoch as a percentage of the - // position size - string max_funding_rate = 13 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.stdduration) = true, - (gogoproto.nullable) = false - ]; - - // the pair of the oracle that is used to determine the index price - // for the market - string oracle_pair = 15 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; -} - -// MarketLastVersion is used to store the last version of the market -message MarketLastVersion { - // version of the market - uint64 version = 1; -} - -message AMM { - // identifies the market this AMM belongs to - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // the version of the AMM, only one AMM can exist per pair, when one is closed - // it cannot be reactivated, so a new AMM must be created, this is the version - // of the AMM - uint64 version = 8; - - // the amount of base reserves this AMM has - string base_reserve = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the amount of quote reserves this AMM has - string quote_reserve = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // sqrt(k) - string sqrt_depth = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // the price multiplier of the dynamic AMM - string price_multiplier = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // Total long refers to the sum of long open notional in base. - string total_long = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // Total short refers to the sum of short open notional in base. - string total_short = 7 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The settlement price if the AMM is settled. - string settlement_price = 9 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.stdduration) = true, - (gogoproto.nullable) = false - ]; -} - -message Position { - // address identifies the address owner of this position - string trader_address = 1; - - // pair identifies the pair associated with this position - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - // the position size - string size = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // amount of margin remaining in the position - string margin = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // value of position in quote assets when opened - string open_notional = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The most recent cumulative premium fraction this position has. - // Used to calculate the next funding payment. - string latest_cumulative_premium_fraction = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // last block number this position was updated - int64 last_updated_block_number = 7; -} - -// a snapshot of the perp.amm's reserves at a given point in time -message ReserveSnapshot { - AMM amm = 1 [ (gogoproto.nullable) = false ]; - - // milliseconds since unix epoch - int64 timestamp_ms = 2; -} - -// DNRAllocation represents a rebates allocation for a given epoch. -message DNRAllocation { - // epoch defines the reference epoch for the allocation. - uint64 epoch = 1; - // amount of DNR allocated for the epoch. - repeated cosmos.base.v1beta1.Coin amount = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} diff --git a/proto/nibiru/perp/v2/tx.proto b/proto/nibiru/perp/v2/tx.proto deleted file mode 100644 index 9153d4f13..000000000 --- a/proto/nibiru/perp/v2/tx.proto +++ /dev/null @@ -1,472 +0,0 @@ -syntax = "proto3"; - -package nibiru.perp.v2; - -import "google/api/annotations.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "gogoproto/gogo.proto"; -import "nibiru/perp/v2/state.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types"; - -// Msg defines the x/perp Msg service. -service Msg { - - rpc RemoveMargin(MsgRemoveMargin) returns (MsgRemoveMarginResponse) {} - - rpc AddMargin(MsgAddMargin) returns (MsgAddMarginResponse) {} - - rpc MultiLiquidate(MsgMultiLiquidate) returns (MsgMultiLiquidateResponse) {} - - rpc MarketOrder(MsgMarketOrder) returns (MsgMarketOrderResponse) {} - - rpc ClosePosition(MsgClosePosition) returns (MsgClosePositionResponse) {} - - rpc PartialClose(MsgPartialClose) returns (MsgPartialCloseResponse) {} - - rpc SettlePosition(MsgSettlePosition) returns (MsgClosePositionResponse) {} - - rpc DonateToEcosystemFund(MsgDonateToEcosystemFund) - returns (MsgDonateToEcosystemFundResponse) {} - - // ChangeCollateralDenom: Updates the collateral denom. A denom is valid if it - // is possible to make an sdk.Coin using it. [SUDO] Only callable by sudoers. - rpc ChangeCollateralDenom(MsgChangeCollateralDenom) - returns (MsgChangeCollateralDenomResponse) {} - - rpc AllocateEpochRebates(MsgAllocateEpochRebates) - returns (MsgAllocateEpochRebatesResponse) {} - - rpc WithdrawEpochRebates(MsgWithdrawEpochRebates) - returns (MsgWithdrawEpochRebatesResponse) {} - - // ShiftPegMultiplier: gRPC tx msg for changing a market's peg multiplier. - // [SUDO] Only callable by sudoers. - rpc ShiftPegMultiplier(MsgShiftPegMultiplier) - returns (MsgShiftPegMultiplierResponse) {} - - // ShiftSwapInvariant: gRPC tx msg for changing a market's swap invariant. - // [SUDO] Only callable by sudoers. - rpc ShiftSwapInvariant(MsgShiftSwapInvariant) - returns (MsgShiftSwapInvariantResponse) {} - - // WithdrawFromPerpFund: gRPC tx msg to withdraw from the perp fund module - // account. [SUDO] Only callable by sudoers. - rpc WithdrawFromPerpFund(MsgWithdrawFromPerpFund) - returns (MsgWithdrawFromPerpFundResponse) {} - - // CloseMarket: gRPC tx msg for closing a market. - // [Admin] Only callable by sudoers. - rpc CloseMarket(MsgCloseMarket) returns (MsgCloseMarketResponse) {} -} - -// -------------------------- Settle Position -------------------------- - -/* MsgSettlePosition: Msg to remove margin. */ -message MsgSettlePosition { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - uint64 version = 3; -} - -// -------------------------- RemoveMargin -------------------------- - -/* MsgRemoveMargin: Msg to remove margin. */ -message MsgRemoveMargin { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - cosmos.base.v1beta1.Coin margin = 3 [ (gogoproto.nullable) = false ]; -} - -message MsgRemoveMarginResponse { - // tokens transferred back to the trader - cosmos.base.v1beta1.Coin margin_out = 1 [ (gogoproto.nullable) = false ]; - - // the funding payment applied on this position interaction - string funding_payment = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The resulting position - nibiru.perp.v2.Position position = 3; -} - -// -------------------------- AddMargin -------------------------- - -/* MsgAddMargin: Msg to remove margin. */ -message MsgAddMargin { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - cosmos.base.v1beta1.Coin margin = 3 [ (gogoproto.nullable) = false ]; -} - -message MsgAddMarginResponse { - string funding_payment = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - nibiru.perp.v2.Position position = 2; -} - -// -------------------------- Liquidation -------------------------- - -message MsgMultiLiquidate { - string sender = 1; - - message Liquidation { - string pair = 1 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - string trader = 2; - } - - repeated Liquidation liquidations = 2; -} - -message MsgMultiLiquidateResponse { - message LiquidationResponse { - bool success = 1; - string error = 2; - - cosmos.base.v1beta1.Coin liquidator_fee = 3 [ (gogoproto.nullable) = true ]; - // nullable since no fee is taken on failed liquidation - - cosmos.base.v1beta1.Coin perp_ef_fee = 4 - [ (gogoproto.nullable) = true ]; // perp ecosystem fund - // nullable since no fee is taken on failed liquidation - - string trader = 5; - string pair = 6 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - } - - repeated LiquidationResponse liquidations = 1; -} - -// -------------------------- MarketOrder -------------------------- - -message MsgMarketOrder { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - nibiru.perp.v2.Direction side = 3; - - string quote_asset_amount = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - - string leverage = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - string base_asset_amount_limit = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; -} - -message MsgMarketOrderResponse { - nibiru.perp.v2.Position position = 1; - - // The amount of quote assets exchanged. - string exchanged_notional_value = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of base assets exchanged. - string exchanged_position_size = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The funding payment applied on this position change, measured in quote - // units. - string funding_payment = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of PnL realized on this position changed, measured in quote - // units. - string realized_pnl = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The unrealized PnL in the position after the position change, measured in - // quote units. - string unrealized_pnl_after = 6 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of margin the trader has to give to the vault. - // A negative value means the vault pays the trader. - string margin_to_vault = 7 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The position's notional value after the position change, measured in quote - // units. - string position_notional = 8 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// -------------------------- ClosePosition -------------------------- - -message MsgClosePosition { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; -} - -message MsgClosePositionResponse { - // The amount of quote assets exchanged. - string exchanged_notional_value = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of base assets exchanged. - string exchanged_position_size = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The funding payment applied on this position change, measured in quote - // units. - string funding_payment = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of PnL realized on this position changed, measured in quote - // units. - string realized_pnl = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of margin the trader receives after closing the position, from - // the vault. Should never be negative. - string margin_to_trader = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -message MsgPartialClose { - string sender = 1; - - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - - string size = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -message MsgPartialCloseResponse { - // The amount of quote assets exchanged. - string exchanged_notional_value = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of base assets exchanged. - string exchanged_position_size = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The funding payment applied on this position change, measured in quote - // units. - string funding_payment = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of PnL realized on this position changed, measured in quote - // units. - string realized_pnl = 4 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; - - // The amount of margin the trader receives after closing the position, from - // the vault. Should never be negative. - string margin_to_trader = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -// -------------------------- DonateToEcosystemFund -------------------------- - -message MsgDonateToEcosystemFund { - string sender = 1; - - // donation to the EF - cosmos.base.v1beta1.Coin donation = 2 [ - (gogoproto.moretags) = "yaml:\"donation\"", - (gogoproto.nullable) = false - ]; -} - -message MsgDonateToEcosystemFundResponse {} - -// ----------------------- MsgChangeCollateralDenom ----------------------- - -// MsgChangeCollateralDenom: Changes the collateral denom for the module. -// [SUDO] Only callable by sudoers. -message MsgChangeCollateralDenom { - string sender = 1; - string new_denom = 2; -} - -message MsgChangeCollateralDenomResponse {} - -// -------------------------- AllocateEpochRebates -------------------------- -message MsgAllocateEpochRebates { - string sender = 1; - - // rebates to allocate - repeated cosmos.base.v1beta1.Coin rebates = 2 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -message MsgAllocateEpochRebatesResponse { - repeated cosmos.base.v1beta1.Coin total_epoch_rebates = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// -------------------------- WithdrawEpochRebates -------------------------- -message MsgWithdrawEpochRebates { - string sender = 1; - repeated uint64 epochs = 2; -} - -message MsgWithdrawEpochRebatesResponse { - repeated cosmos.base.v1beta1.Coin withdrawn_rebates = 1 [ - (gogoproto.nullable) = false, - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins" - ]; -} - -// -------------------------- ShiftPegMultiplier -------------------------- - -// MsgShiftPegMultiplier: gRPC tx msg for changing the peg multiplier. -// [SUDO] Only callable sudoers. -message MsgShiftPegMultiplier { - string sender = 1; - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - string new_peg_mult = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false - ]; -} - -message MsgShiftPegMultiplierResponse {} - -// -------------------------- ShiftSwapInvariant -------------------------- - -// MsgShiftSwapInvariant: gRPC tx msg for changing the swap invariant. -// [SUDO] Only callable sudoers. -message MsgShiftSwapInvariant { - string sender = 1; - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; - string new_swap_invariant = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; -} - -message MsgShiftSwapInvariantResponse {} - -// -------------------------- WithdrawFromPerpFund -------------------------- - -// MsgWithdrawFromPerpFund: gRPC tx msg for changing the swap invariant. -// [SUDO] Only callable sudoers. -message MsgWithdrawFromPerpFund { - string sender = 1; - string amount = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.nullable) = false - ]; - // Optional denom in case withdrawing assets aside from NUSD. - string denom = 3; - string to_addr = 4; -} - -message MsgWithdrawFromPerpFundResponse {} - -// -------------------------- CloseMarket -------------------------- - -// CloseMarket: gRPC tx msg for closing a market. -// Admin-only. -message MsgCloseMarket { - string sender = 1; - string pair = 2 [ - (gogoproto.customtype) = - "github.com/NibiruChain/nibiru/x/common/asset.Pair", - (gogoproto.nullable) = false - ]; -} - -message MsgCloseMarketResponse {} diff --git a/proto/nibiru/spot/v1/event.proto b/proto/nibiru/spot/v1/event.proto deleted file mode 100644 index 3e4788d9a..000000000 --- a/proto/nibiru/spot/v1/event.proto +++ /dev/null @@ -1,86 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "nibiru/spot/v1/pool.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -message EventPoolCreated { - // the address of the user who created the pool - string creator = 1; - - // the create pool fee - repeated cosmos.base.v1beta1.Coin fees = 2 [ (gogoproto.nullable) = false ]; - - // the final state of the pool - nibiru.spot.v1.Pool final_pool = 4 [ (gogoproto.nullable) = false ]; - - // the amount of pool shares that the user received - cosmos.base.v1beta1.Coin final_user_pool_shares = 5 - [ (gogoproto.nullable) = false ]; -} - -message EventPoolJoined { - // the address of the user who joined the pool - string address = 1; - - // the amount of tokens that the user deposited - repeated cosmos.base.v1beta1.Coin tokens_in = 2 - [ (gogoproto.nullable) = false ]; - - // the amount of pool shares that the user received - cosmos.base.v1beta1.Coin pool_shares_out = 3 [ (gogoproto.nullable) = false ]; - - // the amount of tokens remaining for the user - repeated cosmos.base.v1beta1.Coin rem_coins = 4 - [ (gogoproto.nullable) = false ]; - - // the final state of the pool - nibiru.spot.v1.Pool final_pool = 5 [ (gogoproto.nullable) = false ]; - - // the final amount of user pool shares - cosmos.base.v1beta1.Coin final_user_pool_shares = 6 - [ (gogoproto.nullable) = false ]; -} - -message EventPoolExited { - // the address of the user who exited the pool - string address = 1; - - // the amount of pool shares that the user exited with - cosmos.base.v1beta1.Coin pool_shares_in = 2 [ (gogoproto.nullable) = false ]; - - // the amount of tokens returned to the user - repeated cosmos.base.v1beta1.Coin tokens_out = 3 - [ (gogoproto.nullable) = false ]; - - // the amount of fees collected by the pool - repeated cosmos.base.v1beta1.Coin fees = 4 [ (gogoproto.nullable) = false ]; - - // the final state of the pool - nibiru.spot.v1.Pool final_pool = 5 [ (gogoproto.nullable) = false ]; - - // the final amount of user pool shares - cosmos.base.v1beta1.Coin final_user_pool_shares = 6 - [ (gogoproto.nullable) = false ]; -} - -message EventAssetsSwapped { - // the address of the user who swapped tokens - string address = 1; - - // the amount of tokens that the user deposited - cosmos.base.v1beta1.Coin token_in = 2 [ (gogoproto.nullable) = false ]; - - // the amount of tokens that the user received - cosmos.base.v1beta1.Coin token_out = 3 [ (gogoproto.nullable) = false ]; - - // the amount of fees collected by the pool - cosmos.base.v1beta1.Coin fee = 4 [ (gogoproto.nullable) = false ]; - - // the final state of the pool - nibiru.spot.v1.Pool final_pool = 5 [ (gogoproto.nullable) = false ]; -} diff --git a/proto/nibiru/spot/v1/genesis.proto b/proto/nibiru/spot/v1/genesis.proto deleted file mode 100644 index 0d2e222ee..000000000 --- a/proto/nibiru/spot/v1/genesis.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "nibiru/spot/v1/params.proto"; -import "nibiru/spot/v1/pool.proto"; -import "gogoproto/gogo.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -// GenesisState defines the spot module's genesis state. -message GenesisState { - // params defines all the parameters of the module. - nibiru.spot.v1.Params params = 1 [ (gogoproto.nullable) = false ]; - - // pools defines all the pools of the module. - repeated nibiru.spot.v1.Pool pools = 2 [ (gogoproto.nullable) = false ]; -} diff --git a/proto/nibiru/spot/v1/params.proto b/proto/nibiru/spot/v1/params.proto deleted file mode 100644 index d16d71e85..000000000 --- a/proto/nibiru/spot/v1/params.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -// Params defines the parameters for the module. -message Params { - option (gogoproto.goproto_stringer) = false; - - // The start pool number, i.e. the first pool number that isn't taken yet. - uint64 starting_pool_number = 1; - - // The cost of creating a pool, taken from the pool creator's account. - repeated cosmos.base.v1beta1.Coin pool_creation_fee = 2 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"pool_creation_fee\"", - (gogoproto.nullable) = false - ]; - - // The assets that can be used to create liquidity pools - repeated string whitelisted_asset = 3; -} diff --git a/proto/nibiru/spot/v1/pool.proto b/proto/nibiru/spot/v1/pool.proto deleted file mode 100644 index 3b2053d49..000000000 --- a/proto/nibiru/spot/v1/pool.proto +++ /dev/null @@ -1,97 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "cosmos_proto/cosmos.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -// Configuration parameters for the pool. -message PoolParams { - string swap_fee = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.moretags) = "yaml:\"swap_fee\"", - (gogoproto.nullable) = false - ]; - - string exit_fee = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.moretags) = "yaml:\"exit_fee\"", - (gogoproto.nullable) = false - ]; - - // Amplification Parameter (A): Larger value of A make the curve better - // resemble a straight line in the center (when pool is near balance). Highly - // volatile assets should use a lower value, while assets that are closer - // together may be best with a higher value. This is only used if the - // pool_type is set to 1 (stableswap) - string A = 3 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.moretags) = "yaml:\"amplification\"", - (gogoproto.nullable) = false - ]; - - nibiru.spot.v1.PoolType pool_type = 4 - [ (gogoproto.moretags) = "yaml:\"pool_type\"" ]; -} - -// - `balancer`: Balancer are pools defined by the equation xy=k, extended by -// the weighs introduced by Balancer. -// - `stableswap`: Stableswap pools are defined by a combination of -// constant-product and constant-sum pool -enum PoolType { - BALANCER = 0; - STABLESWAP = 1; -} - -// Which assets the pool contains. -message PoolAsset { - // Coins we are talking about, - // the denomination must be unique amongst all PoolAssets for this pool. - cosmos.base.v1beta1.Coin token = 1 - [ (gogoproto.moretags) = "yaml:\"token\"", (gogoproto.nullable) = false ]; - // Weight that is not normalized. This weight must be less than 2^50 - string weight = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.moretags) = "yaml:\"weight\"", - (gogoproto.nullable) = false - ]; -} - -message Pool { - option (gogoproto.goproto_getters) = false; - - // The pool id. - uint64 id = 1; - - // The pool account address. - string address = 2 [ (gogoproto.moretags) = "yaml:\"address\"" ]; - - // Fees and other pool-specific parameters. - nibiru.spot.v1.PoolParams pool_params = 3 [ - (gogoproto.moretags) = "yaml:\"pool_params\"", - (gogoproto.nullable) = false - ]; - - // These are assumed to be sorted by denomiation. - // They contain the pool asset and the information about the weight - repeated PoolAsset pool_assets = 4 [ - (gogoproto.moretags) = "yaml:\"pool_assets\"", - (gogoproto.nullable) = false - ]; - - // sum of all non-normalized pool weights - string total_weight = 5 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.moretags) = "yaml:\"total_weight\"", - (gogoproto.nullable) = false - ]; - - // sum of all LP tokens sent out - cosmos.base.v1beta1.Coin total_shares = 6 [ - (gogoproto.moretags) = "yaml:\"total_shares\"", - (gogoproto.nullable) = false - ]; -} diff --git a/proto/nibiru/spot/v1/query.proto b/proto/nibiru/spot/v1/query.proto deleted file mode 100644 index 5c63cc8bb..000000000 --- a/proto/nibiru/spot/v1/query.proto +++ /dev/null @@ -1,282 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; -import "nibiru/spot/v1/params.proto"; -import "nibiru/spot/v1/pool.proto"; -import "cosmos/base/v1beta1/coin.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -// Query defines the gRPC querier service. -service Query { - // Parameters of the spot module. - rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/nibiru/spot/params"; - } - - // Next available pool id number. - rpc PoolNumber(QueryPoolNumberRequest) returns (QueryPoolNumberResponse) { - option (google.api.http).get = "/nibiru/spot/pool_number"; - } - - // Fetch a pool by id. - rpc Pool(QueryPoolRequest) returns (QueryPoolResponse) { - option (google.api.http).get = "/nibiru/spot/pool"; - } - - // Returns all pools. - rpc Pools(QueryPoolsRequest) returns (QueryPoolsResponse) { - option (google.api.http).get = "/nibiru/spot/pools"; - } - - // Parameters of a single pool. - rpc PoolParams(QueryPoolParamsRequest) returns (QueryPoolParamsResponse) { - option (google.api.http).get = "/nibiru/spot/pools/{pool_id}/params"; - } - - // Number of pools. - rpc NumPools(QueryNumPoolsRequest) returns (QueryNumPoolsResponse) { - option (google.api.http).get = "/nibiru/spot/num_pools"; - } - - // Total liquidity across all pools. - rpc TotalLiquidity(QueryTotalLiquidityRequest) - returns (QueryTotalLiquidityResponse) { - option (google.api.http).get = "/nibiru/spot/total_liquidity"; - } - - // Total liquidity in a single pool. - rpc TotalPoolLiquidity(QueryTotalPoolLiquidityRequest) - returns (QueryTotalPoolLiquidityResponse) { - option (google.api.http).get = - "/nibiru/spot/pools/{pool_id}/total_pool_liquidity"; - } - - // Total shares in a single pool. - rpc TotalShares(QueryTotalSharesRequest) returns (QueryTotalSharesResponse) { - option (google.api.http).get = "/nibiru/spot/pools/{pool_id}/total_shares"; - } - - // Instantaneous price of an asset in a pool. - rpc SpotPrice(QuerySpotPriceRequest) returns (QuerySpotPriceResponse) { - option (google.api.http).get = "/nibiru/spot/pools/{pool_id}/prices"; - } - - // Estimates the amount of assets returned given an exact amount of tokens to - // swap. - rpc EstimateSwapExactAmountIn(QuerySwapExactAmountInRequest) - returns (QuerySwapExactAmountInResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/swap_exact_amount_in"; - } - - // Estimates the amount of tokens required to return the exact amount of - // assets requested. - rpc EstimateSwapExactAmountOut(QuerySwapExactAmountOutRequest) - returns (QuerySwapExactAmountOutResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/swap_exact_amount_out"; - } - - // Estimates the amount of pool shares returned given an amount of tokens to - // join. - rpc EstimateJoinExactAmountIn(QueryJoinExactAmountInRequest) - returns (QueryJoinExactAmountInResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/join_exact_amount_in"; - } - - // Estimates the amount of tokens required to obtain an exact amount of pool - // shares. - rpc EstimateJoinExactAmountOut(QueryJoinExactAmountOutRequest) - returns (QueryJoinExactAmountOutResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/join_exact_amount_out"; - } - - // Estimates the amount of tokens returned to the user given an exact amount - // of pool shares. - rpc EstimateExitExactAmountIn(QueryExitExactAmountInRequest) - returns (QueryExitExactAmountInResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/exit_exact_amount_in"; - } - - // Estimates the amount of pool shares required to extract an exact amount of - // tokens from the pool. - rpc EstimateExitExactAmountOut(QueryExitExactAmountOutRequest) - returns (QueryExitExactAmountOutResponse) { - option (google.api.http).get = - "/nibiru/spot/{pool_id}/estimate/exit_exact_amount_out"; - } -} - -// QueryParamsRequest is request type for the Query/Params RPC method. -message QueryParamsRequest {} -// QueryParamsResponse is response type for the Query/Params RPC method. -message QueryParamsResponse { - // params holds all the parameters of this module. - nibiru.spot.v1.Params params = 1 [ (gogoproto.nullable) = false ]; -} - -message QueryPoolNumberRequest {} -message QueryPoolNumberResponse { uint64 pool_id = 1; } - -message QueryPoolRequest { uint64 pool_id = 1; } -message QueryPoolResponse { nibiru.spot.v1.Pool pool = 1; } - -message QueryPoolsRequest { - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 1; -} -message QueryPoolsResponse { - repeated nibiru.spot.v1.Pool pools = 1; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - -message QueryPoolParamsRequest { uint64 pool_id = 1; } -message QueryPoolParamsResponse { nibiru.spot.v1.PoolParams pool_params = 1; } - -message QueryNumPoolsRequest {} -message QueryNumPoolsResponse { uint64 num_pools = 1; } - -// -------------------------------------------- -// Query total liquidity the protocol -message QueryTotalLiquidityRequest {} -message QueryTotalLiquidityResponse { - repeated cosmos.base.v1beta1.Coin liquidity = 1 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"liquidity\"", - (gogoproto.nullable) = false - ]; -} - -// -------------------------------------------- -// Query total liquidity for a pool -message QueryTotalPoolLiquidityRequest { uint64 pool_id = 1; } - -message QueryTotalPoolLiquidityResponse { - repeated cosmos.base.v1beta1.Coin liquidity = 1 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"liquidity\"", - (gogoproto.nullable) = false - ]; -} - -message QueryTotalSharesRequest { uint64 pool_id = 1; } -message QueryTotalSharesResponse { - // sum of all LP tokens sent out - cosmos.base.v1beta1.Coin total_shares = 1 [ - (gogoproto.moretags) = "yaml:\"total_shares\"", - (gogoproto.nullable) = false - ]; -} - -// Returns the amount of tokenInDenom to produce 1 tokenOutDenom -// For example, if the price of NIBI = 9.123 NUSD, then setting -// tokenInDenom=NUSD and tokenOutDenom=NIBI would give "9.123". -message QuerySpotPriceRequest { - uint64 pool_id = 1; - // the denomination of the token you are giving into the pool - string token_in_denom = 2; - // the denomination of the token you are taking out of the pool - string token_out_denom = 3; -} -message QuerySpotPriceResponse { string spot_price = 1; } - -// Given an exact amount of tokens in and a target tokenOutDenom, calculates -// the expected amount of tokens out received from a swap. -message QuerySwapExactAmountInRequest { - uint64 pool_id = 1; - cosmos.base.v1beta1.Coin token_in = 2 [ - (gogoproto.moretags) = "yaml:\"token_in\"", - (gogoproto.nullable) = false - ]; - string token_out_denom = 3; -} -message QuerySwapExactAmountInResponse { - cosmos.base.v1beta1.Coin token_out = 2 [ - (gogoproto.moretags) = "yaml:\"token_out\"", - (gogoproto.nullable) = false - ]; - cosmos.base.v1beta1.Coin fee = 3 - [ (gogoproto.moretags) = "yaml:\"fee\"", (gogoproto.nullable) = false ]; -} - -// Given an exact amount of tokens out and a target tokenInDenom, calculates -// the expected amount of tokens in required to do the swap. -message QuerySwapExactAmountOutRequest { - uint64 pool_id = 1; - cosmos.base.v1beta1.Coin token_out = 2 [ - (gogoproto.moretags) = "yaml:\"token_out\"", - (gogoproto.nullable) = false - ]; - string token_in_denom = 3; -} -message QuerySwapExactAmountOutResponse { - cosmos.base.v1beta1.Coin token_in = 2 [ - (gogoproto.moretags) = "yaml:\"token_in\"", - (gogoproto.nullable) = false - ]; -} - -message QueryJoinExactAmountInRequest { - uint64 pool_id = 1; - repeated cosmos.base.v1beta1.Coin tokens_in = 2 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"tokens_in\"", - (gogoproto.nullable) = false - ]; -} -message QueryJoinExactAmountInResponse { - - // amount of pool shares returned to user after join - string pool_shares_out = 1 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.moretags) = "yaml:\"pool_shares_out\"", - (gogoproto.nullable) = false - ]; - - // coins remaining after pool join - repeated cosmos.base.v1beta1.Coin rem_coins = 2 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"rem_coins\"", - (gogoproto.nullable) = false - ]; -} - -message QueryJoinExactAmountOutRequest { uint64 pool_id = 1; } -message QueryJoinExactAmountOutResponse {} - -message QueryExitExactAmountInRequest { - uint64 pool_id = 1; - // amount of pool shares to return to pool - string pool_shares_in = 2 [ - (gogoproto.customtype) = "cosmossdk.io/math.Int", - (gogoproto.moretags) = "yaml:\"pool_shares_in\"", - (gogoproto.nullable) = false - ]; -} -message QueryExitExactAmountInResponse { - // coins obtained after exiting - repeated cosmos.base.v1beta1.Coin tokens_out = 1 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"tokens_out\"", - (gogoproto.nullable) = false - ]; - - repeated cosmos.base.v1beta1.Coin fees = 2 [ - (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", - (gogoproto.moretags) = "yaml:\"fees\"", - (gogoproto.nullable) = false - ]; -} - -message QueryExitExactAmountOutRequest { uint64 pool_id = 1; } -message QueryExitExactAmountOutResponse {} diff --git a/proto/nibiru/spot/v1/tx.proto b/proto/nibiru/spot/v1/tx.proto deleted file mode 100644 index 8e9a3fc1c..000000000 --- a/proto/nibiru/spot/v1/tx.proto +++ /dev/null @@ -1,120 +0,0 @@ -syntax = "proto3"; - -package nibiru.spot.v1; - -import "nibiru/spot/v1/pool.proto"; -import "gogoproto/gogo.proto"; -import "cosmos/base/v1beta1/coin.proto"; -import "google/api/annotations.proto"; - -option go_package = "github.com/NibiruChain/nibiru/x/spot/types"; - -// Msg defines the Msg service. -service Msg { - // Used to create a pool. - rpc CreatePool(MsgCreatePool) returns (MsgCreatePoolResponse) { - option (google.api.http).post = "/nibiru/spot/pool"; - } - - // Join a pool as a liquidity provider. - rpc JoinPool(MsgJoinPool) returns (MsgJoinPoolResponse) { - option (google.api.http).post = "/nibiru/spot/{pool_id}/join"; - } - - // Exit a pool position by returning LP shares - rpc ExitPool(MsgExitPool) returns (MsgExitPoolResponse) { - option (google.api.http).post = "/nibiru/spot/{pool_id}/exit"; - } - - // Swap assets in a pool - rpc SwapAssets(MsgSwapAssets) returns (MsgSwapAssetsResponse) { - option (google.api.http).post = "/nibiru/spot/{pool_id}/swap"; - } -} - -message MsgCreatePool { - string creator = 1; - - nibiru.spot.v1.PoolParams pool_params = 2 - [ (gogoproto.moretags) = "yaml:\"pool_params\"" ]; - - repeated nibiru.spot.v1.PoolAsset pool_assets = 3 - [ (gogoproto.nullable) = false ]; -} - -message MsgCreatePoolResponse { uint64 pool_id = 1; } - -/* -Message to join a pool (identified by poolId) with a set of tokens to deposit. -*/ -message MsgJoinPool { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - - uint64 pool_id = 2 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ]; - - repeated cosmos.base.v1beta1.Coin tokens_in = 3 [ - (gogoproto.moretags) = "yaml:\"tokens_in\"", - (gogoproto.nullable) = false - ]; - - bool use_all_coins = 4 [ (gogoproto.moretags) = "yaml:\"use_all_coins\"" ]; -} - -/* -Response when a user joins a pool. -*/ -message MsgJoinPoolResponse { - // the final state of the pool after a join - nibiru.spot.v1.Pool pool = 1; - - // sum of LP tokens minted from the join - cosmos.base.v1beta1.Coin num_pool_shares_out = 2 [ - (gogoproto.moretags) = "yaml:\"num_pool_shares_out\"", - (gogoproto.nullable) = false - ]; - - // remaining tokens from attempting to join the pool - repeated cosmos.base.v1beta1.Coin remaining_coins = 3 [ - (gogoproto.moretags) = "yaml:\"tokens_in\"", - (gogoproto.nullable) = false - ]; -} - -message MsgExitPool { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - - uint64 pool_id = 2 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ]; - - cosmos.base.v1beta1.Coin pool_shares = 3 [ - (gogoproto.moretags) = "yaml:\"pool_shares\"", - (gogoproto.nullable) = false - ]; -} - -message MsgExitPoolResponse { - repeated cosmos.base.v1beta1.Coin tokens_out = 3 [ - (gogoproto.moretags) = "yaml:\"tokens_out\"", - (gogoproto.nullable) = false - ]; -} - -message MsgSwapAssets { - string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; - - uint64 pool_id = 2 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ]; - - cosmos.base.v1beta1.Coin token_in = 3 [ - (gogoproto.moretags) = "yaml:\"token_in\"", - (gogoproto.nullable) = false - ]; - - string token_out_denom = 4 - [ (gogoproto.moretags) = "yaml:\"token_out_denom\"" ]; -} - -message MsgSwapAssetsResponse { - cosmos.base.v1beta1.Coin token_out = 3 [ - (gogoproto.moretags) = "yaml:\"token_out\"", - (gogoproto.nullable) = false - ]; -} diff --git a/x/common/testutil/cli/network.go b/x/common/testutil/cli/network.go index 6652ef3c3..cd2b5333f 100644 --- a/x/common/testutil/cli/network.go +++ b/x/common/testutil/cli/network.go @@ -157,7 +157,7 @@ func BuildNetworkConfig(appGenesis app.GenesisState) Config { chainID := "chain-" + tmrand.NewRand().Str(6) return Config{ - Codec: encCfg.Marshaler, + Codec: encCfg.Codec, TxConfig: encCfg.TxConfig, LegacyAmino: encCfg.Amino, InterfaceRegistry: encCfg.InterfaceRegistry, diff --git a/x/common/testutil/cli/network_test.go b/x/common/testutil/cli/network_test.go index d9ace8ad2..6bafe6370 100644 --- a/x/common/testutil/cli/network_test.go +++ b/x/common/testutil/cli/network_test.go @@ -86,7 +86,7 @@ func (s *IntegrationTestSuite) TestNetwork_LatestHeight() { func (s *IntegrationTestSuite) TestLogMnemonic() { kring, algo, nodeDirName := cli.NewKeyring(s.T()) - var cdc sdkcodec.Codec = codec.MakeEncodingConfig().Marshaler + var cdc sdkcodec.Codec = codec.MakeEncodingConfig().Codec _, mnemonic, err := sdktestutil.GenerateCoinKey(algo, cdc) s.NoError(err) diff --git a/x/common/testutil/cli/util.go b/x/common/testutil/cli/util.go index 9e60c46ec..bd018371a 100644 --- a/x/common/testutil/cli/util.go +++ b/x/common/testutil/cli/util.go @@ -289,7 +289,7 @@ func NewKeyring(t *testing.T) ( algo keyring.SignatureAlgo, nodeDirName string, ) { - var cdc sdkcodec.Codec = codec.MakeEncodingConfig().Marshaler + var cdc sdkcodec.Codec = codec.MakeEncodingConfig().Codec kring = keyring.NewInMemory(cdc) nodeDirName = t.TempDir() algo = hd.Secp256k1 diff --git a/x/common/testutil/genesis/genesis.go b/x/common/testutil/genesis/genesis.go index 70837d526..8ed74dcdd 100644 --- a/x/common/testutil/genesis/genesis.go +++ b/x/common/testutil/genesis/genesis.go @@ -19,7 +19,7 @@ genesis as input. The blockchain genesis state is represented as a map from modu identifier strings to raw json messages. */ func NewTestGenesisState(encodingConfig app.EncodingConfig) app.GenesisState { - codec := encodingConfig.Marshaler + codec := encodingConfig.Codec genState := app.NewDefaultGenesisState(codec) // Set short voting period to allow fast gov proposals in tests diff --git a/x/common/testutil/genesis/oracle_genesis.go b/x/common/testutil/genesis/oracle_genesis.go index 5c366d93f..024fca05c 100644 --- a/x/common/testutil/genesis/oracle_genesis.go +++ b/x/common/testutil/genesis/oracle_genesis.go @@ -10,7 +10,7 @@ import ( ) func AddOracleGenesis(gen app.GenesisState) app.GenesisState { - gen[oracletypes.ModuleName] = app.MakeEncodingConfig().Marshaler. + gen[oracletypes.ModuleName] = app.MakeEncodingConfig().Codec. MustMarshalJSON(OracleGenesis()) return gen } diff --git a/x/common/testutil/genesis/sudo_genesis.go b/x/common/testutil/genesis/sudo_genesis.go index ce1a08c70..475a2649c 100644 --- a/x/common/testutil/genesis/sudo_genesis.go +++ b/x/common/testutil/genesis/sudo_genesis.go @@ -19,7 +19,7 @@ func AddSudoGenesis(gen app.GenesisState) ( rootAddr sdk.AccAddress, ) { sudoGenesis, rootPrivKey, rootAddr := SudoGenesis() - gen[sudotypes.ModuleName] = app.MakeEncodingConfig().Marshaler. + gen[sudotypes.ModuleName] = app.MakeEncodingConfig().Codec. MustMarshalJSON(sudoGenesis) return gen, rootPrivKey, rootAddr } diff --git a/x/common/testutil/testapp/testapp.go b/x/common/testutil/testapp/testapp.go index 7f94cdb1e..94280dfc8 100644 --- a/x/common/testutil/testapp/testapp.go +++ b/x/common/testutil/testapp/testapp.go @@ -36,18 +36,18 @@ func NewNibiruTestAppAndContext() (*app.NibiruApp, sdk.Context) { // Set up base app encoding := app.MakeEncodingConfig() - var appGenesis app.GenesisState = app.NewDefaultGenesisState(encoding.Marshaler) + var appGenesis app.GenesisState = app.NewDefaultGenesisState(encoding.Codec) genModEpochs := epochstypes.DefaultGenesisFromTime(time.Now().UTC()) // Set happy genesis: epochs - appGenesis[epochstypes.ModuleName] = encoding.Marshaler.MustMarshalJSON( + appGenesis[epochstypes.ModuleName] = encoding.Codec.MustMarshalJSON( genModEpochs, ) // Set happy genesis: sudo sudoGenesis := new(sudotypes.GenesisState) sudoGenesis.Sudoers = DefaultSudoers() - appGenesis[sudotypes.ModuleName] = encoding.Marshaler.MustMarshalJSON(sudoGenesis) + appGenesis[sudotypes.ModuleName] = encoding.Codec.MustMarshalJSON(sudoGenesis) app := NewNibiruTestApp(appGenesis) ctx := NewContext(app) @@ -86,10 +86,10 @@ func DefaultSudoRoot() sdk.AccAddress { func SetDefaultSudoGenesis(gen app.GenesisState) { sudoGen := new(sudotypes.GenesisState) encoding := app.MakeEncodingConfig() - encoding.Marshaler.MustUnmarshalJSON(gen[sudotypes.ModuleName], sudoGen) + encoding.Codec.MustUnmarshalJSON(gen[sudotypes.ModuleName], sudoGen) if err := sudoGen.Validate(); err != nil { sudoGen.Sudoers = DefaultSudoers() - gen[sudotypes.ModuleName] = encoding.Marshaler.MustMarshalJSON(sudoGen) + gen[sudotypes.ModuleName] = encoding.Codec.MustMarshalJSON(sudoGen) } } @@ -121,7 +121,7 @@ func NewNibiruTestApp(gen app.GenesisState, baseAppOptions ...func(*baseapp.Base baseAppOptions..., ) - gen, err := GenesisStateWithSingleValidator(encoding.Marshaler, gen) + gen, err := GenesisStateWithSingleValidator(encoding.Codec, gen) if err != nil { panic(err) } diff --git a/x/epochs/genesis_test.go b/x/epochs/genesis_test.go index 1f4b14cb2..88eda5256 100644 --- a/x/epochs/genesis_test.go +++ b/x/epochs/genesis_test.go @@ -20,7 +20,7 @@ func TestEpochsExportGenesis(t *testing.T) { encCfg := app.MakeEncodingConfig() appGenesis := genesis.NewTestGenesisState(encCfg) - appGenesis[types.ModuleName] = encCfg.Marshaler.MustMarshalJSON(moduleGenesisIn) + appGenesis[types.ModuleName] = encCfg.Codec.MustMarshalJSON(moduleGenesisIn) app := testapp.NewNibiruTestApp(appGenesis) ctx := testapp.NewContext(app).WithBlockTime(chainStartTime) diff --git a/x/evm/codec.go b/x/evm/codec.go index e2453a4dd..a382495ac 100644 --- a/x/evm/codec.go +++ b/x/evm/codec.go @@ -22,6 +22,12 @@ var ( AminoCdc = codec.NewAminoCodec(amino) ) +const ( + // Protobuf type URL for a consensus tx holding Ethereum transaction msgs. + // Corresponds with [ExtensionOptionsEthereumTx]. + TYPE_URL_ETHEREUM_TX = "/eth.evm.v1.ExtensionOptionsEthereumTx" +) + // NOTE: This is required for the GetSignBytes function func init() { RegisterLegacyAminoCodec(amino) diff --git a/x/evm/evmmodule/genesis.go b/x/evm/evmmodule/genesis.go index 8f146110d..0f1ba311f 100644 --- a/x/evm/evmmodule/genesis.go +++ b/x/evm/evmmodule/genesis.go @@ -2,9 +2,16 @@ package evmmodule import ( + "bytes" + "fmt" + abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + + "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/keeper" ) @@ -14,10 +21,49 @@ func InitGenesis( ctx sdk.Context, k *keeper.Keeper, accountKeeper evm.AccountKeeper, - data evm.GenesisState, + genState evm.GenesisState, ) []abci.ValidatorUpdate { k.BeginBlock(ctx, abci.RequestBeginBlock{}) - k.EvmState.ModuleParams.Set(ctx, data.Params) + k.SetParams(ctx, genState.Params) + + if addr := accountKeeper.GetModuleAddress(evm.ModuleName); addr == nil { + panic("the EVM module account has not been set") + } + + for _, account := range genState.Accounts { + address := gethcommon.HexToAddress(account.Address) + accAddress := sdk.AccAddress(address.Bytes()) + // check that the EVM balance the matches the account balance + acc := accountKeeper.GetAccount(ctx, accAddress) + if acc == nil { + panic(fmt.Errorf("account not found for address %s", account.Address)) + } + + ethAcct, ok := acc.(eth.EthAccountI) + if !ok { + panic( + fmt.Errorf("account %s must be an EthAccount interface, got %T", + account.Address, acc, + ), + ) + } + code := gethcommon.Hex2Bytes(account.Code) + codeHash := crypto.Keccak256Hash(code) + + // we ignore the empty Code hash checking, see ethermint PR#1234 + if len(account.Code) != 0 && !bytes.Equal(ethAcct.GetCodeHash().Bytes(), codeHash.Bytes()) { + s := "the evm state code doesn't match with the codehash\n" + panic(fmt.Sprintf("%s account: %s , evm state codehash: %v, ethAccount codehash: %v, evm state code: %s\n", + s, account.Address, codeHash, ethAcct.GetCodeHash(), account.Code)) + } + + k.SetCode(ctx, codeHash.Bytes(), code) + + for _, storage := range account.Storage { + k.SetState(ctx, address, gethcommon.HexToHash(storage.Key), gethcommon.HexToHash(storage.Value).Bytes()) + } + } + // TODO: impl InitGenesis return []abci.ValidatorUpdate{} } diff --git a/x/evm/evmmodule/module.go b/x/evm/evmmodule/module.go index 8b9f94ecc..e12366612 100644 --- a/x/evm/evmmodule/module.go +++ b/x/evm/evmmodule/module.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/module" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/cli" "github.com/NibiruChain/nibiru/x/evm/keeper" @@ -92,6 +93,7 @@ func (AppModuleBasic) GetQueryCmd() *cobra.Command { // RegisterInterfaces registers interfaces and implementations of the evm module. func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { evm.RegisterInterfaces(registry) + eth.RegisterInterfaces(registry) } // ____________________________________________________________________________ diff --git a/x/evm/evmtest/eth.go b/x/evm/evmtest/eth.go index 54f312dbf..8a2738be6 100644 --- a/x/evm/evmtest/eth.go +++ b/x/evm/evmtest/eth.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/NibiruChain/nibiru/eth/crypto/ethsecp256k1" - "github.com/NibiruChain/nibiru/eth/encoding" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/client" gethcommon "github.com/ethereum/go-ethereum/common" @@ -23,8 +23,21 @@ import ( // NewEthAddr generates an Ethereum address. func NewEthAddr() gethcommon.Address { - addr, _ := PrivKeyEth() - return addr + ethAddr, _ := PrivKeyEth() + return ethAddr +} + +func NewEthAddrNibiruPair() ( + ethAddr gethcommon.Address, + privKey *ethsecp256k1.PrivKey, + nibiruAddr sdk.AccAddress, +) { + ethAddr, privKey = PrivKeyEth() + return ethAddr, privKey, EthPrivKeyToNibiruAddr(ethAddr) +} + +func EthPrivKeyToNibiruAddr(ethAddr gethcommon.Address) sdk.AccAddress { + return sdk.AccAddress(ethAddr.Bytes()) } // PrivKeyEth returns an Ethereum private key and corresponding Eth address. @@ -66,7 +79,7 @@ func NewEthTxMsgAsCmt(t *testing.T) ( clientCtx client.Context, ) { // Build a TxBuilder that can understand Ethereum types - encCfg := encoding.MakeConfig(app.ModuleBasics) + encCfg := app.MakeEncodingConfig() evm.RegisterInterfaces(encCfg.InterfaceRegistry) eth.RegisterInterfaces(encCfg.InterfaceRegistry) txConfig := encCfg.TxConfig diff --git a/x/evm/keeper/evm_state.go b/x/evm/keeper/evm_state.go index 862323fd1..457268124 100644 --- a/x/evm/keeper/evm_state.go +++ b/x/evm/keeper/evm_state.go @@ -2,9 +2,13 @@ package keeper import ( + "fmt" + "slices" + "github.com/NibiruChain/collections" "github.com/cosmos/cosmos-sdk/codec" sdkstore "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/NibiruChain/nibiru/eth" @@ -86,3 +90,56 @@ func NewEvmState( ), } } + +// BytesToHex converts a byte array to a hexadecimal string +func BytesToHex(bz []byte) string { + return fmt.Sprintf("%x", bz) +} + +func (state EvmState) SetAccCode(ctx sdk.Context, codeHash, code []byte) { + if len(code) > 0 { + state.ContractBytecode.Insert(ctx, codeHash, code) + } else { + // Ignore collections "key not found" error because erasing an empty + // state is perfectly valid here. + _ = state.ContractBytecode.Delete(ctx, codeHash) + } +} + +func (state EvmState) GetContractBytecode( + ctx sdk.Context, codeHash []byte, +) (code []byte) { + return state.ContractBytecode.GetOr(ctx, codeHash, []byte{}) +} + +// GetParams returns the total set of evm parameters. +func (k Keeper) GetParams(ctx sdk.Context) (params evm.Params) { + params, _ = k.EvmState.ModuleParams.Get(ctx) + return params +} + +// SetParams: Setter for the module parameters. +func (k Keeper) SetParams(ctx sdk.Context, params evm.Params) { + slices.Sort(params.ActivePrecompiles) + k.EvmState.ModuleParams.Set(ctx, params) +} + +// SetState update contract storage, delete if value is empty. +func (state EvmState) SetAccState( + ctx sdk.Context, addr eth.EthAddr, stateKey eth.EthHash, stateValue []byte, +) { + if len(stateValue) != 0 { + state.AccState.Insert(ctx, collections.Join(addr, stateKey), stateValue) + } else { + _ = state.AccState.Delete(ctx, collections.Join(addr, stateKey)) + } +} + +// GetState: Implements `statedb.Keeper` interface: Loads smart contract state. +func (k *Keeper) GetState(ctx sdk.Context, addr eth.EthAddr, stateKey eth.EthHash) eth.EthHash { + return gethcommon.BytesToHash(k.EvmState.AccState.GetOr( + ctx, + collections.Join(addr, stateKey), + []byte{}, + )) +} diff --git a/x/evm/keeper/grpc_query.go b/x/evm/keeper/grpc_query.go index d259f8cad..ed1c69f16 100644 --- a/x/evm/keeper/grpc_query.go +++ b/x/evm/keeper/grpc_query.go @@ -16,46 +16,66 @@ import ( // Compile-time interface assertion var _ evm.QueryServer = Keeper{} -// Account: Implements the gRPC query for "/eth.evm.v1.Query/Account". -// Account retrieves the account details for a given Ethereum hex address. +// EthAccount: Implements the gRPC query for "/eth.evm.v1.Query/EthAccount". +// EthAccount retrieves the account details for a given Ethereum hex address. // // Parameters: // - goCtx: The context.Context object representing the request context. -// - req: The QueryAccountRequest object containing the Ethereum address. +// - req: Request containing the Ethereum hexadecimal address. // // Returns: -// - A pointer to the QueryAccountResponse object containing the account details. +// - A pointer to the QueryEthAccountResponse object containing the account details. // - An error if the account retrieval process encounters any issues. -func (k Keeper) Account( - goCtx context.Context, req *evm.QueryAccountRequest, -) (*evm.QueryAccountResponse, error) { - // TODO: feat(evm): impl query Account - return &evm.QueryAccountResponse{ - Balance: "", - CodeHash: "", - Nonce: 0, - }, common.ErrNotImplementedGprc() +func (k Keeper) EthAccount( + goCtx context.Context, req *evm.QueryEthAccountRequest, +) (*evm.QueryEthAccountResponse, error) { + if err := req.Validate(); err != nil { + return nil, err + } + + addr := gethcommon.HexToAddress(req.Address) + ctx := sdk.UnwrapSDKContext(goCtx) + acct := k.GetAccountOrEmpty(ctx, addr) + + return &evm.QueryEthAccountResponse{ + Balance: acct.Balance.String(), + CodeHash: gethcommon.BytesToHash(acct.CodeHash).Hex(), + Nonce: acct.Nonce, + }, nil } -// CosmosAccount: Implements the gRPC query for "/eth.evm.v1.Query/CosmosAccount". -// CosmosAccount retrieves the Cosmos account details for a given Ethereum address. +// NibiruAccount: Implements the gRPC query for "/eth.evm.v1.Query/NibiruAccount". +// NibiruAccount retrieves the Cosmos account details for a given Ethereum address. // // Parameters: // - goCtx: The context.Context object representing the request context. -// - req: The QueryCosmosAccountRequest object containing the Ethereum address. +// - req: The QueryNibiruAccountRequest object containing the Ethereum address. // // Returns: -// - A pointer to the QueryCosmosAccountResponse object containing the Cosmos account details. +// - A pointer to the QueryNibiruAccountResponse object containing the Cosmos account details. // - An error if the account retrieval process encounters any issues. -func (k Keeper) CosmosAccount( - goCtx context.Context, req *evm.QueryCosmosAccountRequest, -) (*evm.QueryCosmosAccountResponse, error) { - // TODO: feat(evm): impl query CosmosAccount - return &evm.QueryCosmosAccountResponse{ - CosmosAddress: "", - Sequence: 0, - AccountNumber: 0, - }, common.ErrNotImplementedGprc() +func (k Keeper) NibiruAccount( + goCtx context.Context, req *evm.QueryNibiruAccountRequest, +) (resp *evm.QueryNibiruAccountResponse, err error) { + if err := req.Validate(); err != nil { + return resp, err + } + + ctx := sdk.UnwrapSDKContext(goCtx) + ethAddr := gethcommon.HexToAddress(req.Address) + nibiruAddr := sdk.AccAddress(ethAddr.Bytes()) + + accountOrNil := k.accountKeeper.GetAccount(ctx, nibiruAddr) + resp = &evm.QueryNibiruAccountResponse{ + Address: nibiruAddr.String(), + } + + if accountOrNil != nil { + resp.Sequence = accountOrNil.GetSequence() + resp.AccountNumber = accountOrNil.GetAccountNumber() + } + + return resp, nil } // ValidatorAccount: Implements the gRPC query for "/eth.evm.v1.Query/ValidatorAccount". @@ -121,11 +141,23 @@ func (k Keeper) BaseFee( // Returns: // - A pointer to the QueryStorageResponse object containing the storage value. // - An error if the storage retrieval process encounters any issues. -func (k Keeper) Storage(goCtx context.Context, req *evm.QueryStorageRequest) (*evm.QueryStorageResponse, error) { - // TODO: feat(evm): impl query Storage +func (k Keeper) Storage( + goCtx context.Context, req *evm.QueryStorageRequest, +) (*evm.QueryStorageResponse, error) { + if err := req.Validate(); err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(goCtx) + + address := gethcommon.HexToAddress(req.Address) + key := gethcommon.HexToHash(req.Key) + + state := k.GetState(ctx, address, key) + stateHex := state.Hex() + return &evm.QueryStorageResponse{ - Value: "", - }, common.ErrNotImplementedGprc() + Value: stateHex, + }, nil } // Code: Implements the gRPC query for "/eth.evm.v1.Query/Code". @@ -157,10 +189,11 @@ func (k Keeper) Code(goCtx context.Context, req *evm.QueryCodeRequest) (*evm.Que // - A pointer to the QueryParamsResponse object containing the EVM module parameters. // - An error if the parameter retrieval process encounters any issues. func (k Keeper) Params(goCtx context.Context, _ *evm.QueryParamsRequest) (*evm.QueryParamsResponse, error) { - // TODO: feat(evm): impl query Params + ctx := sdk.UnwrapSDKContext(goCtx) + params := k.GetParams(ctx) return &evm.QueryParamsResponse{ - Params: evm.Params{}, - }, common.ErrNotImplementedGprc() + Params: params, + }, nil } // EthCall: Implements the gRPC query for "/eth.evm.v1.Query/EthCall". @@ -195,19 +228,19 @@ func (k Keeper) EstimateGas( return k.EstimateGasForEvmCallType(goCtx, req, evm.CallTypeRPC) } -// EstimateGas estimates the gas cost of a transaction. This can be called with -// the "eth_estimateGas" JSON-RPC method or an smart contract query. +// EstimateGasForEvmCallType estimates the gas cost of a transaction. This can be +// called with the "eth_estimateGas" JSON-RPC method or an smart contract query. // // When [EstimateGas] is called from the JSON-RPC client, we need to reset the -// gas meter before simulating the transaction (tx) to have an accurate gas estimate -// txs using EVM extensions. +// gas meter before simulating the transaction (tx) to have an accurate gas +// estimate txs using EVM extensions. // // Parameters: // - goCtx: The context.Context object representing the request context. // - req: The EthCallRequest object containing the transaction parameters. // // Returns: -// - A pointer to the EstimateGasResponse object containing the estimated gas cost. +// - A response containing the estimated gas cost. // - An error if the gas estimation process encounters any issues. func (k Keeper) EstimateGasForEvmCallType( goCtx context.Context, req *evm.EthCallRequest, fromType evm.CallType, diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go new file mode 100644 index 000000000..0943f4cd1 --- /dev/null +++ b/x/evm/keeper/grpc_query_test.go @@ -0,0 +1,192 @@ +package keeper_test + +import ( + "github.com/NibiruChain/nibiru/app" + "github.com/NibiruChain/nibiru/app/codec" + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/eth/crypto/ethsecp256k1" + "github.com/NibiruChain/nibiru/x/common/testutil/testapp" + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/evm/evmtest" + "github.com/NibiruChain/nibiru/x/evm/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" +) + +type TestDeps struct { + chain *app.NibiruApp + ctx sdk.Context + encCfg codec.EncodingConfig + k keeper.Keeper + genState *evm.GenesisState + sender Sender +} + +type Sender struct { + EthAddr gethcommon.Address + PrivKey *ethsecp256k1.PrivKey + NibiruAddr sdk.AccAddress +} + +func (s *KeeperSuite) SetupTest() TestDeps { + testapp.EnsureNibiruPrefix() + encCfg := app.MakeEncodingConfig() + evm.RegisterInterfaces(encCfg.InterfaceRegistry) + eth.RegisterInterfaces(encCfg.InterfaceRegistry) + chain, ctx := testapp.NewNibiruTestAppAndContext() + + ethAddr, privKey, nibiruAddr := evmtest.NewEthAddrNibiruPair() + return TestDeps{ + chain: chain, + ctx: ctx, + encCfg: encCfg, + k: chain.EvmKeeper, + genState: evm.DefaultGenesisState(), + sender: Sender{ + EthAddr: ethAddr, + PrivKey: privKey, + NibiruAddr: nibiruAddr, + }, + } +} + +func InvalidEthAddr() string { return "0x0000" } + +func (s *KeeperSuite) TestQueryNibiruAccount() { + type In = *evm.QueryNibiruAccountRequest + type Out = *evm.QueryNibiruAccountResponse + testCases := []struct { + name string + scenario func() ( + req In, + wantResp Out, + ) + wantErr string + }{ + { + name: "sad: msg validation", + scenario: func() (req In, wantResp Out) { + req = &evm.QueryNibiruAccountRequest{ + Address: InvalidEthAddr(), + } + wantResp = &evm.QueryNibiruAccountResponse{ + Address: sdk.AccAddress(gethcommon.Address{}.Bytes()).String(), + } + return req, wantResp + }, + wantErr: "not a valid ethereum hex addr", + }, + { + name: "happy", + scenario: func() (req In, wantResp Out) { + ethAddr, _, nibiruAddr := evmtest.NewEthAddrNibiruPair() + req = &evm.QueryNibiruAccountRequest{ + Address: ethAddr.String(), + } + wantResp = &evm.QueryNibiruAccountResponse{ + Address: nibiruAddr.String(), + Sequence: 0, + AccountNumber: 0, + } + return req, wantResp + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + req, wantResp := tc.scenario() + deps := s.SetupTest() + goCtx := sdk.WrapSDKContext(deps.ctx) + gotResp, err := deps.k.NibiruAccount(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.EqualValues(wantResp, gotResp) + }) + + } + +} + +func (s *KeeperSuite) TestQueryEthAccount() { + + type In = *evm.QueryEthAccountRequest + type Out = *evm.QueryEthAccountResponse + testCases := []struct { + name string + scenario func(deps *TestDeps) ( + req In, + wantResp Out, + ) + // Optional setup function to create the scenario + setup func(deps *TestDeps) + wantErr string + }{ + { + name: "sad: msg validation", + scenario: func(deps *TestDeps) (req In, wantResp Out) { + req = &evm.QueryEthAccountRequest{ + Address: InvalidEthAddr(), + } + wantResp = &evm.QueryEthAccountResponse{ + Balance: "0", + CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(), + Nonce: 0, + } + return req, wantResp + }, + wantErr: "not a valid ethereum hex addr", + }, + { + name: "happy: fund account + query", + scenario: func(deps *TestDeps) (req In, wantResp Out) { + req = &evm.QueryEthAccountRequest{ + Address: deps.sender.EthAddr.Hex(), + } + wantResp = &evm.QueryEthAccountResponse{ + Balance: "420", + CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(), + Nonce: 0, + } + return req, wantResp + }, + setup: func(deps *TestDeps) { + chain := deps.chain + ethAddr := deps.sender.EthAddr + + // fund account with 420 tokens + coins := sdk.Coins{sdk.NewInt64Coin(evm.DefaultEVMDenom, 420)} + err := chain.BankKeeper.MintCoins(deps.ctx, evm.ModuleName, coins) + s.NoError(err) + err = chain.BankKeeper.SendCoinsFromModuleToAccount( + deps.ctx, evm.ModuleName, ethAddr.Bytes(), coins) + s.Require().NoError(err) + }, + wantErr: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + deps := s.SetupTest() + req, wantResp := tc.scenario(&deps) + if tc.setup != nil { + tc.setup(&deps) + } + goCtx := sdk.WrapSDKContext(deps.ctx) + gotResp, err := deps.k.EthAccount(goCtx, req) + if tc.wantErr != "" { + s.Require().ErrorContains(err, tc.wantErr) + return + } + s.Assert().NoError(err) + s.EqualValues(wantResp, gotResp) + }) + + } + +} diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 09c38ae19..02d313b8b 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -26,23 +26,28 @@ type Keeper struct { // the address capable of executing a MsgUpdateParams message. Typically, this should be the x/gov module account. authority sdk.AccAddress - bankKeeper evm.BankKeeper + bankKeeper evm.BankKeeper + accountKeeper evm.AccountKeeper } func NewKeeper( cdc codec.BinaryCodec, storeKey, transientKey storetypes.StoreKey, authority sdk.AccAddress, + accKeeper evm.AccountKeeper, + bankKeeper evm.BankKeeper, ) Keeper { if err := sdk.VerifyAddressFormat(authority); err != nil { panic(err) } return Keeper{ - cdc: cdc, - storeKey: storeKey, - transientKey: transientKey, - authority: authority, - EvmState: NewEvmState(cdc, storeKey, transientKey), + cdc: cdc, + storeKey: storeKey, + transientKey: transientKey, + authority: authority, + EvmState: NewEvmState(cdc, storeKey, transientKey), + accountKeeper: accKeeper, + bankKeeper: bankKeeper, } } @@ -60,9 +65,3 @@ func (k *Keeper) GetEvmGasBalance(ctx sdk.Context, addr gethcommon.Address) *big coin := k.bankKeeper.GetBalance(ctx, cosmosAddr, evmDenom) return coin.Amount.BigInt() } - -// GetParams returns the total set of evm parameters. -func (k Keeper) GetParams(ctx sdk.Context) (params evm.Params) { - params, _ = k.EvmState.ModuleParams.Get(ctx) - return params -} diff --git a/x/evm/keeper/keeper_test.go b/x/evm/keeper/keeper_test.go index a9c4ede8e..8221cc854 100644 --- a/x/evm/keeper/keeper_test.go +++ b/x/evm/keeper/keeper_test.go @@ -44,14 +44,6 @@ func (s *KeeperSuite) TestQuerier() { goCtx := sdk.WrapSDKContext(ctx) k := chain.EvmKeeper for _, testCase := range []func() error{ - func() error { - _, err := k.Account(goCtx, nil) - return err - }, - func() error { - _, err := k.CosmosAccount(goCtx, nil) - return err - }, func() error { _, err := k.ValidatorAccount(goCtx, nil) return err @@ -60,18 +52,10 @@ func (s *KeeperSuite) TestQuerier() { _, err := k.BaseFee(goCtx, nil) return err }, - func() error { - _, err := k.Storage(goCtx, nil) - return err - }, func() error { _, err := k.Code(goCtx, nil) return err }, - func() error { - _, err := k.Params(goCtx, nil) - return err - }, func() error { _, err := k.EthCall(goCtx, nil) return err diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go new file mode 100644 index 000000000..0c15127f1 --- /dev/null +++ b/x/evm/keeper/statedb.go @@ -0,0 +1,77 @@ +// Copyright (c) 2023-2024 Nibi, Inc. +package keeper + +import ( + "math/big" + + "github.com/NibiruChain/nibiru/eth" + "github.com/NibiruChain/nibiru/x/evm" + "github.com/NibiruChain/nibiru/x/evm/statedb" + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" +) + +// SetState: Update contract storage, delete if value is empty. +// Implements the `statedb.Keeper` interface. +// Only called by `StateDB.Commit()`. +func (k *Keeper) SetState( + ctx sdk.Context, addr gethcommon.Address, stateKey gethcommon.Hash, stateValue []byte, +) { + k.EvmState.SetAccState(ctx, addr, stateKey, stateValue) +} + +// SetCode: Setter for smart contract bytecode. Delete if code is empty. +// Implements the `statedb.Keeper` interface. +// Only called by `StateDB.Commit()`. +func (k *Keeper) SetCode(ctx sdk.Context, codeHash, code []byte) { + k.EvmState.SetAccCode(ctx, codeHash, code) +} + +// GetAccount: Ethereum account getter for a [statedb.Account]. +// Implements the `statedb.Keeper` interface. +// Returns nil if the account does not not exist or has the wrong type. +func (k *Keeper) GetAccount(ctx sdk.Context, addr gethcommon.Address) *statedb.Account { + acct := k.GetAccountWithoutBalance(ctx, addr) + if acct == nil { + return nil + } + + acct.Balance = k.GetEvmGasBalance(ctx, addr) + return acct +} + +// GetAccountOrEmpty returns empty account if not exist, returns error if it's not `EthAccount` +func (k *Keeper) GetAccountOrEmpty( + ctx sdk.Context, addr gethcommon.Address, +) statedb.Account { + acct := k.GetAccount(ctx, addr) + if acct != nil { + return *acct + } + // empty account + return statedb.Account{ + Balance: new(big.Int), + CodeHash: evm.EmptyCodeHash, + } +} + +// GetAccountWithoutBalance load nonce and codehash without balance, +// more efficient in cases where balance is not needed. +func (k *Keeper) GetAccountWithoutBalance(ctx sdk.Context, addr gethcommon.Address) *statedb.Account { + nibiruAddr := sdk.AccAddress(addr.Bytes()) + acct := k.accountKeeper.GetAccount(ctx, nibiruAddr) + if acct == nil { + return nil + } + + codeHash := evm.EmptyCodeHash + ethAcct, ok := acct.(eth.EthAccountI) + if ok { + codeHash = ethAcct.GetCodeHash().Bytes() + } + + return &statedb.Account{ + Nonce: acct.GetSequence(), + CodeHash: codeHash, + } +} diff --git a/x/evm/msg.go b/x/evm/msg.go index 5f0c2017b..ba8a9e830 100644 --- a/x/evm/msg.go +++ b/x/evm/msg.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" gethcore "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" ) var ( @@ -446,3 +447,5 @@ func DecodeTxResponse(in []byte) (*MsgEthereumTxResponse, error) { return &res, nil } + +var EmptyCodeHash = crypto.Keccak256(nil) diff --git a/x/evm/query.go b/x/evm/query.go index f04cc4d14..07ecdcf89 100644 --- a/x/evm/query.go +++ b/x/evm/query.go @@ -29,7 +29,7 @@ func (m QueryTraceBlockRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker return nil } -func (req *QueryAccountRequest) Validate() error { +func (req *QueryEthAccountRequest) Validate() error { if req == nil { return common.ErrNilGrpcMsg() } @@ -41,7 +41,7 @@ func (req *QueryAccountRequest) Validate() error { return nil } -func (req *QueryCosmosAccountRequest) Validate() error { +func (req *QueryNibiruAccountRequest) Validate() error { if req == nil { return common.ErrNilGrpcMsg() } diff --git a/x/evm/query.pb.go b/x/evm/query.pb.go index 36e94537e..052d10057 100644 --- a/x/evm/query.pb.go +++ b/x/evm/query.pb.go @@ -36,24 +36,24 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// QueryAccountRequest is the request type for the Query/Account RPC method. -type QueryAccountRequest struct { +// QueryEthAccountRequest is the request type for the Query/Account RPC method. +type QueryEthAccountRequest struct { // address is the ethereum hex address to query the account for. Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } -func (m *QueryAccountRequest) Reset() { *m = QueryAccountRequest{} } -func (m *QueryAccountRequest) String() string { return proto.CompactTextString(m) } -func (*QueryAccountRequest) ProtoMessage() {} -func (*QueryAccountRequest) Descriptor() ([]byte, []int) { +func (m *QueryEthAccountRequest) Reset() { *m = QueryEthAccountRequest{} } +func (m *QueryEthAccountRequest) String() string { return proto.CompactTextString(m) } +func (*QueryEthAccountRequest) ProtoMessage() {} +func (*QueryEthAccountRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ffa36cdc5add14ed, []int{0} } -func (m *QueryAccountRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryEthAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryEthAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryAccountRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryEthAccountRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -63,20 +63,20 @@ func (m *QueryAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, return b[:n], nil } } -func (m *QueryAccountRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAccountRequest.Merge(m, src) +func (m *QueryEthAccountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEthAccountRequest.Merge(m, src) } -func (m *QueryAccountRequest) XXX_Size() int { +func (m *QueryEthAccountRequest) XXX_Size() int { return m.Size() } -func (m *QueryAccountRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAccountRequest.DiscardUnknown(m) +func (m *QueryEthAccountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEthAccountRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryAccountRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryEthAccountRequest proto.InternalMessageInfo -// QueryAccountResponse is the response type for the Query/Account RPC method. -type QueryAccountResponse struct { +// QueryEthAccountResponse is the response type for the Query/Account RPC method. +type QueryEthAccountResponse struct { // balance is the balance of the EVM denomination. Balance string `protobuf:"bytes,1,opt,name=balance,proto3" json:"balance,omitempty"` // code_hash is the hex-formatted code bytes from the EOA. @@ -85,18 +85,18 @@ type QueryAccountResponse struct { Nonce uint64 `protobuf:"varint,3,opt,name=nonce,proto3" json:"nonce,omitempty"` } -func (m *QueryAccountResponse) Reset() { *m = QueryAccountResponse{} } -func (m *QueryAccountResponse) String() string { return proto.CompactTextString(m) } -func (*QueryAccountResponse) ProtoMessage() {} -func (*QueryAccountResponse) Descriptor() ([]byte, []int) { +func (m *QueryEthAccountResponse) Reset() { *m = QueryEthAccountResponse{} } +func (m *QueryEthAccountResponse) String() string { return proto.CompactTextString(m) } +func (*QueryEthAccountResponse) ProtoMessage() {} +func (*QueryEthAccountResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ffa36cdc5add14ed, []int{1} } -func (m *QueryAccountResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryEthAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryEthAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryAccountResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryEthAccountResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -106,58 +106,58 @@ func (m *QueryAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte return b[:n], nil } } -func (m *QueryAccountResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryAccountResponse.Merge(m, src) +func (m *QueryEthAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEthAccountResponse.Merge(m, src) } -func (m *QueryAccountResponse) XXX_Size() int { +func (m *QueryEthAccountResponse) XXX_Size() int { return m.Size() } -func (m *QueryAccountResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryAccountResponse.DiscardUnknown(m) +func (m *QueryEthAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEthAccountResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryAccountResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryEthAccountResponse proto.InternalMessageInfo -func (m *QueryAccountResponse) GetBalance() string { +func (m *QueryEthAccountResponse) GetBalance() string { if m != nil { return m.Balance } return "" } -func (m *QueryAccountResponse) GetCodeHash() string { +func (m *QueryEthAccountResponse) GetCodeHash() string { if m != nil { return m.CodeHash } return "" } -func (m *QueryAccountResponse) GetNonce() uint64 { +func (m *QueryEthAccountResponse) GetNonce() uint64 { if m != nil { return m.Nonce } return 0 } -// QueryCosmosAccountRequest is the request type for the Query/CosmosAccount RPC +// QueryNibiruAccountRequest is the request type for the Query/NibiruAccount RPC // method. -type QueryCosmosAccountRequest struct { +type QueryNibiruAccountRequest struct { // address is the ethereum hex address to query the account for. Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` } -func (m *QueryCosmosAccountRequest) Reset() { *m = QueryCosmosAccountRequest{} } -func (m *QueryCosmosAccountRequest) String() string { return proto.CompactTextString(m) } -func (*QueryCosmosAccountRequest) ProtoMessage() {} -func (*QueryCosmosAccountRequest) Descriptor() ([]byte, []int) { +func (m *QueryNibiruAccountRequest) Reset() { *m = QueryNibiruAccountRequest{} } +func (m *QueryNibiruAccountRequest) String() string { return proto.CompactTextString(m) } +func (*QueryNibiruAccountRequest) ProtoMessage() {} +func (*QueryNibiruAccountRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ffa36cdc5add14ed, []int{2} } -func (m *QueryCosmosAccountRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryNibiruAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryCosmosAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryNibiruAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryCosmosAccountRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryNibiruAccountRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -167,41 +167,41 @@ func (m *QueryCosmosAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([ return b[:n], nil } } -func (m *QueryCosmosAccountRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryCosmosAccountRequest.Merge(m, src) +func (m *QueryNibiruAccountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryNibiruAccountRequest.Merge(m, src) } -func (m *QueryCosmosAccountRequest) XXX_Size() int { +func (m *QueryNibiruAccountRequest) XXX_Size() int { return m.Size() } -func (m *QueryCosmosAccountRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryCosmosAccountRequest.DiscardUnknown(m) +func (m *QueryNibiruAccountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryNibiruAccountRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryCosmosAccountRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryNibiruAccountRequest proto.InternalMessageInfo -// QueryCosmosAccountResponse is the response type for the Query/CosmosAccount +// QueryNibiruAccountResponse is the response type for the Query/NibiruAccount // RPC method. -type QueryCosmosAccountResponse struct { - // cosmos_address is the cosmos address of the account. - CosmosAddress string `protobuf:"bytes,1,opt,name=cosmos_address,json=cosmosAddress,proto3" json:"cosmos_address,omitempty"` +type QueryNibiruAccountResponse struct { + // Nibiru bech32 account "address" + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // sequence is the account's sequence number. Sequence uint64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"` // account_number is the account number AccountNumber uint64 `protobuf:"varint,3,opt,name=account_number,json=accountNumber,proto3" json:"account_number,omitempty"` } -func (m *QueryCosmosAccountResponse) Reset() { *m = QueryCosmosAccountResponse{} } -func (m *QueryCosmosAccountResponse) String() string { return proto.CompactTextString(m) } -func (*QueryCosmosAccountResponse) ProtoMessage() {} -func (*QueryCosmosAccountResponse) Descriptor() ([]byte, []int) { +func (m *QueryNibiruAccountResponse) Reset() { *m = QueryNibiruAccountResponse{} } +func (m *QueryNibiruAccountResponse) String() string { return proto.CompactTextString(m) } +func (*QueryNibiruAccountResponse) ProtoMessage() {} +func (*QueryNibiruAccountResponse) Descriptor() ([]byte, []int) { return fileDescriptor_ffa36cdc5add14ed, []int{3} } -func (m *QueryCosmosAccountResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryNibiruAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryCosmosAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryNibiruAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryCosmosAccountResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryNibiruAccountResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -211,33 +211,33 @@ func (m *QueryCosmosAccountResponse) XXX_Marshal(b []byte, deterministic bool) ( return b[:n], nil } } -func (m *QueryCosmosAccountResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryCosmosAccountResponse.Merge(m, src) +func (m *QueryNibiruAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryNibiruAccountResponse.Merge(m, src) } -func (m *QueryCosmosAccountResponse) XXX_Size() int { +func (m *QueryNibiruAccountResponse) XXX_Size() int { return m.Size() } -func (m *QueryCosmosAccountResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryCosmosAccountResponse.DiscardUnknown(m) +func (m *QueryNibiruAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryNibiruAccountResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryCosmosAccountResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryNibiruAccountResponse proto.InternalMessageInfo -func (m *QueryCosmosAccountResponse) GetCosmosAddress() string { +func (m *QueryNibiruAccountResponse) GetAddress() string { if m != nil { - return m.CosmosAddress + return m.Address } return "" } -func (m *QueryCosmosAccountResponse) GetSequence() uint64 { +func (m *QueryNibiruAccountResponse) GetSequence() uint64 { if m != nil { return m.Sequence } return 0 } -func (m *QueryCosmosAccountResponse) GetAccountNumber() uint64 { +func (m *QueryNibiruAccountResponse) GetAccountNumber() uint64 { if m != nil { return m.AccountNumber } @@ -287,7 +287,7 @@ var xxx_messageInfo_QueryValidatorAccountRequest proto.InternalMessageInfo // QueryValidatorAccountResponse is the response type for the // Query/ValidatorAccount RPC method. type QueryValidatorAccountResponse struct { - // account_address is the cosmos address of the account in bech32 format. + // account_address is the Nibiru address of the account in bech32 format. AccountAddress string `protobuf:"bytes,1,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` // sequence is the account's sequence number. Sequence uint64 `protobuf:"varint,2,opt,name=sequence,proto3" json:"sequence,omitempty"` @@ -1304,10 +1304,10 @@ func (m *QueryBaseFeeResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryBaseFeeResponse proto.InternalMessageInfo func init() { - proto.RegisterType((*QueryAccountRequest)(nil), "eth.evm.v1.QueryAccountRequest") - proto.RegisterType((*QueryAccountResponse)(nil), "eth.evm.v1.QueryAccountResponse") - proto.RegisterType((*QueryCosmosAccountRequest)(nil), "eth.evm.v1.QueryCosmosAccountRequest") - proto.RegisterType((*QueryCosmosAccountResponse)(nil), "eth.evm.v1.QueryCosmosAccountResponse") + proto.RegisterType((*QueryEthAccountRequest)(nil), "eth.evm.v1.QueryEthAccountRequest") + proto.RegisterType((*QueryEthAccountResponse)(nil), "eth.evm.v1.QueryEthAccountResponse") + proto.RegisterType((*QueryNibiruAccountRequest)(nil), "eth.evm.v1.QueryNibiruAccountRequest") + proto.RegisterType((*QueryNibiruAccountResponse)(nil), "eth.evm.v1.QueryNibiruAccountResponse") proto.RegisterType((*QueryValidatorAccountRequest)(nil), "eth.evm.v1.QueryValidatorAccountRequest") proto.RegisterType((*QueryValidatorAccountResponse)(nil), "eth.evm.v1.QueryValidatorAccountResponse") proto.RegisterType((*QueryBalanceRequest)(nil), "eth.evm.v1.QueryBalanceRequest") @@ -1333,98 +1333,98 @@ func init() { func init() { proto.RegisterFile("eth/evm/v1/query.proto", fileDescriptor_ffa36cdc5add14ed) } var fileDescriptor_ffa36cdc5add14ed = []byte{ - // 1456 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4f, 0x6f, 0xdb, 0xc6, - 0x12, 0x37, 0x2d, 0xd9, 0x92, 0x57, 0x76, 0xe2, 0xb7, 0x71, 0x62, 0x9b, 0xb1, 0x25, 0x87, 0x46, - 0x6c, 0x25, 0xef, 0x85, 0x8c, 0xfd, 0x1e, 0x5e, 0xd1, 0x00, 0x41, 0x11, 0x09, 0x89, 0x9b, 0xe6, - 0x0f, 0x52, 0xd5, 0xe8, 0xa1, 0x40, 0x21, 0xac, 0xa8, 0x0d, 0x45, 0x58, 0xe4, 0x2a, 0xdc, 0x95, - 0x2a, 0x37, 0xcd, 0xa5, 0x05, 0x8a, 0x02, 0x3d, 0x34, 0x40, 0xbf, 0x40, 0x4e, 0xfd, 0x0a, 0xf9, - 0x0a, 0x39, 0x06, 0xe8, 0xa5, 0xe8, 0x21, 0x2d, 0x92, 0x1e, 0x7a, 0xee, 0xb1, 0xa7, 0x62, 0xff, - 0x49, 0xa4, 0x44, 0xd9, 0x4d, 0xff, 0xdc, 0x7a, 0x22, 0x77, 0x77, 0x66, 0x7e, 0xbf, 0xd9, 0x99, - 0x9d, 0x19, 0x70, 0x06, 0xb3, 0x96, 0x83, 0x7b, 0x81, 0xd3, 0xdb, 0x71, 0x1e, 0x74, 0x71, 0x74, - 0x68, 0x77, 0x22, 0xc2, 0x08, 0x04, 0x98, 0xb5, 0x6c, 0xdc, 0x0b, 0xec, 0xde, 0x8e, 0x79, 0xd1, - 0x25, 0x34, 0x20, 0xd4, 0x69, 0x20, 0x8a, 0xa5, 0x90, 0xd3, 0xdb, 0x69, 0x60, 0x86, 0x76, 0x9c, - 0x0e, 0xf2, 0xfc, 0x10, 0x31, 0x9f, 0x84, 0x52, 0xcf, 0x5c, 0x8a, 0xd9, 0xe3, 0xea, 0x72, 0xf7, - 0x54, 0x6c, 0x97, 0xf5, 0xb5, 0xa8, 0x47, 0x3c, 0x22, 0x7e, 0x1d, 0xfe, 0xa7, 0x76, 0xd7, 0x3c, - 0x42, 0xbc, 0x36, 0x76, 0x50, 0xc7, 0x77, 0x50, 0x18, 0x12, 0x26, 0xac, 0x53, 0x75, 0x5a, 0x52, - 0xa7, 0x62, 0xd5, 0xe8, 0xde, 0x77, 0x98, 0x1f, 0x60, 0xca, 0x50, 0xd0, 0x91, 0x02, 0xd6, 0x9b, - 0xe0, 0xd4, 0xbb, 0x9c, 0xe1, 0x35, 0xd7, 0x25, 0xdd, 0x90, 0xd5, 0xf0, 0x83, 0x2e, 0xa6, 0x0c, - 0xae, 0x80, 0x1c, 0x6a, 0x36, 0x23, 0x4c, 0xe9, 0x8a, 0xb1, 0x61, 0x94, 0xe7, 0x6a, 0x7a, 0x79, - 0x25, 0xff, 0xc5, 0x93, 0xd2, 0xd4, 0xcf, 0x4f, 0x4a, 0x53, 0x96, 0x0b, 0x96, 0x92, 0xaa, 0xb4, - 0x43, 0x42, 0x8a, 0xb9, 0x6e, 0x03, 0xb5, 0x51, 0xe8, 0x62, 0xad, 0xab, 0x96, 0xf0, 0x2c, 0x98, - 0x73, 0x49, 0x13, 0xd7, 0x5b, 0x88, 0xb6, 0x56, 0xa6, 0xc5, 0x59, 0x9e, 0x6f, 0xbc, 0x8d, 0x68, - 0x0b, 0x2e, 0x81, 0x99, 0x90, 0x70, 0xa5, 0xcc, 0x86, 0x51, 0xce, 0xd6, 0xe4, 0xc2, 0x7a, 0x0b, - 0xac, 0x0a, 0x90, 0xaa, 0xb8, 0xd2, 0x3f, 0xc0, 0xf2, 0x73, 0x03, 0x98, 0x69, 0x16, 0x14, 0xd9, - 0xf3, 0xe0, 0x84, 0x8c, 0x56, 0x3d, 0x69, 0x69, 0x41, 0xee, 0x5e, 0x93, 0x9b, 0xd0, 0x04, 0x79, - 0xca, 0x41, 0x39, 0xbf, 0x69, 0xc1, 0x6f, 0xb0, 0xe6, 0x26, 0x90, 0xb4, 0x5a, 0x0f, 0xbb, 0x41, - 0x03, 0x47, 0xca, 0x83, 0x05, 0xb5, 0x7b, 0x57, 0x6c, 0x5a, 0xb7, 0xc0, 0x9a, 0xe0, 0xf1, 0x3e, - 0x6a, 0xfb, 0x4d, 0xc4, 0x48, 0x34, 0xe2, 0xcc, 0x39, 0x30, 0xef, 0x92, 0x70, 0x94, 0x47, 0x81, - 0xef, 0x5d, 0x1b, 0xf3, 0xea, 0x4b, 0x03, 0xac, 0x4f, 0xb0, 0xa6, 0x1c, 0xdb, 0x06, 0x27, 0x35, - 0xab, 0xa4, 0x45, 0x4d, 0xf6, 0x2f, 0x74, 0x4d, 0x27, 0x51, 0x45, 0xc6, 0xf9, 0x75, 0xc2, 0x73, - 0x59, 0x25, 0xd1, 0x40, 0xf5, 0xb8, 0x24, 0xb2, 0x6e, 0x29, 0xb0, 0xf7, 0x18, 0x89, 0x90, 0x77, - 0x3c, 0x18, 0x5c, 0x04, 0x99, 0x03, 0x7c, 0xa8, 0xf2, 0x8d, 0xff, 0xc6, 0xe0, 0xff, 0xa3, 0xe0, - 0x07, 0xc6, 0x14, 0xfc, 0x12, 0x98, 0xe9, 0xa1, 0x76, 0x57, 0x83, 0xcb, 0x85, 0xf5, 0x7f, 0xb0, - 0xa8, 0x52, 0xa9, 0xf9, 0x5a, 0x4e, 0x6e, 0x83, 0x7f, 0xc5, 0xf4, 0x14, 0x04, 0x04, 0x59, 0x9e, - 0xfb, 0x42, 0x6b, 0xbe, 0x26, 0xfe, 0xad, 0x8f, 0x01, 0x14, 0x82, 0xfb, 0xfd, 0xdb, 0xc4, 0xa3, - 0x1a, 0x02, 0x82, 0xac, 0x78, 0x31, 0xd2, 0xbe, 0xf8, 0x87, 0x37, 0x00, 0x18, 0xd6, 0x12, 0xe1, - 0x5b, 0x61, 0x77, 0xcb, 0x96, 0x49, 0x6b, 0xf3, 0xc2, 0x63, 0xcb, 0xea, 0xa4, 0x0a, 0x8f, 0x7d, - 0x6f, 0x78, 0x55, 0xb5, 0x98, 0x66, 0x8c, 0xe4, 0x67, 0x86, 0xba, 0x58, 0x0d, 0xae, 0x78, 0x6e, - 0x82, 0x6c, 0x9b, 0x78, 0xdc, 0xbb, 0x4c, 0xb9, 0xb0, 0x7b, 0xd2, 0x1e, 0x16, 0x3a, 0xfb, 0x36, - 0xf1, 0x6a, 0xe2, 0x10, 0xee, 0xa5, 0xd0, 0xd9, 0x3e, 0x96, 0x8e, 0x44, 0x88, 0xf3, 0xb1, 0x96, - 0xd4, 0x0d, 0xdc, 0x43, 0x11, 0x0a, 0xf4, 0x0d, 0x58, 0x7b, 0x8a, 0x9a, 0xde, 0x55, 0xd4, 0x2e, - 0x83, 0xd9, 0x8e, 0xd8, 0x11, 0x57, 0x53, 0xd8, 0x85, 0x71, 0x72, 0x52, 0xb6, 0x92, 0x7d, 0xf6, - 0xa2, 0x34, 0x55, 0x53, 0x72, 0xd6, 0x53, 0x03, 0x9c, 0xb8, 0xce, 0x5a, 0x55, 0xd4, 0x6e, 0xc7, - 0x6e, 0x17, 0x45, 0x1e, 0xd5, 0x71, 0xe0, 0xff, 0x70, 0x19, 0xe4, 0x3c, 0x44, 0xeb, 0x2e, 0xea, - 0xa8, 0x27, 0x31, 0xeb, 0x21, 0x5a, 0x45, 0x1d, 0xf8, 0x21, 0x58, 0xec, 0x44, 0xa4, 0x43, 0x28, - 0x8e, 0x06, 0xcf, 0x8a, 0x3f, 0x89, 0xf9, 0xca, 0xee, 0xaf, 0x2f, 0x4a, 0xb6, 0xe7, 0xb3, 0x56, - 0xb7, 0x61, 0xbb, 0x24, 0x70, 0x54, 0x0f, 0x90, 0x9f, 0x4b, 0xb4, 0x79, 0xe0, 0xb0, 0xc3, 0x0e, - 0xa6, 0x76, 0x75, 0xf8, 0x9e, 0x6b, 0x27, 0xb5, 0x2d, 0xfd, 0x16, 0x57, 0x41, 0xde, 0x6d, 0x21, - 0x3f, 0xac, 0xfb, 0xcd, 0x95, 0xec, 0x86, 0x51, 0xce, 0xd4, 0x72, 0x62, 0x7d, 0xb3, 0x69, 0x6d, - 0x83, 0x53, 0xd7, 0x29, 0xf3, 0x03, 0xc4, 0xf0, 0x1e, 0x1a, 0x5e, 0xc1, 0x22, 0xc8, 0x78, 0x48, - 0x92, 0xcf, 0xd6, 0xf8, 0xaf, 0xf5, 0x4b, 0x46, 0xc7, 0x31, 0x42, 0x2e, 0xde, 0xef, 0x6b, 0x3f, - 0xff, 0x0d, 0x32, 0x01, 0xf5, 0xd4, 0x4d, 0xad, 0xc6, 0x6f, 0xea, 0x0e, 0xf5, 0xae, 0xb3, 0x16, - 0x8e, 0x70, 0x37, 0xd8, 0xef, 0xd7, 0xb8, 0x14, 0xbc, 0x02, 0xe6, 0x19, 0x57, 0xaf, 0xbb, 0x24, - 0xbc, 0xef, 0x7b, 0xc2, 0xc7, 0xc2, 0xee, 0x72, 0x5c, 0x4b, 0x98, 0xaf, 0x8a, 0xe3, 0x5a, 0x81, - 0x0d, 0x17, 0xf0, 0x2a, 0x98, 0xef, 0x44, 0xb8, 0x89, 0x5d, 0x4c, 0x29, 0x89, 0xe8, 0x4a, 0x56, - 0x24, 0xce, 0x11, 0x88, 0x09, 0x71, 0x5e, 0x07, 0x1b, 0x6d, 0xe2, 0x1e, 0xe8, 0x8a, 0x33, 0x23, - 0xee, 0xa1, 0x20, 0xf6, 0x64, 0xbd, 0x81, 0xeb, 0x00, 0x48, 0x11, 0xf1, 0x2c, 0x66, 0xc5, 0xb3, - 0x98, 0x13, 0x3b, 0xa2, 0x93, 0x54, 0xf5, 0x31, 0x6f, 0x76, 0x2b, 0x39, 0x41, 0xdd, 0xb4, 0x65, - 0x27, 0xb4, 0x75, 0x27, 0xb4, 0xf7, 0x75, 0x27, 0xac, 0xe4, 0x79, 0x8a, 0x3c, 0xfe, 0xa1, 0x64, - 0x28, 0x23, 0xfc, 0x24, 0x35, 0xd2, 0xf9, 0xbf, 0x27, 0xd2, 0x73, 0x89, 0x48, 0x43, 0x0b, 0x2c, - 0x48, 0xfa, 0x01, 0xea, 0xd7, 0x79, 0x70, 0x41, 0xec, 0x06, 0xee, 0xa0, 0xfe, 0x1e, 0xa2, 0xef, - 0x64, 0xf3, 0xd3, 0x8b, 0x99, 0x5a, 0x9e, 0xf5, 0xeb, 0x7e, 0xd8, 0xc4, 0x7d, 0xeb, 0xa2, 0xaa, - 0x63, 0x83, 0x98, 0x0f, 0x8b, 0x4c, 0x13, 0x31, 0xa4, 0x93, 0x9b, 0xff, 0x5b, 0xdf, 0x64, 0xc0, - 0x99, 0xa1, 0x70, 0x85, 0x5b, 0x8d, 0xe5, 0x08, 0xeb, 0xeb, 0xa7, 0x7e, 0x54, 0x8e, 0xb0, 0x3e, - 0xfd, 0x53, 0x39, 0xf2, 0x4f, 0x90, 0x8f, 0x0f, 0xb2, 0x75, 0x09, 0x2c, 0x8f, 0xc5, 0xe9, 0x88, - 0xb8, 0x9e, 0x1e, 0x74, 0x61, 0x8a, 0x6f, 0x60, 0x5d, 0xed, 0xad, 0xdb, 0x83, 0x0e, 0xab, 0xb6, - 0x95, 0x89, 0xff, 0x81, 0x3c, 0x2f, 0xcc, 0xf5, 0xfb, 0x58, 0x75, 0xb9, 0xca, 0xea, 0xf7, 0x2f, - 0x4a, 0xa7, 0xa5, 0x87, 0xb4, 0x79, 0x60, 0xfb, 0xc4, 0x09, 0x10, 0x6b, 0xd9, 0x37, 0x43, 0xc6, - 0xbb, 0xaf, 0xd0, 0xde, 0x7d, 0x5a, 0x00, 0x33, 0xc2, 0x1c, 0xec, 0x81, 0x9c, 0x9a, 0x39, 0x60, - 0x29, 0x1e, 0xf3, 0x94, 0x71, 0xd2, 0xdc, 0x98, 0x2c, 0x20, 0xd9, 0x58, 0xe5, 0x4f, 0xbf, 0xfd, - 0xe9, 0xeb, 0x69, 0x0b, 0x6e, 0x38, 0xa1, 0xdf, 0xf0, 0xa3, 0xae, 0x9e, 0x7e, 0xd5, 0xa0, 0xe1, - 0x3c, 0x54, 0xe1, 0x79, 0x04, 0xbf, 0x32, 0xc0, 0x42, 0x62, 0x96, 0x83, 0xe7, 0xc7, 0xac, 0xa7, - 0x4d, 0x8b, 0xe6, 0xd6, 0x71, 0x62, 0x8a, 0x8a, 0x23, 0xa8, 0x5c, 0x80, 0xdb, 0x23, 0x54, 0xf4, - 0x9c, 0x38, 0xc6, 0xe8, 0x89, 0x01, 0x16, 0x47, 0xe7, 0x30, 0x58, 0x1e, 0x43, 0x9b, 0x30, 0xf8, - 0x99, 0x17, 0x7e, 0x87, 0xa4, 0xa2, 0xf6, 0x86, 0xa0, 0xb6, 0x03, 0x9d, 0x11, 0x6a, 0x3d, 0xad, - 0x30, 0x64, 0x17, 0x9f, 0x25, 0x1f, 0xc1, 0x8f, 0x40, 0x4e, 0x4d, 0x58, 0x29, 0xc1, 0x4a, 0x8e, - 0x6d, 0x29, 0xc1, 0x1a, 0x19, 0xce, 0xac, 0x0b, 0x82, 0xc6, 0x26, 0x3c, 0x37, 0x42, 0x43, 0x8d, - 0x68, 0x34, 0x76, 0x37, 0x9f, 0x80, 0x9c, 0x9a, 0xad, 0x52, 0x80, 0x93, 0x23, 0x5c, 0x0a, 0xf0, - 0xc8, 0x58, 0x66, 0xd9, 0x02, 0xb8, 0x0c, 0xb7, 0x46, 0x80, 0xa9, 0x94, 0x1b, 0xe2, 0x3a, 0x0f, - 0x0f, 0xf0, 0xe1, 0x23, 0x78, 0x00, 0xb2, 0x7c, 0xe6, 0x82, 0x6b, 0x29, 0xa1, 0x1f, 0x8c, 0x70, - 0xe6, 0xfa, 0x84, 0x53, 0x05, 0xba, 0x25, 0x40, 0x37, 0x60, 0x71, 0x2c, 0x1f, 0x9a, 0x09, 0x57, - 0x5b, 0x60, 0x56, 0xce, 0x1c, 0xb0, 0x38, 0x66, 0x30, 0x31, 0xce, 0x98, 0xa5, 0x89, 0xe7, 0x0a, - 0x72, 0x5d, 0x40, 0x2e, 0xc3, 0xd3, 0x23, 0x90, 0x72, 0x8a, 0x81, 0x3e, 0xc8, 0xa9, 0x21, 0x06, - 0x9a, 0x71, 0x53, 0xc9, 0xc9, 0xc6, 0x3c, 0x37, 0xb9, 0x80, 0x6b, 0xa0, 0x92, 0x00, 0x5a, 0x85, - 0xcb, 0x23, 0x40, 0x98, 0xb5, 0xea, 0x2e, 0xb7, 0x4f, 0x40, 0x21, 0x36, 0x76, 0x1c, 0x09, 0x97, - 0xf0, 0x2a, 0x65, 0x56, 0xb1, 0x36, 0x05, 0xd8, 0x3a, 0x3c, 0x3b, 0x0a, 0xa6, 0x64, 0x79, 0x1d, - 0x84, 0x01, 0xc8, 0xa9, 0x26, 0x96, 0x92, 0x30, 0xc9, 0x91, 0x26, 0x25, 0x61, 0x46, 0xfa, 0xdf, - 0x44, 0xff, 0x64, 0xe3, 0x62, 0x7d, 0x78, 0x08, 0xc0, 0xb0, 0xbc, 0x42, 0x2b, 0xdd, 0x60, 0xbc, - 0x47, 0x9a, 0x9b, 0x47, 0xca, 0x28, 0x5c, 0x4b, 0xe0, 0xae, 0x41, 0x33, 0x15, 0x57, 0x14, 0x79, - 0xee, 0xa9, 0xaa, 0xc9, 0xa9, 0x6f, 0x32, 0x5e, 0xc4, 0x53, 0xdf, 0x64, 0xa2, 0x9c, 0x4f, 0xf4, - 0x54, 0xd7, 0xf8, 0xca, 0xd5, 0x67, 0x2f, 0x8b, 0xc6, 0xf3, 0x97, 0x45, 0xe3, 0xc7, 0x97, 0x45, - 0xe3, 0xf1, 0xab, 0xe2, 0xd4, 0xf3, 0x57, 0xc5, 0xa9, 0xef, 0x5e, 0x15, 0xa7, 0x3e, 0xd8, 0x8c, - 0xf5, 0xb9, 0xbb, 0x42, 0xb9, 0xca, 0xbb, 0x94, 0x36, 0xd4, 0xe7, 0xa6, 0x1a, 0xb3, 0xa2, 0xa7, - 0xfe, 0xf7, 0xb7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0x8f, 0xb5, 0x2e, 0x01, 0x11, 0x00, 0x00, + // 1454 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x56, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xcf, 0xc6, 0x4e, 0xec, 0x3c, 0xa7, 0x6d, 0x98, 0xa6, 0x4d, 0xb2, 0x4d, 0xec, 0x74, 0x43, + 0x93, 0xb4, 0xb4, 0xbb, 0x4d, 0x40, 0x20, 0x2a, 0x2a, 0xd4, 0x44, 0x69, 0x28, 0xfd, 0xa3, 0x62, + 0x22, 0x0e, 0x48, 0xc8, 0x1a, 0xaf, 0x27, 0xeb, 0x55, 0xbc, 0x3b, 0xee, 0xce, 0x38, 0x38, 0x94, + 0x5e, 0xe8, 0x05, 0x89, 0x03, 0x95, 0xf8, 0x02, 0x3d, 0xf1, 0x15, 0xf8, 0x04, 0x48, 0x3d, 0x56, + 0xe2, 0x82, 0x38, 0x14, 0xd4, 0x72, 0xe0, 0xcc, 0x91, 0x13, 0x9a, 0x3f, 0x6b, 0xaf, 0xed, 0x75, + 0x42, 0xf9, 0x73, 0xe3, 0xb4, 0x3b, 0x33, 0x6f, 0xde, 0xef, 0xf7, 0xe6, 0xcd, 0xbc, 0xf7, 0x83, + 0xd3, 0x84, 0xd7, 0x1d, 0xb2, 0x1f, 0x38, 0xfb, 0x6b, 0xce, 0xbd, 0x16, 0x89, 0x0e, 0xec, 0x66, + 0x44, 0x39, 0x45, 0x40, 0x78, 0xdd, 0x26, 0xfb, 0x81, 0xbd, 0xbf, 0x66, 0x5e, 0x70, 0x29, 0x0b, + 0x28, 0x73, 0xaa, 0x98, 0x11, 0x65, 0xe4, 0xec, 0xaf, 0x55, 0x09, 0xc7, 0x6b, 0x4e, 0x13, 0x7b, + 0x7e, 0x88, 0xb9, 0x4f, 0x43, 0xb5, 0xcf, 0x9c, 0x4e, 0xf8, 0x13, 0xdb, 0xd5, 0xec, 0xc9, 0xc4, + 0x2c, 0x6f, 0xc7, 0xa6, 0x1e, 0xf5, 0xa8, 0xfc, 0x75, 0xc4, 0x9f, 0x9e, 0x9d, 0xf7, 0x28, 0xf5, + 0x1a, 0xc4, 0xc1, 0x4d, 0xdf, 0xc1, 0x61, 0x48, 0xb9, 0xf4, 0xce, 0xf4, 0x6a, 0x49, 0xaf, 0xca, + 0x51, 0xb5, 0xb5, 0xeb, 0x70, 0x3f, 0x20, 0x8c, 0xe3, 0xa0, 0xa9, 0x0c, 0xac, 0x77, 0xe0, 0xf4, + 0x07, 0x82, 0xe1, 0x16, 0xaf, 0x5f, 0x73, 0x5d, 0xda, 0x0a, 0x79, 0x99, 0xdc, 0x6b, 0x11, 0xc6, + 0xd1, 0x2c, 0xe4, 0x70, 0xad, 0x16, 0x11, 0xc6, 0x66, 0x8d, 0x45, 0x63, 0x75, 0xa2, 0x1c, 0x0f, + 0xaf, 0xe4, 0xbf, 0x7c, 0x5c, 0x1a, 0xf9, 0xed, 0x71, 0x69, 0xc4, 0xda, 0x85, 0x99, 0x81, 0xdd, + 0xac, 0x49, 0x43, 0x46, 0xc4, 0xf6, 0x2a, 0x6e, 0xe0, 0xd0, 0x25, 0xf1, 0x76, 0x3d, 0x44, 0x67, + 0x60, 0xc2, 0xa5, 0x35, 0x52, 0xa9, 0x63, 0x56, 0x9f, 0x1d, 0x95, 0x6b, 0x79, 0x31, 0xf1, 0x1e, + 0x66, 0x75, 0x34, 0x0d, 0x63, 0x21, 0x15, 0x9b, 0x32, 0x8b, 0xc6, 0x6a, 0xb6, 0xac, 0x06, 0xd6, + 0xbb, 0x30, 0x27, 0x71, 0xee, 0xf8, 0x55, 0x3f, 0x6a, 0xfd, 0x0d, 0xa2, 0x07, 0x60, 0xa6, 0x39, + 0xe8, 0x72, 0x4d, 0xf7, 0x80, 0x4c, 0xc8, 0x33, 0x01, 0x23, 0x18, 0x8d, 0x4a, 0x46, 0x9d, 0x31, + 0x3a, 0x07, 0xc7, 0xb1, 0x72, 0x54, 0x09, 0x5b, 0x41, 0x95, 0x44, 0x9a, 0xf3, 0x31, 0x3d, 0x7b, + 0x47, 0x4e, 0x5a, 0x37, 0x61, 0x5e, 0x42, 0x7f, 0x84, 0x1b, 0x7e, 0x0d, 0x73, 0x1a, 0xf5, 0xd1, + 0x3f, 0x0b, 0x93, 0x2e, 0x0d, 0x59, 0xa5, 0x97, 0x41, 0x41, 0xcc, 0x5d, 0x1b, 0x88, 0xe3, 0x2b, + 0x03, 0x16, 0x86, 0x78, 0xd3, 0xb1, 0xac, 0xc0, 0x89, 0x98, 0x55, 0xaf, 0xc7, 0x98, 0xec, 0xb5, + 0x7f, 0x2f, 0xb4, 0xb7, 0xe1, 0xa4, 0x24, 0xb3, 0xa1, 0x32, 0xfb, 0x32, 0x09, 0xb9, 0x0c, 0xd3, + 0xbd, 0x5b, 0x8f, 0xba, 0x36, 0xd6, 0x4d, 0x0d, 0xf6, 0x21, 0xa7, 0x11, 0xf6, 0x8e, 0x06, 0x43, + 0x53, 0x90, 0xd9, 0x23, 0x07, 0xfa, 0x86, 0x89, 0xdf, 0x04, 0xfc, 0x45, 0x0d, 0xdf, 0x71, 0xa6, + 0xe1, 0xa7, 0x61, 0x6c, 0x1f, 0x37, 0x5a, 0x31, 0xb8, 0x1a, 0x58, 0x6f, 0xc2, 0x94, 0xb4, 0xde, + 0xa4, 0xb5, 0x97, 0x0a, 0x72, 0x05, 0x5e, 0x49, 0xec, 0xd3, 0x10, 0x08, 0xb2, 0xe2, 0xb6, 0xcb, + 0x5d, 0x93, 0x65, 0xf9, 0x6f, 0x7d, 0x06, 0x48, 0x1a, 0xee, 0xb4, 0x6f, 0x51, 0x8f, 0xc5, 0x10, + 0x08, 0xb2, 0xf2, 0x8d, 0x28, 0xff, 0xf2, 0x1f, 0x5d, 0x07, 0xe8, 0xd6, 0x10, 0x19, 0x5b, 0x61, + 0x7d, 0xd9, 0x56, 0x05, 0xc7, 0x16, 0x05, 0xc7, 0x56, 0x55, 0x49, 0x17, 0x1c, 0xfb, 0x6e, 0xf7, + 0xa8, 0xca, 0x89, 0x9d, 0x09, 0x92, 0x0f, 0x0d, 0x7d, 0xb0, 0x31, 0xb8, 0xe6, 0xb9, 0x04, 0xd9, + 0x06, 0xf5, 0x44, 0x74, 0x99, 0xd5, 0xc2, 0xfa, 0x09, 0xbb, 0x5b, 0xe0, 0xec, 0x5b, 0xd4, 0x2b, + 0xcb, 0x45, 0xb4, 0x9d, 0x42, 0x67, 0xe5, 0x48, 0x3a, 0x0a, 0x21, 0xc9, 0xc7, 0x9a, 0xd6, 0x27, + 0x70, 0x17, 0x47, 0x38, 0x88, 0x4f, 0xc0, 0xda, 0xd6, 0xd4, 0xe2, 0x59, 0x4d, 0xed, 0x32, 0x8c, + 0x37, 0xe5, 0x8c, 0x3c, 0x9a, 0xc2, 0x3a, 0x4a, 0x92, 0x53, 0xb6, 0x1b, 0xd9, 0x27, 0xcf, 0x4a, + 0x23, 0x65, 0x6d, 0x67, 0x7d, 0x67, 0xc0, 0xf1, 0x2d, 0x5e, 0xdf, 0xc4, 0x8d, 0x46, 0xe2, 0x74, + 0x71, 0xe4, 0xb1, 0x38, 0x0f, 0xe2, 0x1f, 0xcd, 0x40, 0xce, 0xc3, 0xac, 0xe2, 0xe2, 0xa6, 0x7e, + 0x12, 0xe3, 0x1e, 0x66, 0x9b, 0xb8, 0x89, 0x3e, 0x81, 0xa9, 0x66, 0x44, 0x9b, 0x94, 0x91, 0xa8, + 0xf3, 0xac, 0xc4, 0x93, 0x98, 0xdc, 0x58, 0xff, 0xe3, 0x59, 0xc9, 0xf6, 0x7c, 0x5e, 0x6f, 0x55, + 0x6d, 0x97, 0x06, 0x8e, 0xae, 0xfd, 0xea, 0x73, 0x89, 0xd5, 0xf6, 0x1c, 0x7e, 0xd0, 0x24, 0xcc, + 0xde, 0xec, 0xbe, 0xe7, 0xf2, 0x89, 0xd8, 0x57, 0xfc, 0x16, 0xe7, 0x20, 0xef, 0xd6, 0xb1, 0x1f, + 0x56, 0xfc, 0xda, 0x6c, 0x76, 0xd1, 0x58, 0xcd, 0x94, 0x73, 0x72, 0x7c, 0xa3, 0x66, 0xad, 0xc0, + 0xc9, 0x2d, 0xc6, 0xfd, 0x00, 0x73, 0xb2, 0x8d, 0xbb, 0x47, 0x30, 0x05, 0x19, 0x0f, 0x2b, 0xf2, + 0xd9, 0xb2, 0xf8, 0xb5, 0x7e, 0xcf, 0xc4, 0x79, 0x8c, 0xb0, 0x4b, 0x76, 0xda, 0x71, 0x9c, 0xaf, + 0x41, 0x26, 0x60, 0x9e, 0x3e, 0xa9, 0xb9, 0xe4, 0x49, 0xdd, 0x66, 0xde, 0x16, 0xaf, 0x93, 0x88, + 0xb4, 0x82, 0x9d, 0x76, 0x59, 0x58, 0xa1, 0x2b, 0x30, 0xc9, 0xc5, 0xf6, 0x8a, 0x4b, 0xc3, 0x5d, + 0xdf, 0x93, 0x31, 0x16, 0xd6, 0x67, 0x92, 0xbb, 0xa4, 0xfb, 0x4d, 0xb9, 0x5c, 0x2e, 0xf0, 0xee, + 0x00, 0x5d, 0x85, 0xc9, 0x66, 0x44, 0x6a, 0xc4, 0x25, 0x8c, 0xd1, 0x88, 0xcd, 0x66, 0xe5, 0xc5, + 0x39, 0x04, 0xb1, 0xc7, 0x5c, 0xd4, 0xc1, 0x6a, 0x83, 0xba, 0x7b, 0x71, 0xc5, 0x19, 0x93, 0xe7, + 0x50, 0x90, 0x73, 0xaa, 0xde, 0xa0, 0x05, 0x00, 0x65, 0x22, 0x9f, 0xc5, 0xb8, 0x7c, 0x16, 0x13, + 0x72, 0x46, 0xf6, 0x8e, 0xcd, 0x78, 0x59, 0x34, 0xb9, 0xd9, 0x9c, 0xa4, 0x6e, 0xda, 0xaa, 0x03, + 0xda, 0x71, 0x07, 0xb4, 0x77, 0xe2, 0x0e, 0xb8, 0x91, 0x17, 0x57, 0xe4, 0xd1, 0xcf, 0x25, 0x43, + 0x3b, 0x11, 0x2b, 0xa9, 0x99, 0xce, 0xff, 0x37, 0x99, 0x9e, 0xe8, 0xc9, 0x34, 0xb2, 0xe0, 0x98, + 0xa2, 0x1f, 0xe0, 0x76, 0x45, 0x24, 0x17, 0x12, 0x27, 0x70, 0x1b, 0xb7, 0xb7, 0x31, 0x7b, 0x3f, + 0x9b, 0x1f, 0x9d, 0xca, 0x94, 0xf3, 0xbc, 0x5d, 0xf1, 0xc3, 0x1a, 0x69, 0x5b, 0x17, 0x74, 0x1d, + 0xeb, 0xe4, 0xbc, 0x5b, 0x64, 0x6a, 0x98, 0xe3, 0xf8, 0x72, 0x8b, 0x7f, 0xeb, 0xdb, 0x8c, 0xee, + 0xf5, 0xd2, 0x78, 0x43, 0x78, 0x4d, 0xdc, 0x11, 0xde, 0x8e, 0x9f, 0xfa, 0x61, 0x77, 0x84, 0xb7, + 0xd9, 0x3f, 0xba, 0x23, 0xff, 0x27, 0xf9, 0xe8, 0x24, 0x5b, 0x97, 0xb4, 0xaa, 0x4a, 0xe6, 0xe9, + 0x90, 0xbc, 0x9e, 0xea, 0x74, 0x61, 0x46, 0xae, 0x93, 0xb8, 0xda, 0x5b, 0xb7, 0x3a, 0x1d, 0x56, + 0x4f, 0x6b, 0x17, 0x6f, 0x40, 0x5e, 0x14, 0xe6, 0xca, 0x2e, 0xd1, 0x5d, 0x6e, 0x63, 0xee, 0xa7, + 0x67, 0xa5, 0x53, 0x2a, 0x42, 0x56, 0xdb, 0xb3, 0x7d, 0xea, 0x04, 0x98, 0xd7, 0xed, 0x1b, 0x21, + 0x17, 0xdd, 0x57, 0xee, 0x5e, 0xff, 0xbe, 0x00, 0x63, 0xd2, 0x1d, 0x7a, 0x68, 0x00, 0x74, 0xf5, + 0x1e, 0xb2, 0x92, 0x79, 0x4f, 0x97, 0x92, 0xe6, 0xd2, 0xa1, 0x36, 0x8a, 0x97, 0x75, 0xf1, 0x8b, + 0x1f, 0x7e, 0xfd, 0x66, 0x74, 0x19, 0xbd, 0xea, 0x84, 0x52, 0xa4, 0x75, 0x54, 0x31, 0xaf, 0x57, + 0xb4, 0xec, 0x70, 0xee, 0xeb, 0x64, 0x3d, 0x40, 0x5f, 0x1b, 0x70, 0xac, 0x47, 0xcc, 0xa1, 0x73, + 0x03, 0x20, 0x69, 0x6a, 0xd1, 0x5c, 0x3e, 0xca, 0x4c, 0xd3, 0x71, 0x24, 0x9d, 0xf3, 0x68, 0xa5, + 0x8f, 0x8e, 0x1a, 0xa5, 0x30, 0x7a, 0x6c, 0xc0, 0x54, 0xbf, 0x2a, 0x43, 0xab, 0x03, 0x68, 0x43, + 0x64, 0xa0, 0x79, 0xfe, 0x2f, 0x58, 0x6a, 0x6a, 0x6f, 0x49, 0x6a, 0x6b, 0xc8, 0xe9, 0xa3, 0xb6, + 0x1f, 0x6f, 0xe8, 0xb2, 0x4b, 0x2a, 0xcb, 0x07, 0xe8, 0x53, 0xc8, 0x69, 0xbd, 0x85, 0x4a, 0x03, + 0x70, 0xbd, 0x22, 0xce, 0x5c, 0x1c, 0x6e, 0xa0, 0x69, 0x9c, 0x97, 0x34, 0x96, 0xd0, 0xd9, 0x3e, + 0x1a, 0x5a, 0xb0, 0xb1, 0xc4, 0xd9, 0x7c, 0x0e, 0x39, 0xad, 0xb4, 0x52, 0x80, 0x7b, 0x05, 0x5d, + 0x0a, 0x70, 0x9f, 0x48, 0xb3, 0x6c, 0x09, 0xbc, 0x8a, 0x96, 0xfb, 0x80, 0x99, 0xb2, 0xeb, 0xe2, + 0x3a, 0xf7, 0xf7, 0xc8, 0xc1, 0x03, 0xb4, 0x07, 0x59, 0xa1, 0xc0, 0xd0, 0xfc, 0x80, 0xe7, 0x84, + 0xa0, 0x33, 0x17, 0x86, 0xac, 0x6a, 0xd0, 0x65, 0x09, 0xba, 0x88, 0x8a, 0x7d, 0xa0, 0x42, 0xbf, + 0x25, 0x43, 0xad, 0xc3, 0xb8, 0x52, 0x20, 0xa8, 0x38, 0xe0, 0xb0, 0x47, 0xdc, 0x98, 0xa5, 0xa1, + 0xeb, 0x1a, 0x72, 0x41, 0x42, 0xce, 0xa0, 0x53, 0x7d, 0x90, 0x4a, 0xd3, 0x20, 0x1f, 0x72, 0x5a, + 0xd2, 0x20, 0x33, 0xe9, 0xaa, 0x57, 0xe7, 0x98, 0x67, 0x87, 0x97, 0xf3, 0x18, 0xa8, 0x24, 0x81, + 0xe6, 0xd0, 0x4c, 0xca, 0xd3, 0x73, 0x85, 0x7f, 0x0a, 0x85, 0x84, 0x08, 0x39, 0x14, 0xae, 0x27, + 0xaa, 0x14, 0xe5, 0x62, 0x2d, 0x49, 0xb0, 0x05, 0x74, 0xa6, 0x1f, 0x4c, 0xdb, 0x8a, 0xaa, 0x88, + 0x02, 0xc8, 0xe9, 0x96, 0x96, 0x72, 0x61, 0x7a, 0x05, 0x4e, 0xca, 0x85, 0xe9, 0xeb, 0x86, 0x43, + 0xe3, 0x53, 0x6d, 0x8c, 0xb7, 0xd1, 0x01, 0x40, 0xb7, 0xd8, 0xa6, 0x94, 0xb4, 0x81, 0x8e, 0x99, + 0x52, 0xd2, 0x06, 0xab, 0xb5, 0x65, 0x49, 0xdc, 0x79, 0x64, 0xa6, 0xe2, 0xca, 0x92, 0x2f, 0x22, + 0xd5, 0x15, 0x3a, 0xf5, 0x4d, 0x26, 0x4b, 0x7a, 0xea, 0x9b, 0xec, 0x29, 0xee, 0x43, 0x23, 0x8d, + 0x2b, 0xfe, 0xc6, 0xd5, 0x27, 0xcf, 0x8b, 0xc6, 0xd3, 0xe7, 0x45, 0xe3, 0x97, 0xe7, 0x45, 0xe3, + 0xd1, 0x8b, 0xe2, 0xc8, 0xd3, 0x17, 0xc5, 0x91, 0x1f, 0x5f, 0x14, 0x47, 0x3e, 0x5e, 0x4a, 0x74, + 0x3d, 0x55, 0x12, 0x37, 0x45, 0xcf, 0x8a, 0x1d, 0xb5, 0x85, 0xab, 0xea, 0xb8, 0xec, 0xb0, 0xaf, + 0xff, 0x19, 0x00, 0x00, 0xff, 0xff, 0x97, 0xcf, 0x5e, 0xd9, 0x07, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1439,10 +1439,10 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - // Account queries an Ethereum account. - Account(ctx context.Context, in *QueryAccountRequest, opts ...grpc.CallOption) (*QueryAccountResponse, error) - // CosmosAccount queries an Ethereum account's Cosmos Address. - CosmosAccount(ctx context.Context, in *QueryCosmosAccountRequest, opts ...grpc.CallOption) (*QueryCosmosAccountResponse, error) + // EthAccount queries an Ethereum account. + EthAccount(ctx context.Context, in *QueryEthAccountRequest, opts ...grpc.CallOption) (*QueryEthAccountResponse, error) + // NibiruAccount queries the Bech32 Nibiru address corresponding to Nibiru EVM account. + NibiruAccount(ctx context.Context, in *QueryNibiruAccountRequest, opts ...grpc.CallOption) (*QueryNibiruAccountResponse, error) // ValidatorAccount queries an Ethereum account's from a validator consensus // Address. ValidatorAccount(ctx context.Context, in *QueryValidatorAccountRequest, opts ...grpc.CallOption) (*QueryValidatorAccountResponse, error) @@ -1476,18 +1476,18 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Account(ctx context.Context, in *QueryAccountRequest, opts ...grpc.CallOption) (*QueryAccountResponse, error) { - out := new(QueryAccountResponse) - err := c.cc.Invoke(ctx, "/eth.evm.v1.Query/Account", in, out, opts...) +func (c *queryClient) EthAccount(ctx context.Context, in *QueryEthAccountRequest, opts ...grpc.CallOption) (*QueryEthAccountResponse, error) { + out := new(QueryEthAccountResponse) + err := c.cc.Invoke(ctx, "/eth.evm.v1.Query/EthAccount", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *queryClient) CosmosAccount(ctx context.Context, in *QueryCosmosAccountRequest, opts ...grpc.CallOption) (*QueryCosmosAccountResponse, error) { - out := new(QueryCosmosAccountResponse) - err := c.cc.Invoke(ctx, "/eth.evm.v1.Query/CosmosAccount", in, out, opts...) +func (c *queryClient) NibiruAccount(ctx context.Context, in *QueryNibiruAccountRequest, opts ...grpc.CallOption) (*QueryNibiruAccountResponse, error) { + out := new(QueryNibiruAccountResponse) + err := c.cc.Invoke(ctx, "/eth.evm.v1.Query/NibiruAccount", in, out, opts...) if err != nil { return nil, err } @@ -1586,10 +1586,10 @@ func (c *queryClient) BaseFee(ctx context.Context, in *QueryBaseFeeRequest, opts // QueryServer is the server API for Query service. type QueryServer interface { - // Account queries an Ethereum account. - Account(context.Context, *QueryAccountRequest) (*QueryAccountResponse, error) - // CosmosAccount queries an Ethereum account's Cosmos Address. - CosmosAccount(context.Context, *QueryCosmosAccountRequest) (*QueryCosmosAccountResponse, error) + // EthAccount queries an Ethereum account. + EthAccount(context.Context, *QueryEthAccountRequest) (*QueryEthAccountResponse, error) + // NibiruAccount queries the Bech32 Nibiru address corresponding to Nibiru EVM account. + NibiruAccount(context.Context, *QueryNibiruAccountRequest) (*QueryNibiruAccountResponse, error) // ValidatorAccount queries an Ethereum account's from a validator consensus // Address. ValidatorAccount(context.Context, *QueryValidatorAccountRequest) (*QueryValidatorAccountResponse, error) @@ -1619,11 +1619,11 @@ type QueryServer interface { type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Account(ctx context.Context, req *QueryAccountRequest) (*QueryAccountResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Account not implemented") +func (*UnimplementedQueryServer) EthAccount(ctx context.Context, req *QueryEthAccountRequest) (*QueryEthAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EthAccount not implemented") } -func (*UnimplementedQueryServer) CosmosAccount(ctx context.Context, req *QueryCosmosAccountRequest) (*QueryCosmosAccountResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CosmosAccount not implemented") +func (*UnimplementedQueryServer) NibiruAccount(ctx context.Context, req *QueryNibiruAccountRequest) (*QueryNibiruAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method NibiruAccount not implemented") } func (*UnimplementedQueryServer) ValidatorAccount(ctx context.Context, req *QueryValidatorAccountRequest) (*QueryValidatorAccountResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ValidatorAccount not implemented") @@ -1660,38 +1660,38 @@ func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } -func _Query_Account_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryAccountRequest) +func _Query_EthAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryEthAccountRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Account(ctx, in) + return srv.(QueryServer).EthAccount(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/eth.evm.v1.Query/Account", + FullMethod: "/eth.evm.v1.Query/EthAccount", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Account(ctx, req.(*QueryAccountRequest)) + return srv.(QueryServer).EthAccount(ctx, req.(*QueryEthAccountRequest)) } return interceptor(ctx, in, info, handler) } -func _Query_CosmosAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryCosmosAccountRequest) +func _Query_NibiruAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryNibiruAccountRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).CosmosAccount(ctx, in) + return srv.(QueryServer).NibiruAccount(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/eth.evm.v1.Query/CosmosAccount", + FullMethod: "/eth.evm.v1.Query/NibiruAccount", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).CosmosAccount(ctx, req.(*QueryCosmosAccountRequest)) + return srv.(QueryServer).NibiruAccount(ctx, req.(*QueryNibiruAccountRequest)) } return interceptor(ctx, in, info, handler) } @@ -1881,12 +1881,12 @@ var _Query_serviceDesc = grpc.ServiceDesc{ HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "Account", - Handler: _Query_Account_Handler, + MethodName: "EthAccount", + Handler: _Query_EthAccount_Handler, }, { - MethodName: "CosmosAccount", - Handler: _Query_CosmosAccount_Handler, + MethodName: "NibiruAccount", + Handler: _Query_NibiruAccount_Handler, }, { MethodName: "ValidatorAccount", @@ -1933,7 +1933,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ Metadata: "eth/evm/v1/query.proto", } -func (m *QueryAccountRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryEthAccountRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1943,12 +1943,12 @@ func (m *QueryAccountRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryAccountRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryEthAccountRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryEthAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1963,7 +1963,7 @@ func (m *QueryAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryAccountResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryEthAccountResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1973,12 +1973,12 @@ func (m *QueryAccountResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryAccountResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryEthAccountResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryEthAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2005,7 +2005,7 @@ func (m *QueryAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryCosmosAccountRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryNibiruAccountRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2015,12 +2015,12 @@ func (m *QueryCosmosAccountRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryCosmosAccountRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryNibiruAccountRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryCosmosAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryNibiruAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2035,7 +2035,7 @@ func (m *QueryCosmosAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *QueryCosmosAccountResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryNibiruAccountResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -2045,12 +2045,12 @@ func (m *QueryCosmosAccountResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryCosmosAccountResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryNibiruAccountResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryCosmosAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryNibiruAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -2065,10 +2065,10 @@ func (m *QueryCosmosAccountResponse) MarshalToSizedBuffer(dAtA []byte) (int, err i-- dAtA[i] = 0x10 } - if len(m.CosmosAddress) > 0 { - i -= len(m.CosmosAddress) - copy(dAtA[i:], m.CosmosAddress) - i = encodeVarintQuery(dAtA, i, uint64(len(m.CosmosAddress))) + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) i-- dAtA[i] = 0xa } @@ -2867,7 +2867,7 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *QueryAccountRequest) Size() (n int) { +func (m *QueryEthAccountRequest) Size() (n int) { if m == nil { return 0 } @@ -2880,7 +2880,7 @@ func (m *QueryAccountRequest) Size() (n int) { return n } -func (m *QueryAccountResponse) Size() (n int) { +func (m *QueryEthAccountResponse) Size() (n int) { if m == nil { return 0 } @@ -2900,7 +2900,7 @@ func (m *QueryAccountResponse) Size() (n int) { return n } -func (m *QueryCosmosAccountRequest) Size() (n int) { +func (m *QueryNibiruAccountRequest) Size() (n int) { if m == nil { return 0 } @@ -2913,13 +2913,13 @@ func (m *QueryCosmosAccountRequest) Size() (n int) { return n } -func (m *QueryCosmosAccountResponse) Size() (n int) { +func (m *QueryNibiruAccountResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.CosmosAddress) + l = len(m.Address) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -3271,7 +3271,7 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *QueryAccountRequest) Unmarshal(dAtA []byte) error { +func (m *QueryEthAccountRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3294,10 +3294,10 @@ func (m *QueryAccountRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAccountRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryEthAccountRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryEthAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3353,7 +3353,7 @@ func (m *QueryAccountRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryAccountResponse) Unmarshal(dAtA []byte) error { +func (m *QueryEthAccountResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3376,10 +3376,10 @@ func (m *QueryAccountResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryAccountResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryEthAccountResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryEthAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3486,7 +3486,7 @@ func (m *QueryAccountResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryCosmosAccountRequest) Unmarshal(dAtA []byte) error { +func (m *QueryNibiruAccountRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3509,10 +3509,10 @@ func (m *QueryCosmosAccountRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryCosmosAccountRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryNibiruAccountRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryCosmosAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryNibiruAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3568,7 +3568,7 @@ func (m *QueryCosmosAccountRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryCosmosAccountResponse) Unmarshal(dAtA []byte) error { +func (m *QueryNibiruAccountResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3591,15 +3591,15 @@ func (m *QueryCosmosAccountResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryCosmosAccountResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryNibiruAccountResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryCosmosAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryNibiruAccountResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CosmosAddress", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3627,7 +3627,7 @@ func (m *QueryCosmosAccountResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.CosmosAddress = string(dAtA[iNdEx:postIndex]) + m.Address = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 0 { diff --git a/x/evm/query.pb.gw.go b/x/evm/query.pb.gw.go index bed25848d..fd0ecc413 100644 --- a/x/evm/query.pb.gw.go +++ b/x/evm/query.pb.gw.go @@ -33,8 +33,8 @@ var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage var _ = metadata.Join -func request_Query_Account_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryAccountRequest +func request_Query_EthAccount_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEthAccountRequest var metadata runtime.ServerMetadata var ( @@ -55,13 +55,13 @@ func request_Query_Account_0(ctx context.Context, marshaler runtime.Marshaler, c return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } - msg, err := client.Account(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.EthAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Account_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryAccountRequest +func local_request_Query_EthAccount_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEthAccountRequest var metadata runtime.ServerMetadata var ( @@ -82,13 +82,13 @@ func local_request_Query_Account_0(ctx context.Context, marshaler runtime.Marsha return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } - msg, err := server.Account(ctx, &protoReq) + msg, err := server.EthAccount(ctx, &protoReq) return msg, metadata, err } -func request_Query_CosmosAccount_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryCosmosAccountRequest +func request_Query_NibiruAccount_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryNibiruAccountRequest var metadata runtime.ServerMetadata var ( @@ -109,13 +109,13 @@ func request_Query_CosmosAccount_0(ctx context.Context, marshaler runtime.Marsha return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } - msg, err := client.CosmosAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.NibiruAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_CosmosAccount_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryCosmosAccountRequest +func local_request_Query_NibiruAccount_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryNibiruAccountRequest var metadata runtime.ServerMetadata var ( @@ -136,7 +136,7 @@ func local_request_Query_CosmosAccount_0(ctx context.Context, marshaler runtime. return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) } - msg, err := server.CosmosAccount(ctx, &protoReq) + msg, err := server.NibiruAccount(ctx, &protoReq) return msg, metadata, err } @@ -565,7 +565,7 @@ func local_request_Query_BaseFee_0(ctx context.Context, marshaler runtime.Marsha // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - mux.Handle("GET", pattern_Query_Account_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_EthAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -576,7 +576,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Account_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_EthAccount_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -584,11 +584,11 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_Account_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_EthAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_CosmosAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_NibiruAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() var stream runtime.ServerTransportStream @@ -599,7 +599,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_CosmosAccount_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_NibiruAccount_0(rctx, inboundMarshaler, server, req, pathParams) md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { @@ -607,7 +607,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv return } - forward_Query_CosmosAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_NibiruAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -882,7 +882,7 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - mux.Handle("GET", pattern_Query_Account_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_EthAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -891,18 +891,18 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Account_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_EthAccount_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Account_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_EthAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_CosmosAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_NibiruAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -911,14 +911,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_CosmosAccount_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_NibiruAccount_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_CosmosAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_NibiruAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -1126,9 +1126,9 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Account_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"nibiru", "evm", "v1", "account", "address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_EthAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"nibiru", "evm", "v1", "eth_account", "address"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_CosmosAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"nibiru", "evm", "v1", "cosmos_account", "address"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_NibiruAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"nibiru", "evm", "v1", "nibiru_account", "address"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ValidatorAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"nibiru", "evm", "v1", "validator_account", "cons_address"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1152,9 +1152,9 @@ var ( ) var ( - forward_Query_Account_0 = runtime.ForwardResponseMessage + forward_Query_EthAccount_0 = runtime.ForwardResponseMessage - forward_Query_CosmosAccount_0 = runtime.ForwardResponseMessage + forward_Query_NibiruAccount_0 = runtime.ForwardResponseMessage forward_Query_ValidatorAccount_0 = runtime.ForwardResponseMessage diff --git a/x/evm/query_test.go b/x/evm/query_test.go index cadcd5818..f32a9704b 100644 --- a/x/evm/query_test.go +++ b/x/evm/query_test.go @@ -15,11 +15,11 @@ type TestSuite struct { func (s *TestSuite) TestNilQueries() { for _, testCase := range []func() error{ func() error { - var req *QueryAccountRequest = nil + var req *QueryEthAccountRequest = nil return req.Validate() }, func() error { - var req *QueryCosmosAccountRequest = nil + var req *QueryNibiruAccountRequest = nil return req.Validate() }, func() error { diff --git a/x/evm/statedb/interfaces.go b/x/evm/statedb/interfaces.go index 25d5182ea..4ef8b2862 100644 --- a/x/evm/statedb/interfaces.go +++ b/x/evm/statedb/interfaces.go @@ -19,16 +19,23 @@ type ExtStateDB interface { // Keeper provide underlying storage of StateDB type Keeper interface { - // Read methods + // GetAccount: Ethereum account getter for a [statedb.Account]. GetAccount(ctx sdk.Context, addr common.Address) *Account GetState(ctx sdk.Context, addr common.Address, key common.Hash) common.Hash GetCode(ctx sdk.Context, codeHash common.Hash) []byte - // the callback returns false to break early - ForEachStorage(ctx sdk.Context, addr common.Address, cb func(key, value common.Hash) bool) - // Write methods, only called by `StateDB.Commit()` + // ForEachStorage: Iterator over contract storage. + ForEachStorage( + ctx sdk.Context, addr common.Address, + stopIter func(key, value common.Hash) bool, + ) + SetAccount(ctx sdk.Context, addr common.Address, account Account) error SetState(ctx sdk.Context, addr common.Address, key common.Hash, value []byte) + // SetCode: Setter for smart contract bytecode. Delete if code is empty. SetCode(ctx sdk.Context, codeHash []byte, code []byte) + + // DeleteAccount handles contract's suicide call, clearing the balance, + // contract bytecode, contract state, and its native account. DeleteAccount(ctx sdk.Context, addr common.Address) error } diff --git a/x/genmsg/integration_test.go b/x/genmsg/integration_test.go index 27f5c63c2..e37476649 100644 --- a/x/genmsg/integration_test.go +++ b/x/genmsg/integration_test.go @@ -20,9 +20,9 @@ func TestIntegration(t *testing.T) { recvAddr := sdk.AccAddress("recv") encoding := app.MakeEncodingConfig() - appGenesis := app.NewDefaultGenesisState(encoding.Marshaler) + appGenesis := app.NewDefaultGenesisState(encoding.Codec) - appGenesis[banktypes.ModuleName] = encoding.Marshaler.MustMarshalJSON(&banktypes.GenesisState{ + appGenesis[banktypes.ModuleName] = encoding.Codec.MustMarshalJSON(&banktypes.GenesisState{ Balances: []banktypes.Balance{ { Address: senderAddr.String(), @@ -40,7 +40,7 @@ func TestIntegration(t *testing.T) { anyMsg, err := codectypes.NewAnyWithValue(testMsg) require.NoError(t, err) - appGenesis[genmsg.ModuleName] = encoding.Marshaler.MustMarshalJSON( + appGenesis[genmsg.ModuleName] = encoding.Codec.MustMarshalJSON( &v1.GenesisState{ Messages: []*codectypes.Any{anyMsg}, }, diff --git a/x/oracle/types/genesis_test.go b/x/oracle/types/genesis_test.go index deedc85e7..a20b2620c 100644 --- a/x/oracle/types/genesis_test.go +++ b/x/oracle/types/genesis_test.go @@ -19,7 +19,7 @@ func TestGenesisValidation(t *testing.T) { } func TestGetGenesisStateFromAppState(t *testing.T) { - cdc := app.MakeEncodingConfig().Marshaler + cdc := app.MakeEncodingConfig().Codec appState := make(map[string]json.RawMessage) defaultGenesisState := types.DefaultGenesisState() diff --git a/x/sudo/cli/cli_test.go b/x/sudo/cli/cli_test.go index c6c45a3bc..dc27bd6e2 100644 --- a/x/sudo/cli/cli_test.go +++ b/x/sudo/cli/cli_test.go @@ -263,7 +263,7 @@ func (s *IntegrationSuite) TestMarshal_EditSudoers() { fileJsonBz, _ := msgPlus.ToJson(t) t.Log("check unmarshal file → proto") - cdc := app.MakeEncodingConfig().Marshaler + cdc := app.MakeEncodingConfig().Codec newMsg := new(types.MsgEditSudoers) err := cdc.UnmarshalJSON(fileJsonBz, newMsg) assert.NoErrorf(t, err, "fileJsonBz: #%v", fileJsonBz) diff --git a/x/tokenfactory/keeper/wasm_test.go b/x/tokenfactory/keeper/wasm_test.go index 105f0f5a0..3afe2ff34 100644 --- a/x/tokenfactory/keeper/wasm_test.go +++ b/x/tokenfactory/keeper/wasm_test.go @@ -268,7 +268,7 @@ func (s *TestSuite) TestStargateSerde() { for _, tc := range testCases { s.Run(tc.typeUrl, func() { pbMsg, _ := (tc.sdkMsg).(codec.ProtoMarshaler) - sgMsgValue := s.encConfig.Marshaler.MustMarshal(pbMsg) + sgMsgValue := s.encConfig.Codec.MustMarshal(pbMsg) sgMsg := wasmvmtypes.StargateMsg{ TypeURL: tc.typeUrl, Value: sgMsgValue, @@ -281,7 +281,7 @@ func (s *TestSuite) TestStargateSerde() { ibcTransferPort := wasmtesting.MockIBCTransferKeeper{ GetPortFn: func(ctx sdk.Context) string { return "myTransferPort" }, } - wasmEncoders := wasmkeeper.DefaultEncoders(s.encConfig.Marshaler, ibcTransferPort) + wasmEncoders := wasmkeeper.DefaultEncoders(s.encConfig.Codec, ibcTransferPort) mockContractAddr := testutil.AccAddress() sdkMsgs, err := wasmEncoders.Encode(s.ctx, mockContractAddr, "mock-ibc-port", wasmvmtypes.CosmosMsg{ From 31e2cecb706a1b83cc47e04e4c5c99c2b92ff3d8 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 23:30:08 -0500 Subject: [PATCH 10/11] chore: linter --- app/keepers.go | 2 +- x/evm/const.go | 4 +- x/evm/evmtest/eth.go | 3 +- x/evm/keeper/evm_state.go | 6 ++- x/evm/keeper/grpc_query_test.go | 75 +++++++++++++++------------------ x/evm/keeper/statedb.go | 5 ++- x/evm/query.go | 2 + x/oracle/types/test_utils.go | 1 + 8 files changed, 47 insertions(+), 51 deletions(-) diff --git a/app/keepers.go b/app/keepers.go index 1f3b9d6cd..e5ed3f5c6 100644 --- a/app/keepers.go +++ b/app/keepers.go @@ -282,7 +282,7 @@ func (app *NibiruApp) InitKeepers( // app.capabilityKeeper.Seal() // TODO: chore(upgrade): Potential breaking change on AccountKeeper dur - // to ProtoBaseAccount replacement. + // to ProtoBaseAccount replacement. app.AccountKeeper = authkeeper.NewAccountKeeper( appCodec, keys[authtypes.StoreKey], diff --git a/x/evm/const.go b/x/evm/const.go index 91a6325e4..7188b4209 100644 --- a/x/evm/const.go +++ b/x/evm/const.go @@ -39,9 +39,7 @@ const ( NamespaceBlockGasUsed ) -var ( - KeyPrefixBzAccState = KeyPrefixAccState.Prefix() -) +var KeyPrefixBzAccState = KeyPrefixAccState.Prefix() // PrefixAccStateEthAddr returns a prefix to iterate over a given account storage. func PrefixAccStateEthAddr(address common.Address) []byte { diff --git a/x/evm/evmtest/eth.go b/x/evm/evmtest/eth.go index 8a2738be6..133ddd5fa 100644 --- a/x/evm/evmtest/eth.go +++ b/x/evm/evmtest/eth.go @@ -8,9 +8,10 @@ import ( cmt "github.com/cometbft/cometbft/types" "github.com/stretchr/testify/assert" - "github.com/NibiruChain/nibiru/eth/crypto/ethsecp256k1" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/NibiruChain/nibiru/eth/crypto/ethsecp256k1" + "github.com/cosmos/cosmos-sdk/client" gethcommon "github.com/ethereum/go-ethereum/common" gethcore "github.com/ethereum/go-ethereum/core/types" diff --git a/x/evm/keeper/evm_state.go b/x/evm/keeper/evm_state.go index 457268124..5cf7cea3c 100644 --- a/x/evm/keeper/evm_state.go +++ b/x/evm/keeper/evm_state.go @@ -15,8 +15,10 @@ import ( "github.com/NibiruChain/nibiru/x/evm" ) -type AccStatePrimaryKey = collections.Pair[gethcommon.Address, gethcommon.Hash] -type CodeHash = []byte +type ( + AccStatePrimaryKey = collections.Pair[gethcommon.Address, gethcommon.Hash] + CodeHash = []byte +) // EvmState isolates the key-value stores (collections) for the x/evm module. type EvmState struct { diff --git a/x/evm/keeper/grpc_query_test.go b/x/evm/keeper/grpc_query_test.go index 0943f4cd1..46b726076 100644 --- a/x/evm/keeper/grpc_query_test.go +++ b/x/evm/keeper/grpc_query_test.go @@ -1,6 +1,9 @@ package keeper_test import ( + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/NibiruChain/nibiru/app" "github.com/NibiruChain/nibiru/app/codec" "github.com/NibiruChain/nibiru/eth" @@ -9,8 +12,6 @@ import ( "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/evmtest" "github.com/NibiruChain/nibiru/x/evm/keeper" - sdk "github.com/cosmos/cosmos-sdk/types" - gethcommon "github.com/ethereum/go-ethereum/common" ) type TestDeps struct { @@ -19,12 +20,12 @@ type TestDeps struct { encCfg codec.EncodingConfig k keeper.Keeper genState *evm.GenesisState - sender Sender + sender Sender } type Sender struct { - EthAddr gethcommon.Address - PrivKey *ethsecp256k1.PrivKey + EthAddr gethcommon.Address + PrivKey *ethsecp256k1.PrivKey NibiruAddr sdk.AccAddress } @@ -52,20 +53,24 @@ func (s *KeeperSuite) SetupTest() TestDeps { func InvalidEthAddr() string { return "0x0000" } +type TestCase[In, Out any] struct { + name string + // setup: Optional setup function to create the scenario + setup func(deps *TestDeps) + scenario func(deps *TestDeps) ( + req In, + wantResp Out, + ) + wantErr string +} + func (s *KeeperSuite) TestQueryNibiruAccount() { type In = *evm.QueryNibiruAccountRequest type Out = *evm.QueryNibiruAccountResponse - testCases := []struct { - name string - scenario func() ( - req In, - wantResp Out, - ) - wantErr string - }{ + testCases := []TestCase[In, Out]{ { name: "sad: msg validation", - scenario: func() (req In, wantResp Out) { + scenario: func(deps *TestDeps) (req In, wantResp Out) { req = &evm.QueryNibiruAccountRequest{ Address: InvalidEthAddr(), } @@ -78,7 +83,7 @@ func (s *KeeperSuite) TestQueryNibiruAccount() { }, { name: "happy", - scenario: func() (req In, wantResp Out) { + scenario: func(deps *TestDeps) (req In, wantResp Out) { ethAddr, _, nibiruAddr := evmtest.NewEthAddrNibiruPair() req = &evm.QueryNibiruAccountRequest{ Address: ethAddr.String(), @@ -96,8 +101,8 @@ func (s *KeeperSuite) TestQueryNibiruAccount() { for _, tc := range testCases { s.Run(tc.name, func() { - req, wantResp := tc.scenario() deps := s.SetupTest() + req, wantResp := tc.scenario(&deps) goCtx := sdk.WrapSDKContext(deps.ctx) gotResp, err := deps.k.NibiruAccount(goCtx, req) if tc.wantErr != "" { @@ -107,25 +112,13 @@ func (s *KeeperSuite) TestQueryNibiruAccount() { s.Assert().NoError(err) s.EqualValues(wantResp, gotResp) }) - } - } func (s *KeeperSuite) TestQueryEthAccount() { - type In = *evm.QueryEthAccountRequest type Out = *evm.QueryEthAccountResponse - testCases := []struct { - name string - scenario func(deps *TestDeps) ( - req In, - wantResp Out, - ) - // Optional setup function to create the scenario - setup func(deps *TestDeps) - wantErr string - }{ + testCases := []TestCase[In, Out]{ { name: "sad: msg validation", scenario: func(deps *TestDeps) (req In, wantResp Out) { @@ -143,17 +136,6 @@ func (s *KeeperSuite) TestQueryEthAccount() { }, { name: "happy: fund account + query", - scenario: func(deps *TestDeps) (req In, wantResp Out) { - req = &evm.QueryEthAccountRequest{ - Address: deps.sender.EthAddr.Hex(), - } - wantResp = &evm.QueryEthAccountResponse{ - Balance: "420", - CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(), - Nonce: 0, - } - return req, wantResp - }, setup: func(deps *TestDeps) { chain := deps.chain ethAddr := deps.sender.EthAddr @@ -166,6 +148,17 @@ func (s *KeeperSuite) TestQueryEthAccount() { deps.ctx, evm.ModuleName, ethAddr.Bytes(), coins) s.Require().NoError(err) }, + scenario: func(deps *TestDeps) (req In, wantResp Out) { + req = &evm.QueryEthAccountRequest{ + Address: deps.sender.EthAddr.Hex(), + } + wantResp = &evm.QueryEthAccountResponse{ + Balance: "420", + CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(), + Nonce: 0, + } + return req, wantResp + }, wantErr: "", }, } @@ -186,7 +179,5 @@ func (s *KeeperSuite) TestQueryEthAccount() { s.Assert().NoError(err) s.EqualValues(wantResp, gotResp) }) - } - } diff --git a/x/evm/keeper/statedb.go b/x/evm/keeper/statedb.go index 0c15127f1..bb243c806 100644 --- a/x/evm/keeper/statedb.go +++ b/x/evm/keeper/statedb.go @@ -4,11 +4,12 @@ package keeper import ( "math/big" + sdk "github.com/cosmos/cosmos-sdk/types" + gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/NibiruChain/nibiru/eth" "github.com/NibiruChain/nibiru/x/evm" "github.com/NibiruChain/nibiru/x/evm/statedb" - sdk "github.com/cosmos/cosmos-sdk/types" - gethcommon "github.com/ethereum/go-ethereum/common" ) // SetState: Update contract storage, delete if value is empty. diff --git a/x/evm/query.go b/x/evm/query.go index 07ecdcf89..79235797d 100644 --- a/x/evm/query.go +++ b/x/evm/query.go @@ -69,6 +69,7 @@ func (req *QueryValidatorAccountRequest) Validate() ( } return consAddr, nil } + func (req *QueryBalanceRequest) Validate() error { if req == nil { return common.ErrNilGrpcMsg() @@ -82,6 +83,7 @@ func (req *QueryBalanceRequest) Validate() error { } return nil } + func (req *QueryStorageRequest) Validate() error { if req == nil { return common.ErrNilGrpcMsg() diff --git a/x/oracle/types/test_utils.go b/x/oracle/types/test_utils.go index 33b7ffd46..c5e06e88f 100644 --- a/x/oracle/types/test_utils.go +++ b/x/oracle/types/test_utils.go @@ -149,6 +149,7 @@ func (v MockValidator) TokensFromSharesRoundUp(sdk.Dec) sdk.Dec { return func (v MockValidator) SharesFromTokens(amt sdk.Int) (sdk.Dec, error) { return sdkmath.LegacyZeroDec(), nil } + func (v MockValidator) SharesFromTokensTruncated(amt sdk.Int) (sdk.Dec, error) { return sdkmath.LegacyZeroDec(), nil } From 75d3990496e1d9e30c2dcf2d5f44dbd933743715 Mon Sep 17 00:00:00 2001 From: Unique-Divine Date: Tue, 14 May 2024 23:31:46 -0500 Subject: [PATCH 11/11] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86be6cd09..da279fe54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1856](https://github.com/NibiruChain/nibiru/pull/1856) - feat(eth-rpc): Conversion types and functions between Ethereum txs and blocks and Tendermint ones. - [#1861](https://github.com/NibiruChain/nibiru/pull/1861) - feat(eth-rpc): RPC backend, Ethereum tracer, KV indexer, and RPC APIs - [#1869](https://github.com/NibiruChain/nibiru/pull/1869) - feat(eth): Module and start of keeper tests -- [#1873](https://github.com/NibiruChain/nibiru/pull/1873) - feat(evm): keeper grpc query impls and collection start +- [#1873](https://github.com/NibiruChain/nibiru/pull/1873) - feat(evm): keeper collections and grpc query impls for EthAccount, NibiruAccount #### Dapp modules: perp, spot, oracle, etc