diff --git a/golang/cosmos/proto/agoric/vbank/vbank.proto b/golang/cosmos/proto/agoric/vbank/vbank.proto index 7884abecc9a..4b47cf71c70 100644 --- a/golang/cosmos/proto/agoric/vbank/vbank.proto +++ b/golang/cosmos/proto/agoric/vbank/vbank.proto @@ -33,6 +33,13 @@ message Params { int64 reward_smoothing_blocks = 3 [ (gogoproto.moretags) = "yaml:\"reward_smoothing_blocks\"" ]; + + // allowed_monitoring_accounts is an array of account addresses that can be + // monitored for sends and receives. An element of `"*"` will permit any + // address. + repeated string allowed_monitoring_accounts = 4 [ + (gogoproto.moretags) = "yaml:\"allowed_monitoring_accounts\"" + ]; } // The current state of the module. diff --git a/golang/cosmos/x/vbank/README.md b/golang/cosmos/x/vbank/README.md index 99aaee4d233..24e8ee2631b 100644 --- a/golang/cosmos/x/vbank/README.md +++ b/golang/cosmos/x/vbank/README.md @@ -13,6 +13,11 @@ entirely at the ERTP level. - `feeCollectorName`: the module which handles fee distribution to stakers. - `reward_epoch_duration_blocks`: the duration (in blocks) over which fees should be given to the fee collector. +- `per_epoch_reward_fraction`: a decimal of how much of the `GiveawayPool` is paid as validator rewards per epoch +- `allowed_monitoring_accounts`: an array of account addresses that can be + monitored for sends and receives, defaulting to + `[authtypes.NewModuleAddress(types.ProvisionPoolName)]`. An element of `"*"` + will permit any address. ## State @@ -22,7 +27,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 *only the mentioned module 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 in the allowed_monitoring_accounts*. The following fields are common to the Vbank messages: - `"address"`, `"recipient"`, `"sender"`: account address as a bech32-encoded string diff --git a/golang/cosmos/x/vbank/keeper/keeper.go b/golang/cosmos/x/vbank/keeper/keeper.go index 6cdfb877674..4e2932d8bfd 100644 --- a/golang/cosmos/x/vbank/keeper/keeper.go +++ b/golang/cosmos/x/vbank/keeper/keeper.go @@ -6,7 +6,6 @@ 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" @@ -88,17 +87,13 @@ func (k Keeper) GetModuleAccountAddress(ctx sdk.Context, name string) sdk.AccAdd return acct.GetAddress() } -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) IsAllowedMonitoringAccount(ctx sdk.Context, addr sdk.AccAddress) bool { + params := k.GetParams(ctx) + return params.IsAllowedMonitoringAccount(addr.String()) } func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { - k.paramSpace.GetParamSet(ctx, ¶ms) + k.paramSpace.GetParamSetIfExists(ctx, ¶ms) return params } diff --git a/golang/cosmos/x/vbank/keeper/migrations.go b/golang/cosmos/x/vbank/keeper/migrations.go new file mode 100644 index 00000000000..360d691bd61 --- /dev/null +++ b/golang/cosmos/x/vbank/keeper/migrations.go @@ -0,0 +1,30 @@ +package keeper + +import ( + "github.com/Agoric/agoric-sdk/golang/cosmos/x/vbank/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Migrator handles in-place store migrations. +type Migrator struct { + keeper Keeper +} + +// NewMigrator creates a new Migrator based on the keeper. +func NewMigrator(keeper Keeper) Migrator { + return Migrator{keeper: keeper} +} + +// Migrate1to2 migrates from version 1 to 2. +func (m Migrator) Migrate1to2(ctx sdk.Context) error { + params := m.keeper.GetParams(ctx) + if params.AllowedMonitoringAccounts != nil { + return nil + } + + defaultParams := types.DefaultParams() + params.AllowedMonitoringAccounts = defaultParams.AllowedMonitoringAccounts + m.keeper.SetParams(ctx, params) + + return nil +} diff --git a/golang/cosmos/x/vbank/module.go b/golang/cosmos/x/vbank/module.go index 812b474eb86..0d755d6a60b 100644 --- a/golang/cosmos/x/vbank/module.go +++ b/golang/cosmos/x/vbank/module.go @@ -91,7 +91,7 @@ func (AppModule) Name() string { return ModuleName } -func (AppModule) ConsensusVersion() uint64 { return 1 } +func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock implements the AppModule interface func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) { @@ -157,7 +157,7 @@ NextEvent: 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) { + if err == nil && am.keeper.IsAllowedMonitoringAccount(ctx, accAddr) { // Pass through the module account. addressToUpdate[addr] = denoms } @@ -204,6 +204,12 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { tx := &types.UnimplementedMsgServer{} types.RegisterMsgServer(cfg.MsgServer(), tx) types.RegisterQueryServer(cfg.QueryServer(), am.keeper) + + m := keeper.NewMigrator(am.keeper) + err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2) + if err != nil { + panic(err) + } } // InitGenesis performs genesis initialization for the ibc-transfer module. It returns diff --git a/golang/cosmos/x/vbank/types/params.go b/golang/cosmos/x/vbank/types/params.go index 82398e9948d..010f8c954c1 100644 --- a/golang/cosmos/x/vbank/types/params.go +++ b/golang/cosmos/x/vbank/types/params.go @@ -6,14 +6,18 @@ import ( yaml "gopkg.in/yaml.v2" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) +const AllowAllMonitoringAccountsPattern = "*" + // Parameter keys var ( ParamStoreKeyRewardEpochDurationBlocks = []byte("reward_epoch_duration_blocks") ParamStoreKeyRewardSmoothingBlocks = []byte("reward_smoothing_blocks") ParamStoreKeyPerEpochRewardFraction = []byte("per_epoch_reward_fraction") + ParamStoreKeyAllowedMonitoringAccounts = []byte("allowed_monitoring_accounts") ) // ParamKeyTable returns the parameter key table. @@ -21,12 +25,14 @@ func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) } -// DefaultParams returns default distribution parameters +// DefaultParams returns default parameters func DefaultParams() Params { + provisionAddress := authtypes.NewModuleAddress(ProvisionPoolName) return Params{ RewardEpochDurationBlocks: 0, RewardSmoothingBlocks: 1, PerEpochRewardFraction: sdk.OneDec(), + AllowedMonitoringAccounts: []string{provisionAddress.String()}, } } @@ -67,12 +73,27 @@ func (p Params) RewardRate(pool sdk.Coins, blocks int64) sdk.Coins { return sdk.NewCoins(coins...) } +// IsAllowedMonitoringAccount checks to see if a given address is allowed to monitor its balance. +func (p Params) IsAllowedMonitoringAccount(addr string) bool { + for _, pat := range p.AllowedMonitoringAccounts { + switch pat { + case AllowAllMonitoringAccountsPattern, addr: + // Got an AllowAll pattern or an exact match. + return true + } + } + + // No match found. + return false +} + // ParamSetPairs returns the parameter set pairs. func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{ paramtypes.NewParamSetPair(ParamStoreKeyRewardEpochDurationBlocks, &p.RewardEpochDurationBlocks, validateRewardEpochDurationBlocks), paramtypes.NewParamSetPair(ParamStoreKeyRewardSmoothingBlocks, &p.RewardSmoothingBlocks, validateRewardSmoothingBlocks), paramtypes.NewParamSetPair(ParamStoreKeyPerEpochRewardFraction, &p.PerEpochRewardFraction, validatePerEpochRewardFraction), + paramtypes.NewParamSetPair(ParamStoreKeyAllowedMonitoringAccounts, &p.AllowedMonitoringAccounts, validateAllowedMonitoringAccounts), } } @@ -84,7 +105,12 @@ func (p Params) ValidateBasic() error { if err := validatePerEpochRewardFraction(p.PerEpochRewardFraction); err != nil { return err } - + if err := validateRewardSmoothingBlocks(p.RewardSmoothingBlocks); err != nil { + return err + } + if err := validateAllowedMonitoringAccounts(p.AllowedMonitoringAccounts); err != nil { + return err + } return nil } @@ -130,3 +156,18 @@ func validatePerEpochRewardFraction(i interface{}) error { return nil } + +func validateAllowedMonitoringAccounts(i interface{}) error { + v, ok := i.([]string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + for a, acc := range v { + if acc == "" { + return fmt.Errorf("allowed monitoring accounts element[%d] cannot be empty", a) + } + } + + return nil +} diff --git a/golang/cosmos/x/vbank/types/vbank.pb.go b/golang/cosmos/x/vbank/types/vbank.pb.go index 1b1e8b5d947..7c690f3dd8f 100644 --- a/golang/cosmos/x/vbank/types/vbank.pb.go +++ b/golang/cosmos/x/vbank/types/vbank.pb.go @@ -39,6 +39,10 @@ type Params struct { // an epoch's rewards. If zero, use the same value as // reward_epoch_duration_blocks. RewardSmoothingBlocks int64 `protobuf:"varint,3,opt,name=reward_smoothing_blocks,json=rewardSmoothingBlocks,proto3" json:"reward_smoothing_blocks,omitempty" yaml:"reward_smoothing_blocks"` + // allowed_monitoring_accounts is an array of account addresses that can be + // monitored for sends and receives. An element of `"*"` will permit any + // address. + AllowedMonitoringAccounts []string `protobuf:"bytes,4,rep,name=allowed_monitoring_accounts,json=allowedMonitoringAccounts,proto3" json:"allowed_monitoring_accounts,omitempty" yaml:"allowed_monitoring_accounts"` } func (m *Params) Reset() { *m = Params{} } @@ -87,6 +91,13 @@ func (m *Params) GetRewardSmoothingBlocks() int64 { return 0 } +func (m *Params) GetAllowedMonitoringAccounts() []string { + if m != nil { + return m.AllowedMonitoringAccounts + } + return nil +} + // The current state of the module. type State struct { // rewardPool is the current balance of rewards in the module account. @@ -170,42 +181,45 @@ func init() { func init() { proto.RegisterFile("agoric/vbank/vbank.proto", fileDescriptor_5e89b3b9e5e671b4) } var fileDescriptor_5e89b3b9e5e671b4 = []byte{ - // 550 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0x73, 0x49, 0xa8, 0xe0, 0x5a, 0x06, 0x4c, 0x01, 0x27, 0x20, 0x3b, 0x32, 0x02, 0xc2, - 0x80, 0xad, 0xc2, 0x82, 0x22, 0x31, 0xd4, 0x84, 0x8e, 0xa8, 0x72, 0x06, 0xa4, 0x2e, 0xd1, 0xd9, - 0x39, 0x1c, 0x2b, 0xb6, 0x9f, 0xb9, 0xbb, 0x14, 0xba, 0xf2, 0x09, 0x10, 0x13, 0x6c, 0x9d, 0xf9, - 0x24, 0x1d, 0x3b, 0x22, 0x24, 0x0c, 0x4a, 0x16, 0x16, 0x96, 0x7c, 0x02, 0xe4, 0xbb, 0x8b, 0x9a, - 0x20, 0x54, 0x60, 0x49, 0x7c, 0xfe, 0xbd, 0xf7, 0xfc, 0x7f, 0xff, 0x77, 0x0f, 0x9b, 0x24, 0x06, - 0x96, 0x44, 0xde, 0x61, 0x48, 0xf2, 0x89, 0xfa, 0x75, 0x0b, 0x06, 0x02, 0x8c, 0x2d, 0x45, 0x5c, - 0xf9, 0xae, 0xbd, 0x1d, 0x43, 0x0c, 0x12, 0x78, 0xd5, 0x93, 0x8a, 0x69, 0x5b, 0x11, 0xf0, 0x0c, - 0xb8, 0x17, 0x12, 0x4e, 0xbd, 0xc3, 0x9d, 0x90, 0x0a, 0xb2, 0xe3, 0x45, 0x90, 0xe4, 0x8a, 0x3b, - 0x3f, 0xeb, 0x78, 0x63, 0x9f, 0x30, 0x92, 0x71, 0x63, 0x8c, 0x6f, 0x31, 0xfa, 0x9a, 0xb0, 0xd1, - 0x90, 0x16, 0x10, 0x8d, 0x87, 0xa3, 0x29, 0x23, 0x22, 0x81, 0x7c, 0x18, 0xa6, 0x10, 0x4d, 0xb8, - 0x89, 0x3a, 0xa8, 0xdb, 0xf0, 0xef, 0x2d, 0x4a, 0xfb, 0xf6, 0x11, 0xc9, 0xd2, 0x9e, 0x73, 0x5e, - 0xb4, 0x13, 0xb4, 0x14, 0x7e, 0x56, 0xd1, 0xbe, 0x86, 0xbe, 0x64, 0xc6, 0x7b, 0x84, 0x5b, 0x05, - 0x65, 0x3a, 0x53, 0x97, 0x79, 0xc9, 0x48, 0x54, 0xc5, 0x98, 0xf5, 0x0e, 0xea, 0x5e, 0xf2, 0x5f, - 0x9c, 0x94, 0x76, 0xed, 0x4b, 0x69, 0xdf, 0x8d, 0x13, 0x31, 0x9e, 0x86, 0x6e, 0x04, 0x99, 0xa7, - 0x7b, 0x51, 0x7f, 0x0f, 0xf8, 0x68, 0xe2, 0x89, 0xa3, 0x82, 0x72, 0xb7, 0x4f, 0xa3, 0x45, 0x69, - 0xdf, 0x51, 0xaa, 0x46, 0x09, 0x8f, 0x18, 0x15, 0xf4, 0xcf, 0xd5, 0x9d, 0xe0, 0x7a, 0x41, 0x99, - 0x14, 0x15, 0x48, 0xb2, 0xa7, 0x81, 0x71, 0x80, 0x6f, 0xe8, 0x58, 0x9e, 0x01, 0x88, 0x71, 0x92, - 0xc7, 0xcb, 0xce, 0x1b, 0xb2, 0x73, 0x67, 0x51, 0xda, 0xd6, 0x5a, 0xe7, 0xbf, 0x07, 0x3a, 0xc1, - 0x35, 0x45, 0x06, 0x4b, 0xa0, 0x1a, 0xee, 0x5d, 0xfc, 0x70, 0x6c, 0xd7, 0x7e, 0x1c, 0xdb, 0xc8, - 0xf9, 0xda, 0xc0, 0x17, 0x06, 0x82, 0x08, 0x6a, 0xbc, 0x45, 0x78, 0x53, 0xd7, 0x29, 0x00, 0x52, - 0x13, 0x75, 0x1a, 0xdd, 0xcd, 0x87, 0x2d, 0x57, 0x75, 0xe7, 0x56, 0x03, 0x73, 0xf5, 0xc0, 0xdc, - 0xa7, 0x90, 0xe4, 0xfe, 0x5e, 0xe5, 0xc8, 0xa2, 0xb4, 0x8d, 0x35, 0x0d, 0x55, 0xae, 0xf3, 0xe9, - 0x9b, 0xdd, 0xfd, 0x07, 0x9f, 0xaa, 0x32, 0x3c, 0xc0, 0x2a, 0x73, 0x1f, 0x20, 0x35, 0x3e, 0x22, - 0x7c, 0x55, 0x17, 0x92, 0x2d, 0x0c, 0x49, 0x06, 0xd3, 0x5c, 0x98, 0xf5, 0xbf, 0x89, 0x79, 0xae, - 0xc5, 0xb4, 0xd7, 0xc4, 0xac, 0xd6, 0xf8, 0x3f, 0x51, 0x57, 0x54, 0x05, 0xe9, 0xd7, 0xae, 0xcc, - 0x37, 0x9e, 0xe0, 0xcb, 0x29, 0xe1, 0x62, 0xc8, 0xe9, 0xab, 0x29, 0xcd, 0x23, 0x2a, 0xc7, 0xd0, - 0xf4, 0xcd, 0x45, 0x69, 0x6f, 0xab, 0xaf, 0xae, 0x61, 0x27, 0xd8, 0xaa, 0xce, 0x03, 0x7d, 0x34, - 0x72, 0x6c, 0x49, 0xae, 0xa5, 0x8d, 0x12, 0x2e, 0x58, 0x12, 0x4e, 0xcf, 0xee, 0xa8, 0xd9, 0x94, - 0x63, 0xbd, 0x7f, 0x76, 0x75, 0xce, 0x8f, 0x77, 0x82, 0x9b, 0x55, 0x80, 0xba, 0x36, 0xfd, 0x15, - 0x2c, 0x45, 0xf7, 0x9a, 0xd5, 0x7c, 0xfd, 0xe0, 0x64, 0x66, 0xa1, 0xd3, 0x99, 0x85, 0xbe, 0xcf, - 0x2c, 0xf4, 0x6e, 0x6e, 0xd5, 0x4e, 0xe7, 0x56, 0xed, 0xf3, 0xdc, 0xaa, 0x1d, 0x3c, 0x5e, 0xf1, - 0x62, 0x57, 0xad, 0xb4, 0xda, 0x5f, 0xe9, 0x45, 0x0c, 0x29, 0xc9, 0xe3, 0xa5, 0x49, 0x6f, 0xf4, - 0xb6, 0x4b, 0x87, 0xc2, 0x0d, 0xb9, 0xaa, 0x8f, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x95, - 0x56, 0xb1, 0x0a, 0x04, 0x00, 0x00, + // 597 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0x3f, 0x6f, 0xd3, 0x4e, + 0x18, 0xc7, 0xe3, 0x26, 0xbf, 0xea, 0xd7, 0x6b, 0x19, 0x30, 0x05, 0x9c, 0x16, 0xd9, 0xd1, 0x21, + 0x4a, 0x18, 0xb0, 0x55, 0x58, 0x50, 0x25, 0x86, 0x9a, 0xd2, 0x0d, 0x54, 0xb9, 0x03, 0x52, 0x97, + 0xe8, 0x7c, 0xb9, 0x3a, 0x56, 0x6d, 0x3f, 0xe1, 0xee, 0xd2, 0xd2, 0x95, 0x57, 0x80, 0x98, 0x60, + 0xeb, 0xcc, 0x2b, 0xe9, 0xd8, 0x05, 0x09, 0x21, 0x61, 0x50, 0xbb, 0x30, 0xe7, 0x15, 0xa0, 0xfb, + 0x53, 0xda, 0x20, 0x14, 0x60, 0x49, 0xe2, 0x7c, 0xbe, 0xcf, 0x93, 0xef, 0xf3, 0x27, 0x0f, 0xf2, + 0x48, 0x06, 0x3c, 0xa7, 0xd1, 0x7e, 0x4a, 0xaa, 0x3d, 0xf3, 0x1a, 0x0e, 0x39, 0x48, 0x70, 0x17, + 0x0c, 0x09, 0xf5, 0x77, 0x4b, 0x8b, 0x19, 0x64, 0xa0, 0x41, 0xa4, 0x3e, 0x19, 0xcd, 0x92, 0x4f, + 0x41, 0x94, 0x20, 0xa2, 0x94, 0x08, 0x16, 0xed, 0xaf, 0xa6, 0x4c, 0x92, 0xd5, 0x88, 0x42, 0x5e, + 0x19, 0x8e, 0x3f, 0x36, 0xd1, 0xec, 0x16, 0xe1, 0xa4, 0x14, 0xee, 0x00, 0xdd, 0xe2, 0xec, 0x80, + 0xf0, 0x7e, 0x8f, 0x0d, 0x81, 0x0e, 0x7a, 0xfd, 0x11, 0x27, 0x32, 0x87, 0xaa, 0x97, 0x16, 0x40, + 0xf7, 0x84, 0xe7, 0x74, 0x9c, 0x6e, 0x33, 0xbe, 0x3b, 0xae, 0x83, 0xdb, 0x87, 0xa4, 0x2c, 0xd6, + 0xf0, 0x34, 0x35, 0x4e, 0xda, 0x06, 0x3f, 0x55, 0x74, 0xc3, 0xc2, 0x58, 0x33, 0xf7, 0xad, 0x83, + 0xda, 0x43, 0xc6, 0x6d, 0xa4, 0x4d, 0xb3, 0xcb, 0x09, 0x55, 0x1a, 0x6f, 0xa6, 0xe3, 0x74, 0xe7, + 0xe2, 0x17, 0xc7, 0x75, 0xd0, 0xf8, 0x5c, 0x07, 0x2b, 0x59, 0x2e, 0x07, 0xa3, 0x34, 0xa4, 0x50, + 0x46, 0xb6, 0x16, 0xf3, 0x76, 0x5f, 0xf4, 0xf7, 0x22, 0x79, 0x38, 0x64, 0x22, 0xdc, 0x60, 0x74, + 0x5c, 0x07, 0x77, 0x8c, 0xab, 0x7e, 0x2e, 0x28, 0x67, 0x92, 0xfd, 0x3e, 0x3b, 0x4e, 0x6e, 0x0c, + 0x19, 0xd7, 0xa6, 0x12, 0x4d, 0x36, 0x2d, 0x70, 0x77, 0xd0, 0x4d, 0xab, 0x15, 0x25, 0x80, 0x1c, + 0xe4, 0x55, 0x76, 0x5e, 0x79, 0x53, 0x57, 0x8e, 0xc7, 0x75, 0xe0, 0x4f, 0x54, 0xfe, 0xab, 0x10, + 0x27, 0xd7, 0x0d, 0xd9, 0x3e, 0x07, 0xb6, 0xe0, 0x5d, 0xb4, 0x4c, 0x8a, 0x02, 0x0e, 0x58, 0xbf, + 0x57, 0x42, 0x95, 0x4b, 0xe0, 0x2a, 0x88, 0x50, 0x0a, 0xa3, 0x4a, 0x0a, 0xaf, 0xd5, 0x69, 0x76, + 0xe7, 0xe2, 0x95, 0x71, 0x1d, 0x60, 0x93, 0x7f, 0x8a, 0x18, 0x27, 0x6d, 0x4b, 0x9f, 0xfd, 0x84, + 0xeb, 0x96, 0xad, 0xfd, 0xff, 0xee, 0x28, 0x68, 0x7c, 0x3f, 0x0a, 0x1c, 0xfc, 0xa5, 0x89, 0xfe, + 0xdb, 0x96, 0x44, 0x32, 0xf7, 0xb5, 0x83, 0xe6, 0xad, 0xdf, 0x21, 0x40, 0xe1, 0x39, 0x9d, 0x66, + 0x77, 0xfe, 0x41, 0x3b, 0x34, 0x5d, 0x0c, 0xd5, 0x62, 0x84, 0x76, 0x31, 0xc2, 0x27, 0x90, 0x57, + 0xf1, 0xa6, 0xea, 0xfc, 0xb8, 0x0e, 0xdc, 0x89, 0x5a, 0x55, 0x2c, 0xfe, 0xf0, 0x35, 0xe8, 0xfe, + 0xc5, 0x3c, 0x54, 0x1a, 0x91, 0x20, 0x13, 0xb9, 0x05, 0x50, 0xb8, 0xef, 0x1d, 0x74, 0xcd, 0x26, + 0xd2, 0xad, 0xea, 0x91, 0x52, 0x39, 0xf6, 0x66, 0xfe, 0x64, 0xe6, 0xb9, 0x35, 0xb3, 0x34, 0x61, + 0xe6, 0x72, 0x8e, 0x7f, 0x33, 0x75, 0xd5, 0x64, 0xd0, 0x73, 0x59, 0xd7, 0xf1, 0xee, 0x63, 0x74, + 0xa5, 0x20, 0x42, 0xf6, 0x04, 0x7b, 0x39, 0x62, 0x15, 0x65, 0x7a, 0xdc, 0xad, 0xd8, 0x1b, 0xd7, + 0xc1, 0xa2, 0xf9, 0xd5, 0x09, 0x8c, 0x93, 0x05, 0xf5, 0xbc, 0x6d, 0x1f, 0xdd, 0x0a, 0xf9, 0x9a, + 0x5b, 0x6b, 0xfd, 0x5c, 0x48, 0x9e, 0xa7, 0xa3, 0x8b, 0xff, 0x82, 0xd7, 0xd2, 0xeb, 0x73, 0xef, + 0x62, 0x45, 0xa7, 0xeb, 0x71, 0xb2, 0xac, 0x04, 0x66, 0x3d, 0x37, 0x2e, 0x61, 0x6d, 0x7a, 0xad, + 0xa5, 0xe6, 0x1b, 0x27, 0xc7, 0xa7, 0xbe, 0x73, 0x72, 0xea, 0x3b, 0xdf, 0x4e, 0x7d, 0xe7, 0xcd, + 0x99, 0xdf, 0x38, 0x39, 0xf3, 0x1b, 0x9f, 0xce, 0xfc, 0xc6, 0xce, 0xa3, 0x4b, 0xbd, 0x58, 0x37, + 0xa7, 0xc3, 0xdc, 0x09, 0xdd, 0x8b, 0x0c, 0x0a, 0x52, 0x65, 0xe7, 0x4d, 0x7a, 0x65, 0xaf, 0x8a, + 0xee, 0x50, 0x3a, 0xab, 0x4f, 0xc2, 0xc3, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x60, 0x18, 0x80, + 0x8f, 0x72, 0x04, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -236,6 +250,14 @@ func (this *Params) Equal(that interface{}) bool { if this.RewardSmoothingBlocks != that1.RewardSmoothingBlocks { return false } + if len(this.AllowedMonitoringAccounts) != len(that1.AllowedMonitoringAccounts) { + return false + } + for i := range this.AllowedMonitoringAccounts { + if this.AllowedMonitoringAccounts[i] != that1.AllowedMonitoringAccounts[i] { + return false + } + } return true } func (this *State) Equal(that interface{}) bool { @@ -301,6 +323,15 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.AllowedMonitoringAccounts) > 0 { + for iNdEx := len(m.AllowedMonitoringAccounts) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.AllowedMonitoringAccounts[iNdEx]) + copy(dAtA[i:], m.AllowedMonitoringAccounts[iNdEx]) + i = encodeVarintVbank(dAtA, i, uint64(len(m.AllowedMonitoringAccounts[iNdEx]))) + i-- + dAtA[i] = 0x22 + } + } if m.RewardSmoothingBlocks != 0 { i = encodeVarintVbank(dAtA, i, uint64(m.RewardSmoothingBlocks)) i-- @@ -410,6 +441,12 @@ func (m *Params) Size() (n int) { if m.RewardSmoothingBlocks != 0 { n += 1 + sovVbank(uint64(m.RewardSmoothingBlocks)) } + if len(m.AllowedMonitoringAccounts) > 0 { + for _, s := range m.AllowedMonitoringAccounts { + l = len(s) + n += 1 + l + sovVbank(uint64(l)) + } + } return n } @@ -547,6 +584,38 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowedMonitoringAccounts", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowVbank + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthVbank + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthVbank + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AllowedMonitoringAccounts = append(m.AllowedMonitoringAccounts, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipVbank(dAtA[iNdEx:]) diff --git a/golang/cosmos/x/vbank/vbank_test.go b/golang/cosmos/x/vbank/vbank_test.go index a308eada914..9a64b016e45 100644 --- a/golang/cosmos/x/vbank/vbank_test.go +++ b/golang/cosmos/x/vbank/vbank_test.go @@ -439,6 +439,7 @@ func Test_Receive_GiveToRewardDistributor(t *testing.T) { params := types.DefaultParams() params.RewardEpochDurationBlocks = 0 params.RewardSmoothingBlocks = tt.duration + params.AllowedMonitoringAccounts = []string{"*"} keeper.SetParams(ctx, params) keeper.SetState(ctx, types.State{RewardPool: tt.rewardPool}) @@ -524,7 +525,7 @@ func Test_EndBlock_Events(t *testing.T) { } keeper, ctx := makeTestKit(acct, bank) // Turn off rewards. - keeper.SetParams(ctx, types.Params{PerEpochRewardFraction: sdk.ZeroDec()}) + keeper.SetParams(ctx, types.Params{PerEpochRewardFraction: sdk.ZeroDec(), AllowedMonitoringAccounts: []string{"*"}}) msgsSent := []string{} keeper.PushAction = func(ctx sdk.Context, action vm.Action) error { bz, err := json.Marshal(action) @@ -804,15 +805,19 @@ func Test_Module_Account(t *testing.T) { } modAddr := sdk.MustAccAddressFromBech32(moduleBech32) - if !keeper.IsModuleAccount(ctx, modAddr) { - t.Errorf("got IsModuleAccount modAddr = false, want true") + if keeper.IsAllowedMonitoringAccount(ctx, modAddr) { + t.Errorf("got IsAllowedMonitoringAccount modAddr = true, want false") + } + provisionPool := authtypes.NewModuleAddress("vbank/provision") + if !keeper.IsAllowedMonitoringAccount(ctx, provisionPool) { + t.Errorf("got IsAllowedMonitoringAccount provisionPool = false, want true") } notModAddr := sdk.MustAccAddressFromBech32(addr1) - if keeper.IsModuleAccount(ctx, notModAddr) { - t.Errorf("got IsModuleAccount notModAddr = true, want false") + if keeper.IsAllowedMonitoringAccount(ctx, notModAddr) { + t.Errorf("got IsAllowedMonitoringAccount notModAddr = true, want false") } missingAddr := sdk.MustAccAddressFromBech32(addr2) - if keeper.IsModuleAccount(ctx, missingAddr) { - t.Errorf("got IsModuleAccount missingAddr = false, want true") + if keeper.IsAllowedMonitoringAccount(ctx, missingAddr) { + t.Errorf("got IsAllowedMonitoringAccount missingAddr = false, want true") } } diff --git a/packages/cosmic-proto/proto/agoric/vbank/vbank.proto b/packages/cosmic-proto/proto/agoric/vbank/vbank.proto index 7884abecc9a..4b47cf71c70 100644 --- a/packages/cosmic-proto/proto/agoric/vbank/vbank.proto +++ b/packages/cosmic-proto/proto/agoric/vbank/vbank.proto @@ -33,6 +33,13 @@ message Params { int64 reward_smoothing_blocks = 3 [ (gogoproto.moretags) = "yaml:\"reward_smoothing_blocks\"" ]; + + // allowed_monitoring_accounts is an array of account addresses that can be + // monitored for sends and receives. An element of `"*"` will permit any + // address. + repeated string allowed_monitoring_accounts = 4 [ + (gogoproto.moretags) = "yaml:\"allowed_monitoring_accounts\"" + ]; } // The current state of the module. diff --git a/packages/cosmic-proto/src/codegen/agoric/vbank/vbank.ts b/packages/cosmic-proto/src/codegen/agoric/vbank/vbank.ts index 96d8b2bcd45..79cea356dd9 100644 --- a/packages/cosmic-proto/src/codegen/agoric/vbank/vbank.ts +++ b/packages/cosmic-proto/src/codegen/agoric/vbank/vbank.ts @@ -23,6 +23,12 @@ export interface Params { * reward_epoch_duration_blocks. */ rewardSmoothingBlocks: bigint; + /** + * allowed_monitoring_accounts is an array of account addresses that can be + * monitored for sends and receives. An element of `"*"` will permit any + * address. + */ + allowedMonitoringAccounts: string[]; } export interface ParamsProtoMsg { typeUrl: '/agoric.vbank.Params'; @@ -33,6 +39,7 @@ export interface ParamsSDKType { reward_epoch_duration_blocks: bigint; per_epoch_reward_fraction: string; reward_smoothing_blocks: bigint; + allowed_monitoring_accounts: string[]; } /** The current state of the module. */ export interface State { @@ -67,6 +74,7 @@ function createBaseParams(): Params { rewardEpochDurationBlocks: BigInt(0), perEpochRewardFraction: '', rewardSmoothingBlocks: BigInt(0), + allowedMonitoringAccounts: [], }; } export const Params = { @@ -88,6 +96,9 @@ export const Params = { if (message.rewardSmoothingBlocks !== BigInt(0)) { writer.uint32(24).int64(message.rewardSmoothingBlocks); } + for (const v of message.allowedMonitoringAccounts) { + writer.uint32(34).string(v!); + } return writer; }, decode(input: BinaryReader | Uint8Array, length?: number): Params { @@ -110,6 +121,9 @@ export const Params = { case 3: message.rewardSmoothingBlocks = reader.int64(); break; + case 4: + message.allowedMonitoringAccounts.push(reader.string()); + break; default: reader.skipType(tag & 7); break; @@ -128,6 +142,11 @@ export const Params = { rewardSmoothingBlocks: isSet(object.rewardSmoothingBlocks) ? BigInt(object.rewardSmoothingBlocks.toString()) : BigInt(0), + allowedMonitoringAccounts: Array.isArray( + object?.allowedMonitoringAccounts, + ) + ? object.allowedMonitoringAccounts.map((e: any) => String(e)) + : [], }; }, toJSON(message: Params): JsonSafe { @@ -142,6 +161,13 @@ export const Params = { (obj.rewardSmoothingBlocks = ( message.rewardSmoothingBlocks || BigInt(0) ).toString()); + if (message.allowedMonitoringAccounts) { + obj.allowedMonitoringAccounts = message.allowedMonitoringAccounts.map( + e => e, + ); + } else { + obj.allowedMonitoringAccounts = []; + } return obj; }, fromPartial(object: Partial): Params { @@ -157,6 +183,8 @@ export const Params = { object.rewardSmoothingBlocks !== null ? BigInt(object.rewardSmoothingBlocks.toString()) : BigInt(0); + message.allowedMonitoringAccounts = + object.allowedMonitoringAccounts?.map(e => e) || []; return message; }, fromProtoMsg(message: ParamsProtoMsg): Params {