Enable/disable coin transfers by denom (#6527)

* initial implementation of per denom sendenabled

* Fix for accidentally removed keyword

* Validate individual param in param array

* Lint fix

* Refactor bank params to use protobuf
Modified SendEnabled property to be part of generic Params object
Updated genesis functions to use default params structure

* Refactor simulation genesis for clarity

* update changelog for bank sendenable per denom

* fix NoOpMsg type in multisend test

* Add a coin denom send check utility function

* Additional godoc comments and clarification

* Add default send enabled parameter to bank.
Remove empty denom capability from SendEnabled parameters
Update simulation to exercise both configuration options independently

* Minor suggested improvements.

* simulation fix

* bank proto sendenabled package name removed

* Remove extra gogo proto yaml tags

* Params rename IsSendEnabled to SendEnabledDenom

* Refactor to SendEnabledCoin(s)

* update slashing test to use bank params

* Clean up change log entry for feature.

Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Alessio Treglia <alessio@tendermint.com>
Co-authored-by: Alexander Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
Ira Miller 2020-07-08 11:43:08 -06:00 committed by GitHub
parent a459b785d6
commit 589c1a531e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 939 additions and 101 deletions

View File

@ -203,6 +203,9 @@ invalid or incomplete requests.
### State Machine Breaking
* (x/bank) [\#6283](https://github.com/cosmos/cosmos-sdk/pull/6283) Create account if recipient does not exist on handing `MsgMultiSend`.
* (x/bank) [\#6518](https://github.com/cosmos/cosmos-sdk/pull/6518) Support for global and per-denomination send enabled flags.
* Existing send_enabled global flag has been moved into a Params structure as `default_send_enabled`.
* An array of: `{denom: string, enabled: bool}` is added to bank Params to support per-denomination override of global default value.
* (x/staking) [\#6061](https://github.com/cosmos/cosmos-sdk/pull/6061) Allow a validator to immediately unjail when no signing info is present due to
falling below their minimum self-delegation and never having been bonded. The validator may immediately unjail once they've met their minimum self-delegation.
* (x/supply) [\#6010](https://github.com/cosmos/cosmos-sdk/pull/6010) Removed the `x/supply` module by merging the existing types and APIs into the `x/bank` module.

View File

@ -7,6 +7,25 @@ import "cosmos/cosmos.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/bank/types";
// Params defines the set of bank parameters.
message Params {
option (gogoproto.goproto_stringer) = false;
repeated SendEnabled send_enabled = 1[
(gogoproto.moretags) = "yaml:\"send_enabled,omitempty\""
];
bool default_send_enabled = 2[
(gogoproto.moretags) = "yaml:\"default_send_enabled,omitempty\""
];
}
// Send enabled configuration properties for each denomination
message SendEnabled {
option (gogoproto.equal) = true;
option (gogoproto.goproto_stringer) = false;
string denom = 1;
bool enabled = 2;
}
// MsgSend - high level transaction of the coin module
message MsgSend {
option (gogoproto.equal) = true;

View File

@ -118,7 +118,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet *tmtypes.ValidatorSet, genAccs
}
// update total supply
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().SendEnabled, balances, totalSupply)
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply)
genesisState[banktypes.ModuleName] = app.Codec().MustMarshalJSON(bankGenesis)
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)
@ -157,7 +157,7 @@ func SetupWithGenesisAccounts(genAccs []authtypes.GenesisAccount, balances ...ba
totalSupply = totalSupply.Add(b.Coins...)
}
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().SendEnabled, balances, totalSupply)
bankGenesis := banktypes.NewGenesisState(banktypes.DefaultGenesisState().Params, balances, totalSupply)
genesisState[banktypes.ModuleName] = app.Codec().MustMarshalJSON(bankGenesis)
stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState)

View File

@ -10,7 +10,7 @@ import (
// InitGenesis initializes the bank module's state from a given genesis state.
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, genState types.GenesisState) {
keeper.SetSendEnabled(ctx, genState.SendEnabled)
keeper.SetParams(ctx, genState.Params)
var totalSupply sdk.Coins
@ -57,11 +57,14 @@ func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) types.GenesisState {
})
}
return types.NewGenesisState(keeper.GetSendEnabled(ctx), balances, keeper.GetSupply(ctx).GetTotal())
return types.NewGenesisState(keeper.GetParams(ctx), balances, keeper.GetSupply(ctx).GetTotal())
}
// ValidateGenesis performs basic validation of supply genesis data returning an
// error for any failed validation criteria.
func ValidateGenesis(data types.GenesisState) error {
if err := data.Params.Validate(); err != nil {
return err
}
return types.NewSupply(data.Supply).ValidateBasic()
}

View File

@ -30,8 +30,8 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
// Handle MsgSend.
func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg *types.MsgSend) (*sdk.Result, error) {
if !k.GetSendEnabled(ctx) {
return nil, types.ErrSendDisabled
if err := k.SendEnabledCoins(ctx, msg.Amount...); err != nil {
return nil, err
}
if k.BlockedAddr(msg.ToAddress) {
@ -66,8 +66,10 @@ func handleMsgSend(ctx sdk.Context, k keeper.Keeper, msg *types.MsgSend) (*sdk.R
// Handle MsgMultiSend.
func handleMsgMultiSend(ctx sdk.Context, k keeper.Keeper, msg *types.MsgMultiSend) (*sdk.Result, error) {
// NOTE: totalIn == totalOut should already have been checked
if !k.GetSendEnabled(ctx) {
return nil, types.ErrSendDisabled
for _, in := range msg.Inputs {
if err := k.SendEnabledCoins(ctx, in.Coins...); err != nil {
return nil, err
}
}
for _, out := range msg.Outputs {

View File

@ -69,7 +69,7 @@ func (suite *IntegrationTestSuite) SetupTest() {
ctx := app.BaseApp.NewContext(false, abci.Header{})
app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
app.BankKeeper.SetSendEnabled(ctx, true)
app.BankKeeper.SetParams(ctx, types.DefaultParams())
suite.app = app
suite.ctx = ctx
@ -454,9 +454,45 @@ func (suite *IntegrationTestSuite) TestBalance() {
func (suite *IntegrationTestSuite) TestSendEnabled() {
app, ctx := suite.app, suite.ctx
enabled := false
app.BankKeeper.SetSendEnabled(ctx, enabled)
suite.Require().Equal(enabled, app.BankKeeper.GetSendEnabled(ctx))
enabled := true
params := types.DefaultParams()
suite.Require().Equal(enabled, params.DefaultSendEnabled)
app.BankKeeper.SetParams(ctx, params)
bondCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())
fooCoin := sdk.NewCoin("foocoin", sdk.OneInt())
barCoin := sdk.NewCoin("barcoin", sdk.OneInt())
// assert with default (all denom) send enabled both Bar and Bond Denom are enabled
suite.Require().Equal(enabled, app.BankKeeper.SendEnabledCoin(ctx, barCoin))
suite.Require().Equal(enabled, app.BankKeeper.SendEnabledCoin(ctx, bondCoin))
// Both coins should be send enabled.
err := app.BankKeeper.SendEnabledCoins(ctx, fooCoin, bondCoin)
suite.Require().NoError(err)
// Set default send_enabled to !enabled, add a foodenom that overrides default as enabled
params.DefaultSendEnabled = !enabled
params = params.SetSendEnabledParam(fooCoin.Denom, enabled)
app.BankKeeper.SetParams(ctx, params)
// Expect our specific override to be enabled, others to be !enabled.
suite.Require().Equal(enabled, app.BankKeeper.SendEnabledCoin(ctx, fooCoin))
suite.Require().Equal(!enabled, app.BankKeeper.SendEnabledCoin(ctx, barCoin))
suite.Require().Equal(!enabled, app.BankKeeper.SendEnabledCoin(ctx, bondCoin))
// Foo coin should be send enabled.
err = app.BankKeeper.SendEnabledCoins(ctx, fooCoin)
suite.Require().NoError(err)
// Expect an error when one coin is not send enabled.
err = app.BankKeeper.SendEnabledCoins(ctx, fooCoin, bondCoin)
suite.Require().Error(err)
// Expect an error when all coins are not send enabled.
err = app.BankKeeper.SendEnabledCoins(ctx, bondCoin, barCoin)
suite.Require().Error(err)
}
func (suite *IntegrationTestSuite) TestHasBalance() {
@ -531,7 +567,7 @@ func (suite *IntegrationTestSuite) TestMsgSendEvents() {
func (suite *IntegrationTestSuite) TestMsgMultiSendEvents() {
app, ctx := suite.app, suite.ctx
app.BankKeeper.SetSendEnabled(ctx, true)
app.BankKeeper.SetParams(ctx, types.DefaultParams())
addr := sdk.AccAddress([]byte("addr1"))
addr2 := sdk.AccAddress([]byte("addr2"))

View File

@ -24,8 +24,11 @@ type SendKeeper interface {
SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance sdk.Coin) error
SetBalances(ctx sdk.Context, addr sdk.AccAddress, balances sdk.Coins) error
GetSendEnabled(ctx sdk.Context) bool
SetSendEnabled(ctx sdk.Context, enabled bool)
GetParams(ctx sdk.Context) types.Params
SetParams(ctx sdk.Context, params types.Params)
SendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool
SendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
BlockedAddr(addr sdk.AccAddress) bool
}
@ -60,6 +63,17 @@ func NewBaseSendKeeper(
}
}
// GetParams returns the total set of bank parameters.
func (k BaseSendKeeper) GetParams(ctx sdk.Context) (params types.Params) {
k.paramSpace.GetParamSet(ctx, &params)
return params
}
// SetParams sets the total set of bank parameters.
func (k BaseSendKeeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSpace.SetParamSet(ctx, &params)
}
// InputOutputCoins performs multi-send functionality. It accepts a series of
// inputs that correspond to a series of outputs. It returns an error if the
// inputs and outputs don't lineup or if any single transfer of tokens fails.
@ -256,16 +270,21 @@ func (k BaseSendKeeper) SetBalance(ctx sdk.Context, addr sdk.AccAddress, balance
return nil
}
// GetSendEnabled returns the current SendEnabled
func (k BaseSendKeeper) GetSendEnabled(ctx sdk.Context) bool {
var enabled bool
k.paramSpace.Get(ctx, types.ParamStoreKeySendEnabled, &enabled)
return enabled
// SendEnabledCoins checks the coins provide and returns an ErrSendDisabled if
// any of the coins are not configured for sending. Returns nil if sending is enabled
// for all provided coin
func (k BaseSendKeeper) SendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error {
for _, coin := range coins {
if !k.SendEnabledCoin(ctx, coin) {
return sdkerrors.Wrapf(types.ErrSendDisabled, "%s transfers are currently disabled", coin.Denom)
}
}
return nil
}
// SetSendEnabled sets the send enabled
func (k BaseSendKeeper) SetSendEnabled(ctx sdk.Context, enabled bool) {
k.paramSpace.Set(ctx, types.ParamStoreKeySendEnabled, &enabled)
// SendEnabledCoin returns the current SendEnabled status of the provided coin's denom
func (k BaseSendKeeper) SendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool {
return k.GetParams(ctx).SendEnabledDenom(coin.Denom)
}
// BlockedAddr checks if a given address is restricted from

View File

@ -3,21 +3,36 @@ package simulation
// DONTCOVER
import (
"fmt"
"math/rand"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
// Simulation parameter constants
const (
SendEnabled = "send_enabled"
)
// RandomGenesisDefaultSendParam computes randomized allow all send transfers param for the bank module
func RandomGenesisDefaultSendParam(r *rand.Rand) bool {
// 90% chance of transfers being enable or P(a) = 0.9 for success
return r.Int63n(101) <= 90
}
// GenSendEnabled randomized SendEnabled
func GenSendEnabled(r *rand.Rand) bool {
return r.Int63n(101) <= 95 // 95% chance of transfers being enabled
// RandomGenesisSendParams randomized Parameters for the bank module
func RandomGenesisSendParams(r *rand.Rand) types.SendEnabledParams {
params := types.DefaultParams()
// 90% chance of transfers being DefaultSendEnabled=true or P(a) = 0.9 for success
// 50% of the time add an additional denom specific record (P(b) = 0.475 = 0.5 * 0.95)
if r.Int63n(101) <= 50 {
// set send enabled 95% of the time
bondEnabled := r.Int63n(101) <= 95
params = params.SetSendEnabledParam(
sdk.DefaultBondDenom,
bondEnabled)
}
// overall probability of enabled for bond denom is 94.75% (P(a)+P(b) - P(a)*P(b))
return params.SendEnabled
}
// RandomGenesisAccounts returns a slice of account balances. Each account has
@ -37,16 +52,31 @@ func RandomGenesisBalances(simState *module.SimulationState) []types.Balance {
// RandomizedGenState generates a random GenesisState for bank
func RandomizedGenState(simState *module.SimulationState) {
var sendEnabled bool
var sendEnabledParams types.SendEnabledParams
simState.AppParams.GetOrGenerate(
simState.Cdc, SendEnabled, &sendEnabled, simState.Rand,
func(r *rand.Rand) { sendEnabled = GenSendEnabled(r) },
simState.Cdc, string(types.KeySendEnabled), &sendEnabledParams, simState.Rand,
func(r *rand.Rand) { sendEnabledParams = RandomGenesisSendParams(r) },
)
var defaultSendEnabledParam bool
simState.AppParams.GetOrGenerate(
simState.Cdc, string(types.KeyDefaultSendEnabled), &defaultSendEnabledParam, simState.Rand,
func(r *rand.Rand) { defaultSendEnabledParam = RandomGenesisDefaultSendParam(r) },
)
numAccs := int64(len(simState.Accounts))
totalSupply := sdk.NewInt(simState.InitialStake * (numAccs + simState.NumBonded))
supply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, totalSupply))
bankGenesis := types.NewGenesisState(sendEnabled, RandomGenesisBalances(simState), supply)
bankGenesis := types.GenesisState{
Params: types.Params{
SendEnabled: sendEnabledParams,
DefaultSendEnabled: defaultSendEnabledParam,
},
Balances: RandomGenesisBalances(simState),
Supply: supply,
}
fmt.Printf("Selected randomly generated bank parameters:\n%s\n", codec.MustMarshalJSONIndent(simState.Cdc, bankGenesis.Params))
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(bankGenesis)
}

View File

@ -59,13 +59,13 @@ func SimulateMsgSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Operatio
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
if !bk.GetSendEnabled(ctx) {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgSend, "transfers are not enabled"), nil, nil
}
simAccount, toSimAcc, coins, skip := randomSendFields(r, ctx, accs, bk, ak)
// Check send_enabled status of each coin denom
if err := bk.SendEnabledCoins(ctx, coins...); err != nil {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgSend, err.Error()), nil, nil
}
if skip {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgSend, "skip all transfers"), nil, nil
}
@ -130,10 +130,6 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope
accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
if !bk.GetSendEnabled(ctx) {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, "transfers are not enabled"), nil, nil
}
// random number of inputs/outputs between [1, 3]
inputs := make([]types.Input, r.Intn(3)+1)
outputs := make([]types.Output, r.Intn(3)+1)
@ -169,6 +165,11 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope
totalSentCoins = totalSentCoins.Add(coins...)
}
// Check send_enabled status of each sent coin denom
if err := bk.SendEnabledCoins(ctx, totalSentCoins...); err != nil {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, err.Error()), nil, nil
}
for o := range outputs {
outAddr, _ := simtypes.RandomAcc(r, accs)

View File

@ -12,15 +12,18 @@ import (
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
const keySendEnabled = "sendenabled"
// ParamChanges defines the parameters that can be modified by param change proposals
// on the simulation
func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
return []simtypes.ParamChange{
simulation.NewSimParamChange(types.ModuleName, keySendEnabled,
simulation.NewSimParamChange(types.ModuleName, string(types.KeySendEnabled),
func(r *rand.Rand) string {
return fmt.Sprintf("%v", GenSendEnabled(r))
return fmt.Sprintf("%s", types.ModuleCdc.MustMarshalJSON(RandomGenesisSendParams(r)))
},
),
simulation.NewSimParamChange(types.ModuleName, string(types.KeyDefaultSendEnabled),
func(r *rand.Rand) string {
return fmt.Sprintf("%v", RandomGenesisDefaultSendParam(r))
},
),
}

View File

@ -6,7 +6,20 @@ order: 5
The bank module contains the following parameters:
| Key | Type | Example |
|-------------|------|---------|
| sendenabled | bool | true |
| Key | Type | Example |
|--------------------|---------------|------------------------------------|
| SendEnabled | []SendEnabled | [{denom: "stake", enabled: true }] |
| DefaultSendEnabled | bool | true |
## SendEnabled
The send enabled parameter is an array of SendEnabled entries mapping coin
denominations to their send_enabled status. Entries in this list take
precedence over the `DefaultSendEnabled` setting.
## DefaultSendEnabled
The default send enabled value controls send transfer capability for all
coin denominations unless specifically included in the array of `SendEnabled`
parameters.

View File

@ -27,6 +27,110 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// Params defines the set of bank parameters.
type Params struct {
SendEnabled []*SendEnabled `protobuf:"bytes,1,rep,name=send_enabled,json=sendEnabled,proto3" json:"send_enabled,omitempty" yaml:"send_enabled,omitempty"`
DefaultSendEnabled bool `protobuf:"varint,2,opt,name=default_send_enabled,json=defaultSendEnabled,proto3" json:"default_send_enabled,omitempty" yaml:"default_send_enabled,omitempty"`
}
func (m *Params) Reset() { *m = Params{} }
func (*Params) ProtoMessage() {}
func (*Params) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{0}
}
func (m *Params) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Params.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Params) XXX_Merge(src proto.Message) {
xxx_messageInfo_Params.Merge(m, src)
}
func (m *Params) XXX_Size() int {
return m.Size()
}
func (m *Params) XXX_DiscardUnknown() {
xxx_messageInfo_Params.DiscardUnknown(m)
}
var xxx_messageInfo_Params proto.InternalMessageInfo
func (m *Params) GetSendEnabled() []*SendEnabled {
if m != nil {
return m.SendEnabled
}
return nil
}
func (m *Params) GetDefaultSendEnabled() bool {
if m != nil {
return m.DefaultSendEnabled
}
return false
}
// Send enabled configuration properties for each denomination
type SendEnabled struct {
Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
Enabled bool `protobuf:"varint,2,opt,name=enabled,proto3" json:"enabled,omitempty"`
}
func (m *SendEnabled) Reset() { *m = SendEnabled{} }
func (*SendEnabled) ProtoMessage() {}
func (*SendEnabled) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{1}
}
func (m *SendEnabled) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *SendEnabled) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_SendEnabled.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *SendEnabled) XXX_Merge(src proto.Message) {
xxx_messageInfo_SendEnabled.Merge(m, src)
}
func (m *SendEnabled) XXX_Size() int {
return m.Size()
}
func (m *SendEnabled) XXX_DiscardUnknown() {
xxx_messageInfo_SendEnabled.DiscardUnknown(m)
}
var xxx_messageInfo_SendEnabled proto.InternalMessageInfo
func (m *SendEnabled) GetDenom() string {
if m != nil {
return m.Denom
}
return ""
}
func (m *SendEnabled) GetEnabled() bool {
if m != nil {
return m.Enabled
}
return false
}
// MsgSend - high level transaction of the coin module
type MsgSend struct {
FromAddress github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=from_address,json=fromAddress,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"from_address,omitempty" yaml:"from_address"`
@ -38,7 +142,7 @@ func (m *MsgSend) Reset() { *m = MsgSend{} }
func (m *MsgSend) String() string { return proto.CompactTextString(m) }
func (*MsgSend) ProtoMessage() {}
func (*MsgSend) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{0}
return fileDescriptor_717c78e54d4b5794, []int{2}
}
func (m *MsgSend) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -98,7 +202,7 @@ func (m *Input) Reset() { *m = Input{} }
func (m *Input) String() string { return proto.CompactTextString(m) }
func (*Input) ProtoMessage() {}
func (*Input) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{1}
return fileDescriptor_717c78e54d4b5794, []int{3}
}
func (m *Input) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -151,7 +255,7 @@ func (m *Output) Reset() { *m = Output{} }
func (m *Output) String() string { return proto.CompactTextString(m) }
func (*Output) ProtoMessage() {}
func (*Output) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{2}
return fileDescriptor_717c78e54d4b5794, []int{4}
}
func (m *Output) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -204,7 +308,7 @@ func (m *MsgMultiSend) Reset() { *m = MsgMultiSend{} }
func (m *MsgMultiSend) String() string { return proto.CompactTextString(m) }
func (*MsgMultiSend) ProtoMessage() {}
func (*MsgMultiSend) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{3}
return fileDescriptor_717c78e54d4b5794, []int{5}
}
func (m *MsgMultiSend) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -256,7 +360,7 @@ type Supply struct {
func (m *Supply) Reset() { *m = Supply{} }
func (*Supply) ProtoMessage() {}
func (*Supply) Descriptor() ([]byte, []int) {
return fileDescriptor_717c78e54d4b5794, []int{4}
return fileDescriptor_717c78e54d4b5794, []int{6}
}
func (m *Supply) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -286,6 +390,8 @@ func (m *Supply) XXX_DiscardUnknown() {
var xxx_messageInfo_Supply proto.InternalMessageInfo
func init() {
proto.RegisterType((*Params)(nil), "cosmos.bank.Params")
proto.RegisterType((*SendEnabled)(nil), "cosmos.bank.SendEnabled")
proto.RegisterType((*MsgSend)(nil), "cosmos.bank.MsgSend")
proto.RegisterType((*Input)(nil), "cosmos.bank.Input")
proto.RegisterType((*Output)(nil), "cosmos.bank.Output")
@ -296,38 +402,73 @@ func init() {
func init() { proto.RegisterFile("cosmos/bank/bank.proto", fileDescriptor_717c78e54d4b5794) }
var fileDescriptor_717c78e54d4b5794 = []byte{
// 457 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0xcc, 0xcb, 0x06, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42,
0xdc, 0x10, 0x71, 0x3d, 0x90, 0x90, 0x94, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x58, 0x5c, 0x1f, 0xc4,
0x82, 0x28, 0x91, 0x92, 0x84, 0x28, 0x89, 0x87, 0x48, 0x40, 0xd5, 0x43, 0xa4, 0x84, 0xa1, 0xa6,
0x22, 0x0b, 0x2a, 0xed, 0x66, 0xe2, 0x62, 0xf7, 0x2d, 0x4e, 0x0f, 0x4e, 0xcd, 0x4b, 0x11, 0xca,
0xe6, 0xe2, 0x49, 0x2b, 0xca, 0xcf, 0x8d, 0x4f, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x96, 0x60,
0x54, 0x60, 0xd4, 0xe0, 0x71, 0xf2, 0xf8, 0x74, 0x4f, 0x5e, 0xb8, 0x32, 0x31, 0x37, 0xc7, 0x4a,
0x09, 0x59, 0x56, 0xe9, 0xd7, 0x3d, 0x79, 0xdd, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4,
0xfc, 0x5c, 0x7d, 0x14, 0xc3, 0x75, 0x8b, 0x53, 0xb2, 0xf5, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0xf5,
0x1c, 0x93, 0x93, 0x1d, 0x21, 0x3a, 0x82, 0xb8, 0x41, 0xfa, 0xa1, 0x1c, 0xa1, 0x54, 0x2e, 0xae,
0x92, 0x7c, 0xb8, 0x55, 0x4c, 0x60, 0xab, 0xdc, 0x3e, 0xdd, 0x93, 0x17, 0x84, 0x58, 0x85, 0x90,
0x23, 0xc3, 0x22, 0xce, 0x92, 0x7c, 0x98, 0x35, 0x61, 0x5c, 0x6c, 0x89, 0xb9, 0xf9, 0xa5, 0x79,
0x25, 0x12, 0xcc, 0x0a, 0xcc, 0x1a, 0xdc, 0x46, 0x3c, 0x7a, 0x50, 0xef, 0x3b, 0xe7, 0x67, 0xe6,
0x39, 0x19, 0x9c, 0xb8, 0x27, 0xcf, 0xb0, 0xea, 0xbe, 0xbc, 0x06, 0x11, 0xe6, 0x83, 0x34, 0x14,
0x07, 0x41, 0x4d, 0xb3, 0x62, 0x79, 0xb1, 0x40, 0x9e, 0x51, 0x69, 0x03, 0x23, 0x17, 0xab, 0x67,
0x5e, 0x41, 0x69, 0x89, 0x90, 0x37, 0x17, 0x3b, 0x6a, 0xb0, 0x19, 0x92, 0xee, 0x6c, 0x98, 0x09,
0x42, 0x21, 0x5c, 0xac, 0xc9, 0x20, 0xdb, 0x24, 0x98, 0xa8, 0xe2, 0x66, 0x88, 0x61, 0x50, 0x27,
0x6f, 0x64, 0xe4, 0x62, 0xf3, 0x2f, 0x2d, 0x19, 0x52, 0x6e, 0xae, 0xe6, 0xe2, 0xf1, 0x2d, 0x4e,
0xf7, 0x2d, 0xcd, 0x29, 0xc9, 0x04, 0x27, 0x54, 0x03, 0x2e, 0xb6, 0x4c, 0x50, 0xa8, 0x83, 0xdc,
0x0d, 0xb2, 0x4c, 0x48, 0x0f, 0x29, 0x63, 0xe8, 0x81, 0x23, 0xc4, 0x89, 0x05, 0x64, 0x65, 0x10,
0x54, 0x9d, 0x90, 0x31, 0x17, 0x7b, 0x3e, 0xd8, 0xd3, 0x30, 0xf7, 0x09, 0xa3, 0x68, 0x81, 0x04,
0x08, 0x54, 0x0f, 0x4c, 0x25, 0xd4, 0xf2, 0xa5, 0x8c, 0x5c, 0x6c, 0xc1, 0xa5, 0x05, 0x05, 0x39,
0x95, 0x20, 0x3f, 0x96, 0xe4, 0x97, 0x24, 0xe6, 0x40, 0xad, 0xa5, 0xd8, 0x8f, 0x60, 0xc3, 0xac,
0x5c, 0x3b, 0x16, 0xc8, 0x33, 0xcc, 0x58, 0x20, 0xcf, 0x00, 0xb2, 0xee, 0xd2, 0x16, 0x5d, 0x53,
0x2d, 0xbc, 0x26, 0x54, 0x40, 0x8a, 0x85, 0xd4, 0x8a, 0x82, 0xfc, 0xa2, 0x92, 0xd4, 0x14, 0x3d,
0x88, 0xdb, 0x3c, 0x9d, 0x9c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23,
0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x4a,
0x93, 0x18, 0xf3, 0xc0, 0x0e, 0x4b, 0x62, 0x03, 0x97, 0x0a, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff,
0xff, 0xa5, 0xa6, 0xc2, 0x41, 0x82, 0x04, 0x00, 0x00,
// 583 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x54, 0x3d, 0x6f, 0xd3, 0x4e,
0x18, 0xf7, 0xa5, 0xad, 0xd3, 0x5e, 0xb2, 0xfc, 0x2f, 0xd1, 0x5f, 0xa6, 0x12, 0x76, 0xb0, 0x84,
0x94, 0x22, 0xe2, 0x14, 0x2a, 0x96, 0x6c, 0x75, 0x55, 0xa0, 0x42, 0x11, 0xc8, 0x45, 0x0c, 0x20,
0x11, 0x39, 0xf1, 0x35, 0x44, 0xb1, 0x7d, 0x56, 0xee, 0x2c, 0x35, 0xe2, 0x0b, 0x30, 0x32, 0x32,
0x66, 0x61, 0x61, 0x02, 0x89, 0x8d, 0x2f, 0x50, 0x89, 0xa5, 0x62, 0x62, 0x32, 0x28, 0x59, 0x98,
0x33, 0x32, 0x21, 0xdf, 0x9d, 0xa9, 0x2d, 0x21, 0x54, 0x5e, 0x16, 0x96, 0x28, 0xf7, 0x3c, 0xbf,
0xb7, 0x7b, 0xce, 0x77, 0xf0, 0xff, 0x01, 0xa1, 0x01, 0xa1, 0xed, 0xbe, 0x1b, 0x8e, 0xf9, 0x8f,
0x15, 0x4d, 0x08, 0x23, 0xa8, 0x22, 0xea, 0x56, 0x5a, 0xda, 0xac, 0x0f, 0xc9, 0x90, 0xf0, 0x7a,
0x3b, 0xfd, 0x27, 0x20, 0x9b, 0x17, 0x04, 0xa4, 0x27, 0x1a, 0x12, 0x2f, 0x5a, 0x35, 0xa9, 0x9a,
0x2f, 0x9a, 0xef, 0x01, 0x54, 0xef, 0xb9, 0x13, 0x37, 0xa0, 0xe8, 0x31, 0xac, 0x52, 0x1c, 0x7a,
0x3d, 0x1c, 0xba, 0x7d, 0x1f, 0x7b, 0x1a, 0x68, 0xac, 0x34, 0x2b, 0xd7, 0x35, 0x2b, 0x67, 0x6a,
0x1d, 0xe2, 0xd0, 0xdb, 0x17, 0x7d, 0xfb, 0xd2, 0x32, 0x31, 0x2e, 0x4e, 0xdd, 0xc0, 0xef, 0x98,
0x79, 0xde, 0x55, 0x12, 0x8c, 0x18, 0x0e, 0x22, 0x36, 0x35, 0x9d, 0x0a, 0x3d, 0xc3, 0xa3, 0x47,
0xb0, 0xee, 0xe1, 0x23, 0x37, 0xf6, 0x59, 0xaf, 0xe0, 0x53, 0x6a, 0x80, 0xe6, 0xba, 0xbd, 0xb5,
0x4c, 0x8c, 0xcb, 0x42, 0xed, 0x47, 0xa8, 0xbc, 0x2a, 0x92, 0x80, 0x5c, 0x98, 0xce, 0xea, 0x8b,
0x99, 0xa1, 0x98, 0xb7, 0x60, 0x25, 0x57, 0x44, 0x75, 0xb8, 0xe6, 0xe1, 0x90, 0x04, 0x1a, 0x68,
0x80, 0xe6, 0x86, 0x23, 0x16, 0x48, 0x83, 0xe5, 0x82, 0xb5, 0x93, 0x2d, 0x3b, 0xeb, 0xa9, 0xc8,
0x97, 0x99, 0x01, 0xcc, 0x77, 0x25, 0x58, 0xee, 0xd2, 0x61, 0x2a, 0x86, 0xc6, 0xb0, 0x7a, 0x34,
0x21, 0x41, 0xcf, 0xf5, 0xbc, 0x09, 0xa6, 0x94, 0x8b, 0x55, 0xed, 0xdb, 0xcb, 0xc4, 0xa8, 0x89,
0xbc, 0xf9, 0xae, 0xf9, 0x35, 0x31, 0x5a, 0xc3, 0x11, 0x7b, 0x12, 0xf7, 0xad, 0x01, 0x09, 0xda,
0x85, 0x99, 0xb7, 0xa8, 0x37, 0x6e, 0xb3, 0x69, 0x84, 0xa9, 0xb5, 0x3b, 0x18, 0xec, 0x0a, 0x86,
0x53, 0x49, 0xf9, 0x72, 0x81, 0x30, 0x84, 0x8c, 0x7c, 0xb7, 0x2a, 0x71, 0xab, 0x9b, 0xcb, 0xc4,
0xf8, 0x4f, 0x58, 0x9d, 0xf5, 0x7e, 0xc3, 0x68, 0x83, 0x91, 0xcc, 0xe6, 0x01, 0x54, 0xdd, 0x80,
0xc4, 0x21, 0xd3, 0x56, 0xf8, 0x29, 0x57, 0xb3, 0x53, 0xde, 0x23, 0xa3, 0xd0, 0xde, 0x3e, 0x49,
0x0c, 0xe5, 0xd5, 0x27, 0xa3, 0x79, 0x0e, 0xfd, 0x94, 0x40, 0x1d, 0xa9, 0xd6, 0x59, 0xe5, 0xd3,
0x7b, 0x0d, 0xe0, 0xda, 0x41, 0x18, 0xc5, 0x0c, 0xdd, 0x81, 0xe5, 0xe2, 0xd8, 0xae, 0xfd, 0x7a,
0xec, 0x4c, 0x01, 0xdd, 0x87, 0x6b, 0x83, 0xd4, 0x4d, 0x2b, 0xfd, 0x95, 0xcc, 0x42, 0x4c, 0x46,
0x7e, 0x03, 0xa0, 0x7a, 0x37, 0x66, 0xff, 0x54, 0xe6, 0xa7, 0xb0, 0xda, 0xa5, 0xc3, 0x6e, 0xec,
0xb3, 0x11, 0xff, 0x50, 0xb7, 0xa1, 0x3a, 0x4a, 0xa7, 0x4e, 0xe5, 0xd5, 0x45, 0x85, 0xab, 0xcb,
0x0f, 0xc4, 0x5e, 0x4d, 0x2d, 0x1d, 0x89, 0x43, 0x3b, 0xb0, 0x4c, 0xf8, 0xa6, 0xb3, 0x7c, 0xb5,
0x02, 0x45, 0x0c, 0x44, 0x72, 0x32, 0xa4, 0x34, 0x7f, 0x09, 0xa0, 0x7a, 0x18, 0x47, 0x91, 0x3f,
0x4d, 0xf7, 0xc8, 0x08, 0x73, 0x7d, 0x69, 0xfb, 0xc7, 0x7b, 0xe4, 0x62, 0x9d, 0xfd, 0x67, 0x33,
0x43, 0xc9, 0x2e, 0xe4, 0x87, 0xb7, 0xad, 0x1b, 0x57, 0x7e, 0xaa, 0x70, 0x2c, 0x5e, 0x4b, 0x7c,
0x1c, 0x91, 0x09, 0xc3, 0x9e, 0x25, 0xb2, 0x1d, 0xd8, 0x7b, 0x27, 0x73, 0x1d, 0x9c, 0xce, 0x75,
0xf0, 0x79, 0xae, 0x83, 0xe7, 0x0b, 0x5d, 0x39, 0x5d, 0xe8, 0xca, 0xc7, 0x85, 0xae, 0x3c, 0xdc,
0x3a, 0x8f, 0x1e, 0x0f, 0xd6, 0x57, 0xf9, 0x63, 0xb9, 0xf3, 0x2d, 0x00, 0x00, 0xff, 0xff, 0xba,
0x32, 0x90, 0x68, 0x99, 0x05, 0x00, 0x00,
}
func (this *SendEnabled) Equal(that interface{}) bool {
if that == nil {
return this == nil
}
that1, ok := that.(*SendEnabled)
if !ok {
that2, ok := that.(SendEnabled)
if ok {
that1 = &that2
} else {
return false
}
}
if that1 == nil {
return this == nil
} else if this == nil {
return false
}
if this.Denom != that1.Denom {
return false
}
if this.Enabled != that1.Enabled {
return false
}
return true
}
func (this *MsgSend) Equal(that interface{}) bool {
if that == nil {
return this == nil
@ -493,6 +634,93 @@ func (this *Supply) Equal(that interface{}) bool {
}
return true
}
func (m *Params) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Params) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.DefaultSendEnabled {
i--
if m.DefaultSendEnabled {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x10
}
if len(m.SendEnabled) > 0 {
for iNdEx := len(m.SendEnabled) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.SendEnabled[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintBank(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *SendEnabled) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *SendEnabled) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *SendEnabled) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Enabled {
i--
if m.Enabled {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x10
}
if len(m.Denom) > 0 {
i -= len(m.Denom)
copy(dAtA[i:], m.Denom)
i = encodeVarintBank(dAtA, i, uint64(len(m.Denom)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *MsgSend) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -731,6 +959,40 @@ func encodeVarintBank(dAtA []byte, offset int, v uint64) int {
dAtA[offset] = uint8(v)
return base
}
func (m *Params) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.SendEnabled) > 0 {
for _, e := range m.SendEnabled {
l = e.Size()
n += 1 + l + sovBank(uint64(l))
}
}
if m.DefaultSendEnabled {
n += 2
}
return n
}
func (m *SendEnabled) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Denom)
if l > 0 {
n += 1 + l + sovBank(uint64(l))
}
if m.Enabled {
n += 2
}
return n
}
func (m *MsgSend) Size() (n int) {
if m == nil {
return 0
@ -834,6 +1096,218 @@ func sovBank(x uint64) (n int) {
func sozBank(x uint64) (n int) {
return sovBank(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Params) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Params: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field SendEnabled", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthBank
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthBank
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.SendEnabled = append(m.SendEnabled, &SendEnabled{})
if err := m.SendEnabled[len(m.SendEnabled)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DefaultSendEnabled", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.DefaultSendEnabled = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipBank(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthBank
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthBank
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *SendEnabled) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: SendEnabled: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: SendEnabled: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
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 ErrInvalidLengthBank
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthBank
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Denom = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Enabled", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowBank
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Enabled = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipBank(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthBank
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthBank
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *MsgSend) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@ -14,9 +14,9 @@ var _ exported.GenesisBalance = (*Balance)(nil)
// GenesisState defines the bank module's genesis state.
type GenesisState struct {
SendEnabled bool `json:"send_enabled" yaml:"send_enabled"`
Balances []Balance `json:"balances" yaml:"balances"`
Supply sdk.Coins `json:"supply" yaml:"supply"`
Params Params `json:"params" yaml:"params"`
Balances []Balance `json:"balances" yaml:"balances"`
Supply sdk.Coins `json:"supply" yaml:"supply"`
}
// Balance defines an account address and balance pair used in the bank module's
@ -50,17 +50,17 @@ func SanitizeGenesisBalances(balances []Balance) []Balance {
}
// NewGenesisState creates a new genesis state.
func NewGenesisState(sendEnabled bool, balances []Balance, supply sdk.Coins) GenesisState {
func NewGenesisState(params Params, balances []Balance, supply sdk.Coins) GenesisState {
return GenesisState{
SendEnabled: sendEnabled,
Balances: balances,
Supply: supply,
Params: params,
Balances: balances,
Supply: supply,
}
}
// DefaultGenesisState returns a default bank module genesis state.
func DefaultGenesisState() GenesisState {
return NewGenesisState(true, []Balance{}, DefaultSupply().GetTotal())
return NewGenesisState(DefaultParams(), []Balance{}, DefaultSupply().GetTotal())
}
// GetGenesisStateFromAppState returns x/bank GenesisState given raw application

View File

@ -3,7 +3,9 @@ package types
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
yaml "gopkg.in/yaml.v2"
)
const (
@ -11,21 +13,129 @@ const (
DefaultSendEnabled = true
)
// ParamStoreKeySendEnabled is store's key for SendEnabled
var ParamStoreKeySendEnabled = []byte("sendenabled")
var (
// KeySendEnabled is store's key for SendEnabled Params
KeySendEnabled = []byte("SendEnabled")
// KeyDefaultSendEnabled is store's key for the DefaultSendEnabled option
KeyDefaultSendEnabled = []byte("DefaultSendEnabled")
)
// ParamKeyTable type declaration for parameters
// ParamKeyTable for bank module.
func ParamKeyTable() paramtypes.KeyTable {
return paramtypes.NewKeyTable(
paramtypes.NewParamSetPair(ParamStoreKeySendEnabled, false, validateSendEnabled),
)
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
}
// NewParams creates a new parameter configuration for the bank module
func NewParams(defaultSendEnabled bool, sendEnabledParams SendEnabledParams) Params {
return Params{
SendEnabled: sendEnabledParams,
DefaultSendEnabled: defaultSendEnabled,
}
}
// DefaultParams is the default parameter configuration for the bank module
func DefaultParams() Params {
return Params{
SendEnabled: SendEnabledParams{},
// The default send enabled value allows send transfers for all coin denoms
DefaultSendEnabled: true,
}
}
// Validate all bank module parameters
func (p Params) Validate() error {
if err := validateSendEnabledParams(p.SendEnabled); err != nil {
return err
}
return validateIsBool(p.DefaultSendEnabled)
}
// String implements the Stringer interface.
func (p Params) String() string {
out, _ := yaml.Marshal(p)
return string(out)
}
// SendEnabledDenom returns true if the given denom is enabled for sending
func (p Params) SendEnabledDenom(denom string) bool {
for _, pse := range p.SendEnabled {
if pse.Denom == denom {
return pse.Enabled
}
}
return p.DefaultSendEnabled
}
// SetSendEnabledParam returns an updated set of Parameters with the given denom
// send enabled flag set.
func (p Params) SetSendEnabledParam(denom string, sendEnabled bool) Params {
var sendParams SendEnabledParams
for _, p := range p.SendEnabled {
if p.Denom != denom {
sendParams = append(sendParams, NewSendEnabled(p.Denom, p.Enabled))
}
}
sendParams = append(sendParams, NewSendEnabled(denom, sendEnabled))
return NewParams(p.DefaultSendEnabled, sendParams)
}
// ParamSetPairs implements params.ParamSet
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
return paramtypes.ParamSetPairs{
paramtypes.NewParamSetPair(KeySendEnabled, &p.SendEnabled, validateSendEnabledParams),
paramtypes.NewParamSetPair(KeyDefaultSendEnabled, &p.DefaultSendEnabled, validateIsBool),
}
}
// SendEnabledParams is a collection of parameters indicating if a coin denom is enabled for sending
type SendEnabledParams []*SendEnabled
func validateSendEnabledParams(i interface{}) error {
params, ok := i.([]*SendEnabled)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
// ensure each denom is only registered one time.
registered := make(map[string]bool)
for _, p := range params {
if _, exists := registered[p.Denom]; exists {
return fmt.Errorf("duplicate send enabled parameter found: '%s'", p.Denom)
}
if err := validateSendEnabled(*p); err != nil {
return err
}
registered[p.Denom] = true
}
return nil
}
// NewSendEnabled creates a new SendEnabled object
// The denom may be left empty to control the global default setting of send_enabled
func NewSendEnabled(denom string, sendEnabled bool) *SendEnabled {
return &SendEnabled{
Denom: denom,
Enabled: sendEnabled,
}
}
// String implements stringer insterface
func (se SendEnabled) String() string {
out, _ := yaml.Marshal(se)
return string(out)
}
func validateSendEnabled(i interface{}) error {
param, ok := i.(SendEnabled)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return sdk.ValidateDenom(param.Denom)
}
func validateIsBool(i interface{}) error {
_, ok := i.(bool)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
}
return nil
}

124
x/bank/types/params_test.go Normal file
View File

@ -0,0 +1,124 @@
package types
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
)
func Test_validateSendEnabledParam(t *testing.T) {
type args struct {
i interface{}
}
tests := []struct {
name string
args args
wantErr bool
}{
{"invalid type", args{sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())}, true},
{"invalid empty denom send enabled", args{*NewSendEnabled("", true)}, true},
{"invalid empty denom send disabled", args{*NewSendEnabled("", false)}, true},
{"valid denom send enabled", args{*NewSendEnabled(sdk.DefaultBondDenom, true)}, false},
{"valid denom send disabled", args{*NewSendEnabled(sdk.DefaultBondDenom, false)}, false},
{"invalid denom send enabled", args{*NewSendEnabled("FOO", true)}, true},
{"invalid denom send disabled", args{*NewSendEnabled("FOO", false)}, true},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.wantErr, validateSendEnabled(tt.args.i) != nil)
})
}
}
func Test_sendParamEqual(t *testing.T) {
paramsA := NewSendEnabled(sdk.DefaultBondDenom, true)
paramsB := NewSendEnabled(sdk.DefaultBondDenom, true)
paramsC := NewSendEnabled("foodenom", false)
ok := paramsA.Equal(paramsB)
require.True(t, ok)
ok = paramsA.Equal(paramsC)
require.False(t, ok)
}
func Test_sendParamString(t *testing.T) {
paramString := "denom: foo\nenabled: false\n"
param := NewSendEnabled("foo", false)
require.Equal(t, paramString, param.String())
}
func Test_validateParams(t *testing.T) {
params := DefaultParams()
// default params have no error
require.NoError(t, params.Validate())
// default case is all denoms are enabled for sending
require.True(t, params.SendEnabledDenom(sdk.DefaultBondDenom))
require.True(t, params.SendEnabledDenom("foodenom"))
params.DefaultSendEnabled = false
params = params.SetSendEnabledParam("foodenom", true)
require.NoError(t, validateSendEnabledParams(params.SendEnabled))
require.True(t, params.SendEnabledDenom("foodenom"))
require.False(t, params.SendEnabledDenom(sdk.DefaultBondDenom))
params.DefaultSendEnabled = true
params = params.SetSendEnabledParam("foodenom", false)
require.NoError(t, validateSendEnabledParams(params.SendEnabled))
require.False(t, params.SendEnabledDenom("foodenom"))
require.True(t, params.SendEnabledDenom(sdk.DefaultBondDenom))
params = params.SetSendEnabledParam("foodenom", true)
require.True(t, params.SendEnabledDenom("foodenom"))
params = params.SetSendEnabledParam("foodenom", false)
require.False(t, params.SendEnabledDenom("foodenom"))
require.True(t, params.SendEnabledDenom("foodenom2"))
params = params.SetSendEnabledParam("foodenom2", false)
require.True(t, params.SendEnabledDenom(""))
require.True(t, params.SendEnabledDenom(sdk.DefaultBondDenom))
require.False(t, params.SendEnabledDenom("foodenom2"))
paramYaml := `send_enabled:
- denom: foodenom
enabled: false
- denom: foodenom2
enabled: false
default_send_enabled: true
`
require.Equal(t, paramYaml, params.String())
// Ensure proper format of yaml output when false
params.DefaultSendEnabled = false
paramYaml = `send_enabled:
- denom: foodenom
enabled: false
- denom: foodenom2
enabled: false
`
require.Equal(t, paramYaml, params.String())
params = NewParams(true, SendEnabledParams{
NewSendEnabled("foodenom", false),
NewSendEnabled("foodenom", true), // this is not allowed
})
// fails due to duplicate entries.
require.Error(t, params.Validate())
// fails due to invalid type
require.Error(t, validateSendEnabledParams(NewSendEnabled("foodenom", true)))
require.Error(t, validateSendEnabledParams(SendEnabledParams{NewSendEnabled("INVALIDDENOM", true)}))
}

View File

@ -13,6 +13,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
)
@ -31,7 +32,7 @@ func (suite *SlashingTestSuite) SetupTest() {
ctx := app.BaseApp.NewContext(false, abci.Header{})
app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
app.BankKeeper.SetSendEnabled(ctx, true)
app.BankKeeper.SetParams(ctx, banktypes.DefaultParams())
app.SlashingKeeper.SetParams(ctx, keeper.TestParams())
addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.TokensFromConsensusPower(200))