Skip to content

Commit

Permalink
wip!: Save checkpoint.
Browse files Browse the repository at this point in the history
1. Created NibiruBankKeeper with safety around NIBI transfers inside of
   EthereumTx.
2. The "PrecompileCalled" JournalChange now has a propery implementation
   and a strong test case to show that reverting the precompile calls
   works as intended.
3. Remove unneeded functions created for testing with low-level struct
   fields.
  • Loading branch information
Unique-Divine committed Oct 26, 2024
1 parent 80dd2d7 commit c624912
Show file tree
Hide file tree
Showing 17 changed files with 289 additions and 143 deletions.
20 changes: 17 additions & 3 deletions app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ type AppKeepers struct {
}

type privateKeepers struct {
bankBaseKeeper bankkeeper.BaseKeeper
capabilityKeeper *capabilitykeeper.Keeper
slashingKeeper slashingkeeper.Keeper
crisisKeeper crisiskeeper.Keeper
Expand Down Expand Up @@ -262,13 +263,26 @@ func (app *NibiruApp) InitKeepers(
sdk.GetConfig().GetBech32AccountAddrPrefix(),
govModuleAddr,
)
app.BankKeeper = bankkeeper.NewBaseKeeper(

app.bankBaseKeeper = bankkeeper.NewBaseKeeper(
appCodec,
keys[banktypes.StoreKey],
app.AccountKeeper,
BlockedAddresses(),
govModuleAddr,
)
nibiruBankKeeper := evmkeeper.NibiruBankKeeper{
BaseKeeper: bankkeeper.NewBaseKeeper(
appCodec,
keys[banktypes.StoreKey],
app.AccountKeeper,
BlockedAddresses(),
govModuleAddr,
),
StateDB: nil,
}
app.BankKeeper = nibiruBankKeeper

app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec,
keys[stakingtypes.StoreKey],
Expand Down Expand Up @@ -370,7 +384,7 @@ func (app *NibiruApp) InitKeepers(
tkeys[evm.TransientKey],
authtypes.NewModuleAddress(govtypes.ModuleName),
app.AccountKeeper,
app.BankKeeper,
&nibiruBankKeeper,
app.StakingKeeper,
cast.ToString(appOpts.Get("evm.tracer")),
)
Expand Down Expand Up @@ -605,7 +619,7 @@ func (app *NibiruApp) initAppModules(
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
bank.NewAppModule(appCodec, app.bankBaseKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
capability.NewAppModule(appCodec, *app.capabilityKeeper, false),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)),
Expand Down
13 changes: 0 additions & 13 deletions x/evm/deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package evm
import (
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bank "github.com/cosmos/cosmos-sdk/x/bank/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

Expand Down Expand Up @@ -32,18 +31,6 @@ type AccountKeeper interface {
SetModuleAccount(ctx sdk.Context, macc authtypes.ModuleAccountI)
}

// 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

GetDenomMetaData(ctx sdk.Context, denom string) (metadata bank.Metadata, isFound bool)
SetDenomMetaData(ctx sdk.Context, denomMetaData bank.Metadata)
}

// StakingKeeper returns the historical headers kept in store.
type StakingKeeper interface {
GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, bool)
Expand Down
3 changes: 2 additions & 1 deletion x/evm/evmtest/test_deps.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ func NewTestDeps() TestDeps {
}

func (deps TestDeps) StateDB() *statedb.StateDB {
return statedb.New(deps.Ctx, &deps.App.EvmKeeper,
return deps.EvmKeeper.NewStateDB(
deps.Ctx,
statedb.NewEmptyTxConfig(
gethcommon.BytesToHash(deps.Ctx.HeaderHash().Bytes()),
),
Expand Down
163 changes: 163 additions & 0 deletions x/evm/keeper/bank_extension.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
package keeper

import (
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"

"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{}
)

type NibiruBankKeeper struct {
bankkeeper.BaseKeeper
StateDB *statedb.StateDB
balanceChangesForStateDB uint64
}

func (evmKeeper *Keeper) NewStateDB(
ctx sdk.Context, txConfig statedb.TxConfig,
) *statedb.StateDB {
stateDB := statedb.New(ctx, evmKeeper, txConfig)
bk := evmKeeper.bankKeeper
bk.StateDB = stateDB
bk.balanceChangesForStateDB = 0
return stateDB
}

// BalanceChangesForStateDB returns the count of [statedb.JournalChange] entries
// that were added to the current [statedb.StateDB]
func (bk *NibiruBankKeeper) BalanceChangesForStateDB() uint64 { return bk.balanceChangesForStateDB }

func (bk NibiruBankKeeper) MintCoins(
ctx sdk.Context,
moduleName string,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.MintCoins(ctx, moduleName, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
moduleBech32Addr := auth.NewModuleAddress(evm.ModuleName)
bk.SyncStateDBWithAccount(ctx, moduleBech32Addr)
}
return nil
}

func (bk NibiruBankKeeper) BurnCoins(
ctx sdk.Context,
moduleName string,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.BurnCoins(ctx, moduleName, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
moduleBech32Addr := auth.NewModuleAddress(evm.ModuleName)
bk.SyncStateDBWithAccount(ctx, moduleBech32Addr)
}
return nil
}

func (bk NibiruBankKeeper) SendCoins(
ctx sdk.Context,
fromAddr sdk.AccAddress,
toAddr sdk.AccAddress,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.SendCoins(ctx, fromAddr, toAddr, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
bk.SyncStateDBWithAccount(ctx, fromAddr)
bk.SyncStateDBWithAccount(ctx, toAddr)
}
return nil
}

func (bk *NibiruBankKeeper) SyncStateDBWithAccount(
ctx sdk.Context, acc sdk.AccAddress,
) {
// If there's no StateDB set, it means we're not in an EthereumTx.
if bk.StateDB == nil {
return
}
balanceWei := evm.NativeToWei(
bk.GetBalance(ctx, acc, evm.EVMBankDenom).Amount.BigInt(),
)
bk.StateDB.SetBalanceWei(eth.NibiruAddrToEthAddr(acc), balanceWei)
bk.balanceChangesForStateDB += 1
}

func findEtherBalanceChangeFromCoins(coins sdk.Coins) (found bool) {
for _, c := range coins {
if c.Denom == evm.EVMBankDenom {
return true
}
}
return false
}

func (bk NibiruBankKeeper) SendCoinsFromAccountToModule(
ctx sdk.Context,
senderAddr sdk.AccAddress,
recipientModule string,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.SendCoinsFromAccountToModule(ctx, senderAddr, recipientModule, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
bk.SyncStateDBWithAccount(ctx, senderAddr)
moduleBech32Addr := auth.NewModuleAddress(recipientModule)
bk.SyncStateDBWithAccount(ctx, moduleBech32Addr)
}
return nil
}

func (bk NibiruBankKeeper) SendCoinsFromModuleToAccount(
ctx sdk.Context,
senderModule string,
recipientAddr sdk.AccAddress,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.SendCoinsFromModuleToAccount(ctx, senderModule, recipientAddr, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
moduleBech32Addr := auth.NewModuleAddress(senderModule)
bk.SyncStateDBWithAccount(ctx, moduleBech32Addr)
bk.SyncStateDBWithAccount(ctx, recipientAddr)
}
return nil
}

func (bk NibiruBankKeeper) SendCoinsFromModuleToModule(
ctx sdk.Context,
senderModule string,
recipientModule string,
coins sdk.Coins,
) error {
// Use the embedded function from [bankkeeper.Keeper]
if err := bk.BaseKeeper.SendCoinsFromModuleToModule(ctx, senderModule, recipientModule, coins); err != nil {
return err
}
if findEtherBalanceChangeFromCoins(coins) {
senderBech32Addr := auth.NewModuleAddress(senderModule)
recipientBech32Addr := auth.NewModuleAddress(recipientModule)
bk.SyncStateDBWithAccount(ctx, senderBech32Addr)
bk.SyncStateDBWithAccount(ctx, recipientBech32Addr)
}
return nil
}
5 changes: 3 additions & 2 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Keeper struct {
// this should be the x/gov module account.
authority sdk.AccAddress

bankKeeper evm.BankKeeper
bankKeeper *NibiruBankKeeper
accountKeeper evm.AccountKeeper
stakingKeeper evm.StakingKeeper

Expand All @@ -63,13 +63,14 @@ func NewKeeper(
storeKey, transientKey storetypes.StoreKey,
authority sdk.AccAddress,
accKeeper evm.AccountKeeper,
bankKeeper evm.BankKeeper,
bankKeeper *NibiruBankKeeper,
stakingKeeper evm.StakingKeeper,
tracer string,
) Keeper {
if err := sdk.VerifyAddressFormat(authority); err != nil {
panic(err)
}

return Keeper{
cdc: cdc,
storeKey: storeKey,
Expand Down
2 changes: 1 addition & 1 deletion x/evm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func (k *Keeper) ApplyEvmMsg(ctx sdk.Context,
vmErr error // vm errors do not effect consensus and are therefore not assigned to err
)

stateDB := statedb.New(ctx, k, txConfig)
stateDB := k.NewStateDB(ctx, txConfig)
evmObj = k.NewEVM(ctx, msg, evmConfig, tracer, stateDB)

leftoverGas := msg.Gas()
Expand Down
15 changes: 9 additions & 6 deletions x/evm/keeper/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,31 +65,34 @@ func (k *Keeper) ForEachStorage(
}
}

// SetAccBalance update account's balance, compare with current balance first, then decide to mint or burn.
// SetAccBalance update account's balance, compare with current balance first,
// then decide to mint or burn.
// Implements the `statedb.Keeper` interface.
// Only called by `StateDB.Commit()`.
func (k *Keeper) SetAccBalance(
ctx sdk.Context, addr gethcommon.Address, amountEvmDenom *big.Int,
) error {
nativeAddr := sdk.AccAddress(addr.Bytes())
balance := k.bankKeeper.GetBalance(ctx, nativeAddr, evm.EVMBankDenom).Amount.BigInt()
balance := k.bankKeeper.BaseKeeper.GetBalance(ctx, nativeAddr, evm.EVMBankDenom).Amount.BigInt()
delta := new(big.Int).Sub(amountEvmDenom, balance)

switch delta.Sign() {
case 1:
// mint
coins := sdk.NewCoins(sdk.NewCoin(evm.EVMBankDenom, sdkmath.NewIntFromBigInt(delta)))
if err := k.bankKeeper.MintCoins(ctx, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.BaseKeeper.MintCoins(ctx, evm.ModuleName, coins); err != nil {
return err
}
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, evm.ModuleName, nativeAddr, coins); err != nil {
if err := k.bankKeeper.BaseKeeper.SendCoinsFromModuleToAccount(ctx, evm.ModuleName, nativeAddr, coins); err != nil {
return err
}
case -1:
// burn
coins := sdk.NewCoins(sdk.NewCoin(evm.EVMBankDenom, sdkmath.NewIntFromBigInt(new(big.Int).Neg(delta))))
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, nativeAddr, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.BaseKeeper.SendCoinsFromAccountToModule(ctx, nativeAddr, evm.ModuleName, coins); err != nil {
return err
}
if err := k.bankKeeper.BurnCoins(ctx, evm.ModuleName, coins); err != nil {
if err := k.bankKeeper.BaseKeeper.BurnCoins(ctx, evm.ModuleName, coins); err != nil {
return err
}
default:
Expand Down
2 changes: 1 addition & 1 deletion x/evm/precompile/funtoken.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (p precompileFunToken) Run(
if err != nil {
return nil, err
}
return bz, OnRunEnd(start.StateDB, start.SnapshotBeforeRun, p.Address())
return bz, err
}

func PrecompileFunToken(keepers keepers.PublicKeepers) vm.PrecompiledContract {
Expand Down
Loading

0 comments on commit c624912

Please sign in to comment.