Skip to content

Commit

Permalink
Merge pull request #7473 from Agoric/mfig-vbank-only-macc-events
Browse files Browse the repository at this point in the history
Only "module account" transfer events cause vpurse balance updates
  • Loading branch information
mergify[bot] authored Apr 22, 2023
2 parents 7760a65 + f90f094 commit 338650a
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 10 deletions.
2 changes: 1 addition & 1 deletion golang/cosmos/x/vbank/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The Vbank module maintains no significant state, but will access stored state th

Purse operations which change the balance result in a downcall to this module to update the underlying account. A downcall is also made to query the account balance.

Upon an `EndBlock()` call, the module will scan the block for all `MsgSend` and `MsgMultiSend` events (see `cosmos-sdk/x/bank/spec/04_events.md`) and perform a `VBANK_BALANCE_UPDATE` upcall for all denominations held in all mentioned accounts.
Upon an `EndBlock()` call, the module will scan the block for all `MsgSend` and `MsgMultiSend` events (see `cosmos-sdk/x/bank/spec/04_events.md`) and perform a `VBANK_BALANCE_UPDATE` upcall for all denominations held in *only the mentioned module accounts*.

The following fields are common to the Vbank messages:
- `"address"`, `"recipient"`, `"sender"`: account address as a bech32-encoded string
Expand Down
10 changes: 10 additions & 0 deletions golang/cosmos/x/vbank/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/Agoric/agoric-sdk/golang/cosmos/x/vbank/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

vm "github.com/Agoric/agoric-sdk/golang/cosmos/vm"
Expand Down Expand Up @@ -82,6 +83,15 @@ func (k Keeper) GetModuleAccountAddress(ctx sdk.Context, name string) sdk.AccAdd
return k.accountKeeper.GetModuleAddress(name)
}

func (k Keeper) IsModuleAccount(ctx sdk.Context, addr sdk.AccAddress) bool {
acc := k.accountKeeper.GetAccount(ctx, addr)
if acc == nil {
return false
}
_, ok := acc.(authtypes.ModuleAccountI)
return ok
}

func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramSpace.GetParamSet(ctx, &params)
return params
Expand Down
14 changes: 13 additions & 1 deletion golang/cosmos/x/vbank/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,26 @@ NextEvent:
}
}

// Prune the addressToUpdate map to only include module accounts. We prune
// only after recording and consolidating all account updates to minimize the
// number of account keeper queries.
unfilteredAddresses := addressToUpdate
addressToUpdate = make(map[string]sdk.Coins, len(addressToUpdate))
for addr, denoms := range unfilteredAddresses {
accAddr, err := sdk.AccAddressFromBech32(addr)
if err == nil && am.keeper.IsModuleAccount(ctx, accAddr) {
// Pass through the module account.
addressToUpdate[addr] = denoms
}
}

// Dump all the addressToBalances entries to SwingSet.
action := getBalanceUpdate(ctx, am.keeper, addressToUpdate)
if action != nil {
err := am.PushAction(ctx, action)
if err != nil {
panic(err)
}

}

if err := am.keeper.DistributeRewards(ctx); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions golang/cosmos/x/vbank/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)

// A subset of github.com/cosmos/cosmos-sdk/x/bank/keeper.Keeper
Expand All @@ -17,4 +18,5 @@ type BankKeeper interface {

type AccountKeeper interface {
GetModuleAddress(name string) sdk.AccAddress
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
}
68 changes: 60 additions & 8 deletions golang/cosmos/x/vbank/vbank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -98,7 +99,7 @@ func decodeBalances(encoded []byte) (balances, uint64, error) {
return nil, 0, err
}
b := newBalances()
fmt.Printf("updated balances %v\n", balanceUpdate.Updated)
// fmt.Printf("updated balances %v\n", balanceUpdate.Updated)
for _, u := range balanceUpdate.Updated {
account(u.Address, coin(u.Denom, u.Amount))(b)
}
Expand Down Expand Up @@ -514,7 +515,14 @@ func Test_EndBlock_Events(t *testing.T) {
sdk.NewInt64Coin("arcadeTokens", 7),
),
}}
keeper, ctx := makeTestKit(nil, bank)
acct := &mockAuthKeeper{
accounts: map[string]authtypes.AccountI{
addr1: &authtypes.ModuleAccount{BaseAccount: &authtypes.BaseAccount{}},
addr2: &authtypes.ModuleAccount{BaseAccount: &authtypes.BaseAccount{}},
addr3: &authtypes.BaseAccount{},
},
}
keeper, ctx := makeTestKit(acct, bank)
// Turn off rewards.
keeper.SetParams(ctx, types.Params{PerEpochRewardFraction: sdk.ZeroDec()})
msgsSent := []string{}
Expand Down Expand Up @@ -552,6 +560,14 @@ func Test_EndBlock_Events(t *testing.T) {
{Key: []byte("amount"), Value: []byte("500ubld,600urun,700ushmoo")},
},
},
{
Type: "non_modaccount",
Attributes: []abci.EventAttribute{
{Key: []byte("receiver"), Value: []byte(addr3)},
{Key: []byte("spender"), Value: []byte(addr4)},
{Key: []byte("amount"), Value: []byte("100ubld")},
},
},
}
em := sdk.NewEventManagerWithHistory(events)
ctx = ctx.WithEventManager(em)
Expand Down Expand Up @@ -730,16 +746,38 @@ func Test_EndBlock_Rewards(t *testing.T) {
}
}

type mockAccount struct{}
type mockAuthKeeper struct{
accounts map[string]authtypes.AccountI
}

func (ma mockAccount) GetModuleAddress(name string) sdk.AccAddress {
func (ma mockAuthKeeper) GetModuleAddress(name string) sdk.AccAddress {
return sdk.AccAddress(name)
}

func (ma mockAuthKeeper) GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI {
// fmt.Printf("GetAccount %s\n", addr.String())
return ma.accounts[addr.String()]
}

func Test_Module_Account(t *testing.T) {
account := &mockAccount{}
keeper, ctx := makeTestKit(account, nil)
ch := NewPortHandler(AppModule{}, keeper)
moduleBech32 := "cosmos1we3xzmnt9aex2um9wfmx2em0pd0"
moduleJson, err := json.Marshal(moduleBech32)
if err != nil {
t.Fatalf("got error = %v", err)
}

acct := &mockAuthKeeper{
accounts: map[string]authtypes.AccountI{
moduleBech32: &authtypes.ModuleAccount{
BaseAccount: &authtypes.BaseAccount{},
Name: "vbank/reserve",
},
addr1: &authtypes.BaseAccount{},
},
}
keeper, ctx := makeTestKit(acct, nil)
am := AppModule{keeper: keeper}
ch := NewPortHandler(am, keeper)
ctlCtx := &vm.ControllerContext{Context: ctx}

mod1 := "vbank/reserve"
Expand All @@ -750,8 +788,22 @@ func Test_Module_Account(t *testing.T) {
if err != nil {
t.Fatalf("got error = %v", err)
}
expected := `"cosmos1we3xzmnt9aex2um9wfmx2em0pd0"`

expected := string(moduleJson)
if ret != expected {
t.Errorf("got ret = %v, want %v", ret, expected)
}

modAddr := sdk.MustAccAddressFromBech32(moduleBech32)
if !keeper.IsModuleAccount(ctx, modAddr) {
t.Errorf("got IsModuleAccount modAddr = false, want true")
}
notModAddr := sdk.MustAccAddressFromBech32(addr1)
if keeper.IsModuleAccount(ctx, notModAddr) {
t.Errorf("got IsModuleAccount notModAddr = true, want false")
}
missingAddr := sdk.MustAccAddressFromBech32(addr2)
if keeper.IsModuleAccount(ctx, missingAddr) {
t.Errorf("got IsModuleAccount missingAddr = false, want true")
}
}

0 comments on commit 338650a

Please sign in to comment.