Skip to content

Commit

Permalink
Create account for sendNative receiver (sei-protocol#1736)
Browse files Browse the repository at this point in the history
  • Loading branch information
codchen authored Jun 20, 2024
1 parent d2f408b commit 08204c6
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 15 deletions.
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@ func New(
app.IBCKeeper.ClientKeeper,
app.IBCKeeper.ConnectionKeeper,
app.IBCKeeper.ChannelKeeper,
app.AccountKeeper,
); err != nil {
panic(err)
}
Expand Down
24 changes: 16 additions & 8 deletions precompiles/bank/bank.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"math/big"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -54,9 +55,10 @@ func GetABI() abi.ABI {

type Precompile struct {
pcommon.Precompile
bankKeeper pcommon.BankKeeper
evmKeeper pcommon.EVMKeeper
address common.Address
accountKeeper pcommon.AccountKeeper
bankKeeper pcommon.BankKeeper
evmKeeper pcommon.EVMKeeper
address common.Address

SendID []byte
SendNativeID []byte
Expand All @@ -73,14 +75,15 @@ type CoinBalance struct {
Denom string
}

func NewPrecompile(bankKeeper pcommon.BankKeeper, evmKeeper pcommon.EVMKeeper) (*Precompile, error) {
func NewPrecompile(bankKeeper pcommon.BankKeeper, evmKeeper pcommon.EVMKeeper, accountKeeper pcommon.AccountKeeper) (*Precompile, error) {
newAbi := GetABI()

p := &Precompile{
Precompile: pcommon.Precompile{ABI: newAbi},
bankKeeper: bankKeeper,
evmKeeper: evmKeeper,
address: common.HexToAddress(BankAddress),
Precompile: pcommon.Precompile{ABI: newAbi},
bankKeeper: bankKeeper,
evmKeeper: evmKeeper,
accountKeeper: accountKeeper,
address: common.HexToAddress(BankAddress),
}

for name, m := range newAbi.Methods {
Expand Down Expand Up @@ -240,6 +243,11 @@ func (p Precompile) sendNative(ctx sdk.Context, method *abi.Method, args []inter
if err := p.bankKeeper.SendCoinsAndWei(ctx, senderSeiAddr, receiverSeiAddr, usei, wei); err != nil {
return nil, err
}
accExists := p.accountKeeper.HasAccount(ctx, receiverSeiAddr)
if !accExists {
defer telemetry.IncrCounter(1, "new", "account")
p.accountKeeper.SetAccount(ctx, p.accountKeeper.NewAccountWithAddress(ctx, receiverSeiAddr))
}

return method.Outputs.Pack(true)
}
Expand Down
20 changes: 15 additions & 5 deletions precompiles/bank/bank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestRun(t *testing.T) {
// Setup receiving addresses
seiAddr, evmAddr := testkeeper.MockAddressPair()
k.SetAddressMapping(ctx, seiAddr, evmAddr)
p, err := bank.NewPrecompile(k.BankKeeper(), k)
p, err := bank.NewPrecompile(k.BankKeeper(), k, k.AccountKeeper())
require.Nil(t, err)
statedb := state.NewDBImpl(ctx, k, true)
evm := vm.EVM{
Expand Down Expand Up @@ -194,6 +194,16 @@ func TestRun(t *testing.T) {
weiBalance := k.BankKeeper().GetWeiBalance(ctx, seiAddr)
require.Equal(t, big.NewInt(100), weiBalance.BigInt())

newAddr, _ := testkeeper.MockAddressPair()
require.Nil(t, k.AccountKeeper().GetAccount(ctx, newAddr))
argsNewAccount, err := sendNative.Inputs.Pack(newAddr.String())
require.Nil(t, err)
require.Nil(t, k.BankKeeper().SendCoins(ctx, seiAddr, k.GetSeiAddressOrDefault(ctx, p.Address()), sdk.NewCoins(sdk.NewCoin("usei", sdk.OneInt()))))
_, err = p.Run(&evm, evmAddr, evmAddr, append(p.SendNativeID, argsNewAccount...), big.NewInt(1), false)
require.Nil(t, err)
// should create account if not exists
require.NotNil(t, k.AccountKeeper().GetAccount(statedb.Ctx(), newAddr))

// test get all balances
allBalances, err := p.ABI.MethodById(p.AllBalancesID)
require.Nil(t, err)
Expand Down Expand Up @@ -256,7 +266,7 @@ func TestSendForUnlinkedReceiver(t *testing.T) {

// Setup receiving addresses - NOT linked
_, evmAddr := testkeeper.MockAddressPair()
p, err := bank.NewPrecompile(k.BankKeeper(), k)
p, err := bank.NewPrecompile(k.BankKeeper(), k, k.AccountKeeper())
require.Nil(t, err)
statedb := state.NewDBImpl(ctx, k, true)
evm := vm.EVM{
Expand Down Expand Up @@ -325,7 +335,7 @@ func TestSendForUnlinkedReceiver(t *testing.T) {
func TestMetadata(t *testing.T) {
k, ctx := testkeeper.MockEVMKeeper()
k.BankKeeper().SetDenomMetaData(ctx, banktypes.Metadata{Name: "SEI", Symbol: "usei", Base: "usei"})
p, err := bank.NewPrecompile(k.BankKeeper(), k)
p, err := bank.NewPrecompile(k.BankKeeper(), k, k.AccountKeeper())
require.Nil(t, err)
statedb := state.NewDBImpl(ctx, k, true)
evm := vm.EVM{
Expand Down Expand Up @@ -374,7 +384,7 @@ func TestMetadata(t *testing.T) {

func TestRequiredGas(t *testing.T) {
k, _ := testkeeper.MockEVMKeeper()
p, err := bank.NewPrecompile(k.BankKeeper(), k)
p, err := bank.NewPrecompile(k.BankKeeper(), k, k.AccountKeeper())
require.Nil(t, err)
balanceRequiredGas := p.RequiredGas(p.BalanceID)
require.Equal(t, uint64(1000), balanceRequiredGas)
Expand All @@ -384,7 +394,7 @@ func TestRequiredGas(t *testing.T) {

func TestAddress(t *testing.T) {
k, _ := testkeeper.MockEVMKeeper()
p, err := bank.NewPrecompile(k.BankKeeper(), k)
p, err := bank.NewPrecompile(k.BankKeeper(), k, k.AccountKeeper())
require.Nil(t, err)
require.Equal(t, common.HexToAddress(bank.BankAddress), p.Address())
}
7 changes: 7 additions & 0 deletions precompiles/common/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/cosmos/ibc-go/v3/modules/core/exported"

sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
Expand Down Expand Up @@ -41,6 +42,12 @@ type EVMKeeper interface {
GetERC721CW721Pointer(ctx sdk.Context, cw721Address string) (addr common.Address, version uint16, exists bool)
}

type AccountKeeper interface {
HasAccount(ctx sdk.Context, addr sdk.AccAddress) bool
SetAccount(ctx sdk.Context, acc authtypes.AccountI)
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
}

type OracleKeeper interface {
IterateBaseExchangeRates(ctx sdk.Context, handler func(denom string, exchangeRate oracletypes.OracleExchangeRate) (stop bool))
CalculateTwaps(ctx sdk.Context, lookbackSeconds uint64) (oracletypes.OracleTwaps, error)
Expand Down
5 changes: 3 additions & 2 deletions precompiles/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ func InitializePrecompiles(
clientKeeper common.ClientKeeper,
connectionKeeper common.ConnectionKeeper,
channelKeeper common.ChannelKeeper,
accountKeeper common.AccountKeeper,
) error {
SetupMtx.Lock()
defer SetupMtx.Unlock()
if Initialized {
panic("precompiles already initialized")
}
bankp, err := bank.NewPrecompile(bankKeeper, evmKeeper)
bankp, err := bank.NewPrecompile(bankKeeper, evmKeeper, accountKeeper)
if err != nil {
return err
}
Expand Down Expand Up @@ -133,7 +134,7 @@ func InitializePrecompiles(
func GetPrecompileInfo(name string) PrecompileInfo {
if !Initialized {
// Precompile Info does not require any keeper state
_ = InitializePrecompiles(true, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
_ = InitializePrecompiles(true, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
}
i, ok := PrecompileNamesToInfo[name]
if !ok {
Expand Down

0 comments on commit 08204c6

Please sign in to comment.