Skip to content

Commit

Permalink
Merge branch 'main' into mat/bank-precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
k-yang authored Jan 6, 2025
2 parents 2999827 + 350b9e9 commit 7afd3a0
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 64 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#2125](https://github.com/NibiruChain/nibiru/pull/2125) - feat(evm-precompile):Emit EVM events created to reflect the ABCI events that occur outside the EVM to make sure that block explorers and indexers can find indexed ABCI event information.
- [#2129](https://github.com/NibiruChain/nibiru/pull/2129) - fix(evm): issue with infinite recursion in erc20 funtoken contracts
- [#2134](https://github.com/NibiruChain/nibiru/pull/2134) - fix(evm): query of NIBI should use bank state, not the StateDB
- [#2140](https://github.com/NibiruChain/nibiru/pull/2140) - fix(bank): bank keeper extension now charges gas for the bank operations
- [#2141](https://github.com/NibiruChain/nibiru/pull/2141) - refactor: simplify account retrieval operation in `nibid q evm account`.
- [#2142](https://github.com/NibiruChain/nibiru/pull/2142) - fix(bank): add additional missing methods to the NibiruBankKeeper


#### Nibiru EVM | Before Audit 2 - 2024-12-06

Expand Down
2 changes: 1 addition & 1 deletion app/ante/fixed_gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (suite *AnteTestSuite) TestOraclePostPriceTransactionsHaveFixedPrice() {
Amount: sdk.NewCoins(sdk.NewInt64Coin(appconst.BondDenom, 200)),
},
},
expectedGas: 38175,
expectedGas: 67193,
expectedErr: nil,
},
}
Expand Down
87 changes: 68 additions & 19 deletions x/evm/keeper/bank_extension.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
package keeper

import (
store "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
auth "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"

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

var (
_ bankkeeper.Keeper = &NibiruBankKeeper{}
_ bankkeeper.SendKeeper = &NibiruBankKeeper{}
)
var _ bankkeeper.Keeper = &NibiruBankKeeper{}

type NibiruBankKeeper struct {
bankkeeper.BaseKeeper
Expand All @@ -29,6 +26,69 @@ func (evmKeeper *Keeper) NewStateDB(
return stateDB
}

func (bk NibiruBankKeeper) InputOutputCoins(
ctx sdk.Context,
input []banktypes.Input,
output []banktypes.Output,
) error {
return bk.ForceGasInvariant(
ctx,
func(ctx sdk.Context) error {
return bk.BaseKeeper.InputOutputCoins(ctx, input, output)
},
func(ctx sdk.Context) {
for _, input := range input {
if findEtherBalanceChangeFromCoins(input.Coins) {
bk.SyncStateDBWithAccount(ctx, sdk.MustAccAddressFromBech32(input.Address))
}
}
for _, output := range output {
if findEtherBalanceChangeFromCoins(output.Coins) {
bk.SyncStateDBWithAccount(ctx, sdk.MustAccAddressFromBech32(output.Address))
}
}
},
)
}

func (bk NibiruBankKeeper) DelegateCoins(
ctx sdk.Context,
delegatorAddr sdk.AccAddress,
moduleBech32Addr sdk.AccAddress,
coins sdk.Coins,
) error {
return bk.ForceGasInvariant(
ctx,
func(ctx sdk.Context) error {
return bk.BaseKeeper.DelegateCoins(ctx, delegatorAddr, moduleBech32Addr, coins)
},
func(ctx sdk.Context) {
if findEtherBalanceChangeFromCoins(coins) {
bk.SyncStateDBWithAccount(ctx, delegatorAddr)
}
},
)
}

func (bk NibiruBankKeeper) UndelegateCoins(
ctx sdk.Context,
delegatorAddr sdk.AccAddress,
moduleBech32Addr sdk.AccAddress,
coins sdk.Coins,
) error {
return bk.ForceGasInvariant(
ctx,
func(ctx sdk.Context) error {
return bk.BaseKeeper.UndelegateCoins(ctx, delegatorAddr, moduleBech32Addr, coins)
},
func(ctx sdk.Context) {
if findEtherBalanceChangeFromCoins(coins) {
bk.SyncStateDBWithAccount(ctx, delegatorAddr)
}
},
)
}

func (bk NibiruBankKeeper) MintCoins(
ctx sdk.Context,
moduleName string,
Expand Down Expand Up @@ -108,10 +168,9 @@ func (bk NibiruBankKeeper) ForceGasInvariant(
// Note that because the ctx gas meter uses private variables to track gas,
// we have to branch off with a new gas meter instance to avoid mutating the
// "true" gas meter (called GasMeterBefore here).
ctx = ctx.
WithGasMeter(sdk.NewGasMeter(gasMeterBefore.Limit())).
WithKVGasConfig(zeroCostGasConfig).
WithTransientKVGasConfig(zeroCostGasConfig)
// We use an infinite gas meter because we consume gas in the deferred function
// and gasMeterBefore will panic if we consume too much gas.
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())

err := BaseOp(ctx)
baseOpGasConsumed = ctx.GasMeter().GasConsumed()
Expand All @@ -123,16 +182,6 @@ func (bk NibiruBankKeeper) ForceGasInvariant(
return nil
}

var zeroCostGasConfig store.GasConfig = store.GasConfig{
HasCost: 0,
DeleteCost: 0,
ReadCostFlat: 0,
ReadCostPerByte: 0,
WriteCostFlat: 0,
WriteCostPerByte: 0,
IterNextCostFlat: 0,
}

func (bk NibiruBankKeeper) SendCoins(
ctx sdk.Context,
fromAddr sdk.AccAddress,
Expand Down
8 changes: 5 additions & 3 deletions x/evm/keeper/bank_extension_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ func (s *Suite) TestGasConsumedInvariantSend() {
for idx, tc := range testCases {
s.Run(tc.name, func() {
gasConsumed := tc.GasConsumedInvariantScenario.Run(s, to)
s.T().Logf("gasConsumed: %d", gasConsumed)
s.Require().NotZerof(gasConsumed, "gasConsumed should not be zero")
if idx == 0 {
first = gasConsumed
return
}
// Each elem being equal to "first" implies that each elem is equal
s.Equalf(
fmt.Sprintf("%d", first),
fmt.Sprintf("%d", gasConsumed),
first,
gasConsumed,
"Gas consumed should be equal",
)
})
Expand Down Expand Up @@ -106,7 +108,7 @@ func (scenario GasConsumedInvariantScenario) Run(
)
gasConsumedAfter := deps.Ctx.GasMeter().GasConsumed()

s.GreaterOrEqualf(gasConsumedAfter, gasConsumedBefore,
s.Greaterf(gasConsumedAfter, gasConsumedBefore,
"gas meter consumed should not be negative: gas consumed after = %d, gas consumed before = %d ",
gasConsumedAfter, gasConsumedBefore,
)
Expand Down
7 changes: 5 additions & 2 deletions x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ func (k Keeper) EthAccount(
}

ctx := sdk.UnwrapSDKContext(goCtx)
acct := k.GetAccountOrEmpty(ctx, addrEth)
acct := k.getAccountWithoutBalance(ctx, addrEth)
if acct == nil {
return nil, fmt.Errorf("account not found for %s", addrEth.Hex())
}
balNative := k.Bank.GetBalance(ctx, addrBech32, evm.EVMBankDenom).Amount.BigInt()

return &evm.QueryEthAccountResponse{
Expand Down Expand Up @@ -205,7 +208,7 @@ func (k Keeper) Code(
ctx := sdk.UnwrapSDKContext(goCtx)

address := gethcommon.HexToAddress(req.Address)
acct := k.GetAccountWithoutBalance(ctx, address)
acct := k.getAccountWithoutBalance(ctx, address)

var code []byte
if acct != nil && acct.IsContract() {
Expand Down
22 changes: 4 additions & 18 deletions x/evm/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,10 @@ func (s *Suite) TestQueryEvmAccount() {
req = &evm.QueryEthAccountRequest{
Address: ethAcc.EthAddr.String(),
}
wantResp = &evm.QueryEthAccountResponse{
Balance: "0",
BalanceWei: "0",
CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(),
Nonce: 0,
EthAddress: ethAcc.EthAddr.String(),
Bech32Address: ethAcc.NibiruAddr.String(),
}
wantResp = nil
return req, wantResp
},
wantErr: "",
wantErr: "account not found for",
},
{
name: "happy: nonexistent account (bech32 input)",
Expand All @@ -163,17 +156,10 @@ func (s *Suite) TestQueryEvmAccount() {
req = &evm.QueryEthAccountRequest{
Address: ethAcc.NibiruAddr.String(),
}
wantResp = &evm.QueryEthAccountResponse{
Balance: "0",
BalanceWei: "0",
CodeHash: gethcommon.BytesToHash(evm.EmptyCodeHash).Hex(),
Nonce: 0,
EthAddress: ethAcc.EthAddr.String(),
Bech32Address: ethAcc.NibiruAddr.String(),
}
wantResp = nil
return req, wantResp
},
wantErr: "",
wantErr: "account not found for",
},
}

Expand Down
25 changes: 4 additions & 21 deletions x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ var _ statedb.Keeper = &Keeper{}
// Implements the `statedb.Keeper` interface.
// Returns nil if the account does not exist or has the wrong type.
func (k *Keeper) GetAccount(ctx sdk.Context, addr gethcommon.Address) *statedb.Account {
acct := k.GetAccountWithoutBalance(ctx, addr)
acct := k.getAccountWithoutBalance(ctx, addr)
if acct == nil {
return nil
}
Expand Down Expand Up @@ -184,11 +184,10 @@ func (k *Keeper) DeleteAccount(ctx sdk.Context, addr gethcommon.Address) error {
return nil
}

// GetAccountWithoutBalance load nonce and codehash without balance,
// 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)
func (k *Keeper) getAccountWithoutBalance(ctx sdk.Context, addr gethcommon.Address) *statedb.Account {
acct := k.accountKeeper.GetAccount(ctx, eth.EthAddrToNibiruAddr(addr))
if acct == nil {
return nil
}
Expand All @@ -204,19 +203,3 @@ func (k *Keeper) GetAccountWithoutBalance(ctx sdk.Context, addr gethcommon.Addre
CodeHash: codeHash,
}
}

// 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{
BalanceNative: new(big.Int),
CodeHash: evm.EmptyCodeHash,
}
}

0 comments on commit 7afd3a0

Please sign in to comment.