Merge branch 'master' into master
This commit is contained in:
commit
38762621a3
|
@ -105,6 +105,7 @@ if input key is empty, or input data contains empty key.
|
|||
* `sdk.Msg` now only contains `ValidateBasic` and `GetSigners` methods. The remaining methods `GetSignBytes`, `Route` and `Type` are moved to `legacytx.LegacyMsg`.
|
||||
* The `RegisterCustomTypeURL` function and the `cosmos.base.v1beta1.ServiceMsg` interface have been removed from the interface registry.
|
||||
* (codec) [\#9251](https://github.com/cosmos/cosmos-sdk/pull/9251) Rename `clientCtx.JSONMarshaler` to `clientCtx.JSONCodec` as per #9226.
|
||||
* (x/bank) [\#9271](https://github.com/cosmos/cosmos-sdk/pull/9271) SendEnabledCoin(s) renamed to IsSendEnabledCoin(s) to better reflect its functionality.
|
||||
|
||||
|
||||
### State Machine Breaking
|
||||
|
|
|
@ -0,0 +1,277 @@
|
|||
# ADR 042: Group Module
|
||||
|
||||
## Changelog
|
||||
|
||||
- 2020/04/09: Initial Draft
|
||||
|
||||
## Status
|
||||
|
||||
Draft
|
||||
|
||||
## Abstract
|
||||
|
||||
This ADR defines the `x/group` module which allows the creation and management of on-chain multi-signature accounts and enables voting for message execution based on configurable decision policies.
|
||||
|
||||
## Context
|
||||
|
||||
The legacy amino multi-signature mechanism of the Cosmos SDK has certain limitations:
|
||||
- Key rotation is not possible, although this can be solved with [account rekeying](adr-034-account-rekeying.md).
|
||||
- Thresholds can't be changed.
|
||||
- UX is cumbersome for non-technical users ([#5661](https://github.com/cosmos/cosmos-sdk/issues/5661)).
|
||||
- It requires `legacy_amino` sign mode ([#8141](https://github.com/cosmos/cosmos-sdk/issues/8141)).
|
||||
|
||||
While the group module is not meant to be a total replacement for the current multi-signature accounts, it provides a solution to the limitations described above, with a more flexible key management system where keys can be added, updated or removed, as well as configurable thresholds.
|
||||
It's meant to be used with other access control modules such as [`x/feegrant`](./adr-029-fee-grant-module.md) ans [`x/authz`](adr-030-authz-module.md) to simplify key management for individuals and organizations.
|
||||
|
||||
The proof of concept of the group module can be found in https://github.com/regen-network/regen-ledger/tree/master/proto/regen/group/v1alpha1 and https://github.com/regen-network/regen-ledger/tree/master/x/group.
|
||||
|
||||
## Decision
|
||||
|
||||
We propose merging the `x/group` module with its supporting [ORM/Table Store package](https://github.com/regen-network/regen-ledger/tree/master/orm) ([#7098](https://github.com/cosmos/cosmos-sdk/issues/7098)) into the Cosmos SDK and continuing development here. There will be a dedicated ADR for the ORM package.
|
||||
|
||||
### Group
|
||||
|
||||
A group is a composition of accounts with associated weights. It is not
|
||||
an account and doesn't have a balance. It doesn't in and of itself have any
|
||||
sort of voting or decision weight.
|
||||
Group members can create proposals and vote on them through group accounts using different decision policies.
|
||||
|
||||
It has an `admin` account which can manage members in the group, update the group
|
||||
metadata and set a new admin.
|
||||
|
||||
```proto
|
||||
message GroupInfo {
|
||||
|
||||
// group_id is the unique ID of this group.
|
||||
uint64 group_id = 1;
|
||||
|
||||
// admin is the account address of the group's admin.
|
||||
string admin = 2;
|
||||
|
||||
// metadata is any arbitrary metadata to attached to the group.
|
||||
bytes metadata = 3;
|
||||
|
||||
// version is used to track changes to a group's membership structure that
|
||||
// would break existing proposals. Whenever a member weight has changed,
|
||||
// or any member is added or removed, the version is incremented and will
|
||||
// invalidate all proposals from older versions.
|
||||
uint64 version = 4;
|
||||
|
||||
// total_weight is the sum of the group members' weights.
|
||||
string total_weight = 5;
|
||||
}
|
||||
```
|
||||
|
||||
```proto
|
||||
message GroupMember {
|
||||
|
||||
// group_id is the unique ID of the group.
|
||||
uint64 group_id = 1;
|
||||
|
||||
// member is the member data.
|
||||
Member member = 2;
|
||||
}
|
||||
|
||||
// Member represents a group member with an account address,
|
||||
// non-zero weight and metadata.
|
||||
message Member {
|
||||
|
||||
// address is the member's account address.
|
||||
string address = 1;
|
||||
|
||||
// weight is the member's voting weight that should be greater than 0.
|
||||
string weight = 2;
|
||||
|
||||
// metadata is any arbitrary metadata to attached to the member.
|
||||
bytes metadata = 3;
|
||||
}
|
||||
```
|
||||
|
||||
### Group Account
|
||||
|
||||
A group account is an account associated with a group and a decision policy.
|
||||
A group account does have a balance.
|
||||
|
||||
Group accounts are abstracted from groups because a single group may have
|
||||
multiple decision policies for different types of actions. Managing group
|
||||
membership separately from decision policies results in the least overhead
|
||||
and keeps membership consistent across different policies. The pattern that
|
||||
is recommended is to have a single master group account for a given group,
|
||||
and then to create separate group accounts with different decision policies
|
||||
and delegate the desired permissions from the master account to
|
||||
those "sub-accounts" using the [`x/authz` module](adr-030-authz-module.md).
|
||||
|
||||
```proto
|
||||
message GroupAccountInfo {
|
||||
|
||||
// address is the group account address.
|
||||
string address = 1;
|
||||
|
||||
// group_id is the ID of the Group the GroupAccount belongs to.
|
||||
uint64 group_id = 2;
|
||||
|
||||
// admin is the account address of the group admin.
|
||||
string admin = 3;
|
||||
|
||||
// metadata is any arbitrary metadata of this group account.
|
||||
bytes metadata = 4;
|
||||
|
||||
// version is used to track changes to a group's GroupAccountInfo structure that
|
||||
// invalidates active proposal from old versions.
|
||||
uint64 version = 5;
|
||||
|
||||
// decision_policy specifies the group account's decision policy.
|
||||
google.protobuf.Any decision_policy = 6 [(cosmos_proto.accepts_interface) = "DecisionPolicy"];
|
||||
}
|
||||
```
|
||||
|
||||
Similarly to a group admin, a group account admin can update its metadata, decision policy or set a new group account admin.
|
||||
|
||||
A group account can also be an admin or a member of a group.
|
||||
For instance, a group admin could be another group account which could "elects" the members or it could be the same group that elects itself.
|
||||
|
||||
### Decision Policy
|
||||
|
||||
A decision policy is the mechanism by which members of a group can vote on
|
||||
proposals.
|
||||
|
||||
All decision policies should have a minimum and maximum voting window.
|
||||
The minimum voting window is the minimum duration that must pass in order
|
||||
for a proposal to potentially pass, and it may be set to 0. The maximum voting
|
||||
window is the maximum time that a proposal may be voted on and executed if
|
||||
it reached enough support before it is closed.
|
||||
Both of these values must be less than a chain-wide max voting window parameter.
|
||||
|
||||
We define the `DecisionPolicy` interface that all decision policies must implement:
|
||||
|
||||
```go
|
||||
type DecisionPolicy interface {
|
||||
codec.ProtoMarshaler
|
||||
|
||||
ValidateBasic() error
|
||||
GetTimeout() types.Duration
|
||||
Allow(tally Tally, totalPower string, votingDuration time.Duration) (DecisionPolicyResult, error)
|
||||
Validate(g GroupInfo) error
|
||||
}
|
||||
|
||||
type DecisionPolicyResult struct {
|
||||
Allow bool
|
||||
Final bool
|
||||
}
|
||||
```
|
||||
|
||||
#### Threshold decision policy
|
||||
|
||||
A threshold decision policy defines a minimum support votes (_yes_), based on a tally
|
||||
of voter weights, for a proposal to pass. For
|
||||
this decision policy, abstain and veto are treated as no support (_no_).
|
||||
|
||||
```proto
|
||||
message ThresholdDecisionPolicy {
|
||||
|
||||
// threshold is the minimum weighted sum of support votes for a proposal to succeed.
|
||||
string threshold = 1;
|
||||
|
||||
// voting_period is the duration from submission of a proposal to the end of voting period
|
||||
// Within this period, votes and exec messages can be submitted.
|
||||
google.protobuf.Duration voting_period = 2 [(gogoproto.nullable) = false];
|
||||
}
|
||||
```
|
||||
|
||||
### Proposal
|
||||
|
||||
Any member of a group can submit a proposal for a group account to decide upon.
|
||||
A proposal consists of a set of `sdk.Msg`s that will be executed if the proposal
|
||||
passes as well as any metadata associated with the proposal. These `sdk.Msg`s get validated as part of the `Msg/CreateProposal` request validation. They should also have their signer set as the group account.
|
||||
|
||||
Internally, a proposal also tracks:
|
||||
- its current `Status`: submitted, closed or aborted
|
||||
- its `Result`: unfinalized, accepted or rejected
|
||||
- its `VoteState` in the form of a `Tally`, which is calculated on new votes and when executing the proposal.
|
||||
|
||||
```proto
|
||||
// Tally represents the sum of weighted votes.
|
||||
message Tally {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// yes_count is the weighted sum of yes votes.
|
||||
string yes_count = 1;
|
||||
|
||||
// no_count is the weighted sum of no votes.
|
||||
string no_count = 2;
|
||||
|
||||
// abstain_count is the weighted sum of abstainers.
|
||||
string abstain_count = 3;
|
||||
|
||||
// veto_count is the weighted sum of vetoes.
|
||||
string veto_count = 4;
|
||||
}
|
||||
```
|
||||
|
||||
### Voting
|
||||
|
||||
Members of a group can vote on proposals. There are four choices to choose while voting - yes, no, abstain and veto. Not
|
||||
all decision policies will support them. Votes can contain some optional metadata.
|
||||
In the current implementation, the voting window begins as soon as a proposal
|
||||
is submitted.
|
||||
|
||||
Voting internally updates the proposal `VoteState` as well as `Status` and `Result` if needed.
|
||||
|
||||
### Executing Proposals
|
||||
|
||||
Proposals will not be automatically executed by the chain in this current design,
|
||||
but rather a user must submit a `Msg/Exec` transaction to attempt to execute the
|
||||
proposal based on the current votes and decision policy. A future upgrade could
|
||||
automate this and have the group account (or a fee granter) pay.
|
||||
|
||||
#### Changing Group Membership
|
||||
|
||||
In the current implementation, updating a group or a group account after submitting a proposal will make it invalid. It will simply fail if someone calls `Msg/Exec` and will eventually be garbage collected.
|
||||
|
||||
### Notes on current implementation
|
||||
|
||||
This section outlines the current implementation used in the proof of concept of the group module but this could be subject to changes and iterated on.
|
||||
|
||||
#### ORM
|
||||
|
||||
The [ORM package](https://github.com/cosmos/cosmos-sdk/discussions/9156) defines tables, sequences and secondary indexes which are used in the group module.
|
||||
|
||||
Groups are stored in state as part of a `groupTable`, the `group_id` being an auto-increment integer. Group members are stored in a `groupMemberTable`.
|
||||
|
||||
Group accounts are stored in a `groupAccountTable`. The group account address is generated based on an auto-increment integer which is used to derive the group module `RootModuleKey` into a `DerivedModuleKey`, as stated in [ADR-033](adr-033-protobuf-inter-module-comm.md#modulekeys-and-moduleids). The group account is added as a new `ModuleAccount` through `x/auth`.
|
||||
|
||||
Proposals are stored as part of the `proposalTable` using the `Proposal` type. The `proposal_id` is an auto-increment integer.
|
||||
|
||||
Votes are stored in the `voteTable`. The primary key is based on the vote's `proposal_id` and `voter` account address.
|
||||
|
||||
#### ADR-033 to route proposal messages
|
||||
|
||||
Inter-module communication introduced by [ADR-033](adr-033-protobuf-inter-module-comm.md) can be used to route a proposal's messages using the `DerivedModuleKey` corresponding to the proposal's group account.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- Improved UX for multi-signature accounts allowing key rotation and custom decision policies.
|
||||
|
||||
### Negative
|
||||
|
||||
### Neutral
|
||||
|
||||
- It uses ADR 033 so it will need to be implemented within the Cosmos SDK, but this doesn't imply necessarily any large refactoring of existing Cosmos SDK modules.
|
||||
- The current implementation of the group module uses the ORM package.
|
||||
|
||||
## Further Discussions
|
||||
|
||||
- Convergence of `/group` and `x/gov` as both support proposals and voting: https://github.com/cosmos/cosmos-sdk/discussions/9066
|
||||
- `x/group` possible future improvements:
|
||||
- Execute proposals on submission (https://github.com/regen-network/regen-ledger/issues/288)
|
||||
- Withdraw a proposal (https://github.com/regen-network/cosmos-modules/issues/41)
|
||||
- Make `Tally` more flexible and support non-binary choices
|
||||
|
||||
## References
|
||||
|
||||
- Initial specification:
|
||||
- https://gist.github.com/aaronc/b60628017352df5983791cad30babe56#group-module
|
||||
- [#5236](https://github.com/cosmos/cosmos-sdk/pull/5236)
|
||||
- Proposal to add `x/group` into the SDK: [#7633](https://github.com/cosmos/cosmos-sdk/issues/7633)
|
|
@ -1323,8 +1323,7 @@ account with the provided expiration time.
|
|||
| ----- | ---- | ----- | ----------- |
|
||||
| `granter` | [string](#string) | | |
|
||||
| `grantee` | [string](#string) | | |
|
||||
| `authorization` | [google.protobuf.Any](#google.protobuf.Any) | | |
|
||||
| `expiration` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | |
|
||||
| `grant` | [Grant](#cosmos.authz.v1beta1.Grant) | | |
|
||||
|
||||
|
||||
|
||||
|
@ -6183,9 +6182,9 @@ AuthorizationType defines the type of staking module authorization type
|
|||
| Name | Number | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| AUTHORIZATION_TYPE_UNSPECIFIED | 0 | AUTHORIZATION_TYPE_UNSPECIFIED specifies an unknown authorization type |
|
||||
| AUTHORIZATION_TYPE_DELEGATE | 1 | AUTHORIZATION_TYPE_DELEGATE defines an authorization type for Msg/Delegate |
|
||||
| AUTHORIZATION_TYPE_UNDELEGATE | 2 | AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for Msg/Undelegate |
|
||||
| AUTHORIZATION_TYPE_REDELEGATE | 3 | AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for Msg/BeginRedelegate |
|
||||
| AUTHORIZATION_TYPE_DELEGATE | 1 | AUTHORIZATION_TYPE_DELEGATE defines an authorization type for MsgDelegate |
|
||||
| AUTHORIZATION_TYPE_UNDELEGATE | 2 | AUTHORIZATION_TYPE_UNDELEGATE defines an authorization type for MsgUndelegate |
|
||||
| AUTHORIZATION_TYPE_REDELEGATE | 3 | AUTHORIZATION_TYPE_REDELEGATE defines an authorization type for MsgBeginRedelegate |
|
||||
|
||||
|
||||
<!-- end enums -->
|
||||
|
@ -7168,7 +7167,7 @@ of coins from a delegator and source validator to a destination validator.
|
|||
<a name="cosmos.staking.v1beta1.MsgBeginRedelegateResponse"></a>
|
||||
|
||||
### MsgBeginRedelegateResponse
|
||||
MsgBeginRedelegateResponse defines the Msg/BeginRedelegate response type.
|
||||
MsgBeginRedelegateResponse defines the MsgBeginRedelegate response type.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
|
@ -7204,7 +7203,7 @@ MsgCreateValidator defines a SDK message for creating a new validator.
|
|||
<a name="cosmos.staking.v1beta1.MsgCreateValidatorResponse"></a>
|
||||
|
||||
### MsgCreateValidatorResponse
|
||||
MsgCreateValidatorResponse defines the Msg/CreateValidator response type.
|
||||
MsgCreateValidatorResponse defines the MsgCreateValidator response type.
|
||||
|
||||
|
||||
|
||||
|
@ -7232,7 +7231,7 @@ from a delegator to a validator.
|
|||
<a name="cosmos.staking.v1beta1.MsgDelegateResponse"></a>
|
||||
|
||||
### MsgDelegateResponse
|
||||
MsgDelegateResponse defines the Msg/Delegate response type.
|
||||
MsgDelegateResponse defines the MsgDelegate response type.
|
||||
|
||||
|
||||
|
||||
|
@ -7260,7 +7259,7 @@ MsgEditValidator defines a SDK message for editing an existing validator.
|
|||
<a name="cosmos.staking.v1beta1.MsgEditValidatorResponse"></a>
|
||||
|
||||
### MsgEditValidatorResponse
|
||||
MsgEditValidatorResponse defines the Msg/EditValidator response type.
|
||||
MsgEditValidatorResponse defines the MsgEditValidator response type.
|
||||
|
||||
|
||||
|
||||
|
@ -7288,7 +7287,7 @@ delegate and a validator.
|
|||
<a name="cosmos.staking.v1beta1.MsgUndelegateResponse"></a>
|
||||
|
||||
### MsgUndelegateResponse
|
||||
MsgUndelegateResponse defines the Msg/Undelegate response type.
|
||||
MsgUndelegateResponse defines the MsgUndelegate response type.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
|
|
2
go.mod
2
go.mod
|
@ -30,7 +30,7 @@ require (
|
|||
github.com/jhump/protoreflect v1.8.2
|
||||
github.com/magiconair/properties v1.8.5
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/otiai10/copy v1.5.1
|
||||
github.com/otiai10/copy v1.6.0
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.10.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -512,8 +512,8 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS
|
|||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/otiai10/copy v1.5.1 h1:a/cs2E1/1V0az8K5nblbl+ymEa4E11AfaOLMar8V34w=
|
||||
github.com/otiai10/copy v1.5.1/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
|
||||
github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ=
|
||||
github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
|
|
|
@ -6,6 +6,7 @@ import "gogoproto/gogo.proto";
|
|||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
import "cosmos/base/abci/v1beta1/abci.proto";
|
||||
import "cosmos/authz/v1beta1/authz.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/authz";
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
|
@ -32,8 +33,7 @@ message MsgGrant {
|
|||
string granter = 1;
|
||||
string grantee = 2;
|
||||
|
||||
google.protobuf.Any authorization = 3 [(cosmos_proto.accepts_interface) = "Authorization"];
|
||||
google.protobuf.Timestamp expiration = 4 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
|
||||
cosmos.authz.v1beta1.Grant grant = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// MsgExecResponse defines the Msg/MsgExecResponse response type.
|
||||
|
|
|
@ -52,7 +52,7 @@ message Supply {
|
|||
option (gogoproto.equal) = true;
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/exported.SupplyI";
|
||||
option (cosmos_proto.implements_interface) = "*github.com/cosmos/cosmos-sdk/x/bank/legacy/v040.SupplyI";
|
||||
|
||||
repeated cosmos.base.v1beta1.Coin total = 1
|
||||
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
|
||||
|
|
|
@ -32,7 +32,7 @@ func (s msgServer) CreateVestingAccount(goCtx context.Context, msg *types.MsgCre
|
|||
ak := s.AccountKeeper
|
||||
bk := s.BankKeeper
|
||||
|
||||
if err := bk.SendEnabledCoins(ctx, msg.Amount...); err != nil {
|
||||
if err := bk.IsSendEnabledCoins(ctx, msg.Amount...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
// BankKeeper defines the expected interface contract the vesting module requires
|
||||
// for creating vesting accounts with funds.
|
||||
type BankKeeper interface {
|
||||
SendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
|
||||
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
BlockedAddr(addr sdk.AccAddress) bool
|
||||
}
|
||||
|
|
|
@ -9,24 +9,23 @@ import (
|
|||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
// NewGrant returns new AuthrizationGrant
|
||||
func NewGrant(authorization Authorization, expiration time.Time) (Grant, error) {
|
||||
auth := Grant{
|
||||
// NewGrant returns new Grant
|
||||
func NewGrant(a Authorization, expiration time.Time) (Grant, error) {
|
||||
g := Grant{
|
||||
Expiration: expiration,
|
||||
}
|
||||
msg, ok := authorization.(proto.Message)
|
||||
msg, ok := a.(proto.Message)
|
||||
if !ok {
|
||||
return Grant{}, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", authorization)
|
||||
return Grant{}, sdkerrors.Wrapf(sdkerrors.ErrPackAny, "cannot proto marshal %T", a)
|
||||
}
|
||||
|
||||
any, err := cdctypes.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
return Grant{}, err
|
||||
}
|
||||
g.Authorization = any
|
||||
|
||||
auth.Authorization = any
|
||||
|
||||
return auth, nil
|
||||
return g, nil
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -34,16 +33,32 @@ var (
|
|||
)
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (auth Grant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
|
||||
func (g Grant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
|
||||
var authorization Authorization
|
||||
return unpacker.UnpackAny(auth.Authorization, &authorization)
|
||||
return unpacker.UnpackAny(g.Authorization, &authorization)
|
||||
}
|
||||
|
||||
// GetAuthorization returns the cached value from the Grant.Authorization if present.
|
||||
func (auth Grant) GetAuthorization() Authorization {
|
||||
authorization, ok := auth.Authorization.GetCachedValue().(Authorization)
|
||||
func (g Grant) GetAuthorization() Authorization {
|
||||
if g.Authorization == nil {
|
||||
return nil
|
||||
}
|
||||
a, ok := g.Authorization.GetCachedValue().(Authorization)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return authorization
|
||||
return a
|
||||
}
|
||||
|
||||
func (g Grant) ValidateBasic() error {
|
||||
if g.Expiration.Unix() < time.Now().Unix() {
|
||||
return sdkerrors.Wrap(ErrInvalidExpirationTime, "Time can't be in the past")
|
||||
}
|
||||
|
||||
av := g.Authorization.GetCachedValue()
|
||||
a, ok := av.(Authorization)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (Authorization)(nil), av)
|
||||
}
|
||||
return a.ValidateBasic()
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func (k Keeper) Grant(goCtx context.Context, msg *authz.MsgGrant) (*authz.MsgGra
|
|||
return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "%s doesn't exist.", t)
|
||||
}
|
||||
|
||||
err = k.SaveGrant(ctx, grantee, granter, authorization, msg.Expiration)
|
||||
err = k.SaveGrant(ctx, grantee, granter, authorization, msg.Grant.Expiration)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ var (
|
|||
//nolint:interfacer
|
||||
func NewMsgGrant(granter sdk.AccAddress, grantee sdk.AccAddress, a Authorization, expiration time.Time) (*MsgGrant, error) {
|
||||
m := &MsgGrant{
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
Expiration: expiration,
|
||||
Granter: granter.String(),
|
||||
Grantee: grantee.String(),
|
||||
Grant: Grant{Expiration: expiration},
|
||||
}
|
||||
err := m.SetAuthorization(a)
|
||||
if err != nil {
|
||||
|
@ -57,26 +57,12 @@ func (msg MsgGrant) ValidateBasic() error {
|
|||
if granter.Equals(grantee) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "granter and grantee cannot be same")
|
||||
}
|
||||
|
||||
if msg.Expiration.Unix() < time.Now().Unix() {
|
||||
return sdkerrors.Wrap(ErrInvalidExpirationTime, "Time can't be in the past")
|
||||
}
|
||||
|
||||
av := msg.Authorization.GetCachedValue()
|
||||
a, ok := av.(Authorization)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", (Authorization)(nil), av)
|
||||
}
|
||||
return a.ValidateBasic()
|
||||
return msg.Grant.ValidateBasic()
|
||||
}
|
||||
|
||||
// GetAuthorization returns the cache value from the MsgGrant.Authorization if present.
|
||||
func (msg *MsgGrant) GetAuthorization() Authorization {
|
||||
a, ok := msg.Authorization.GetCachedValue().(Authorization)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return a
|
||||
return msg.Grant.GetAuthorization()
|
||||
}
|
||||
|
||||
// SetAuthorization converts Authorization to any and adds it to MsgGrant.Authorization.
|
||||
|
@ -89,7 +75,7 @@ func (msg *MsgGrant) SetAuthorization(a Authorization) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg.Authorization = any
|
||||
msg.Grant.Authorization = any
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -108,8 +94,7 @@ func (msg MsgExec) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
|
|||
|
||||
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
|
||||
func (msg MsgGrant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
|
||||
var a Authorization
|
||||
return unpacker.UnpackAny(msg.Authorization, &a)
|
||||
return msg.Grant.UnpackInterfaces(unpacker)
|
||||
}
|
||||
|
||||
// NewMsgRevoke creates a new MsgRevoke
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
|
@ -97,3 +98,20 @@ func TestMsgGrantAuthorization(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMsgGrantGetAuthorization(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
m := authz.MsgGrant{}
|
||||
require.Nil(m.GetAuthorization())
|
||||
|
||||
g := authz.GenericAuthorization{Msg: "some_type"}
|
||||
var err error
|
||||
m.Grant.Authorization, err = cdctypes.NewAnyWithValue(&g)
|
||||
require.NoError(err)
|
||||
require.Equal(m.GetAuthorization(), &g)
|
||||
|
||||
g = authz.GenericAuthorization{Msg: "some_type2"}
|
||||
m.SetAuthorization(&g)
|
||||
require.Equal(m.GetAuthorization(), &g)
|
||||
}
|
||||
|
|
161
x/authz/tx.pb.go
161
x/authz/tx.pb.go
|
@ -6,12 +6,11 @@ package authz
|
|||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
types1 "github.com/cosmos/cosmos-sdk/types"
|
||||
types1 "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
grpc1 "github.com/gogo/protobuf/grpc"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
github_com_gogo_protobuf_types "github.com/gogo/protobuf/types"
|
||||
_ "github.com/regen-network/cosmos-proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
|
@ -20,14 +19,12 @@ import (
|
|||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
time "time"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
var _ = time.Kitchen
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
|
@ -38,10 +35,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
|||
// MsgGrant grants the provided authorization to the grantee on the granter's
|
||||
// account with the provided expiration time.
|
||||
type MsgGrant struct {
|
||||
Granter string `protobuf:"bytes,1,opt,name=granter,proto3" json:"granter,omitempty"`
|
||||
Grantee string `protobuf:"bytes,2,opt,name=grantee,proto3" json:"grantee,omitempty"`
|
||||
Authorization *types.Any `protobuf:"bytes,3,opt,name=authorization,proto3" json:"authorization,omitempty"`
|
||||
Expiration time.Time `protobuf:"bytes,4,opt,name=expiration,proto3,stdtime" json:"expiration"`
|
||||
Granter string `protobuf:"bytes,1,opt,name=granter,proto3" json:"granter,omitempty"`
|
||||
Grantee string `protobuf:"bytes,2,opt,name=grantee,proto3" json:"grantee,omitempty"`
|
||||
Grant Grant `protobuf:"bytes,3,opt,name=grant,proto3" json:"grant"`
|
||||
}
|
||||
|
||||
func (m *MsgGrant) Reset() { *m = MsgGrant{} }
|
||||
|
@ -79,7 +75,7 @@ var xxx_messageInfo_MsgGrant proto.InternalMessageInfo
|
|||
|
||||
// MsgExecResponse defines the Msg/MsgExecResponse response type.
|
||||
type MsgExecResponse struct {
|
||||
Result *types1.Result `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`
|
||||
Result *types.Result `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgExecResponse) Reset() { *m = MsgExecResponse{} }
|
||||
|
@ -123,7 +119,7 @@ type MsgExec struct {
|
|||
// Authorization Msg requests to execute. Each msg must implement Authorization interface
|
||||
// The x/authz will try to find a grant matching (msg.signers[0], grantee, MsgTypeURL(msg))
|
||||
// triple and validate it.
|
||||
Msgs []*types.Any `protobuf:"bytes,2,rep,name=msgs,proto3" json:"msgs,omitempty"`
|
||||
Msgs []*types1.Any `protobuf:"bytes,2,rep,name=msgs,proto3" json:"msgs,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgExec) Reset() { *m = MsgExec{} }
|
||||
|
@ -286,40 +282,39 @@ func init() {
|
|||
func init() { proto.RegisterFile("cosmos/authz/v1beta1/tx.proto", fileDescriptor_3ceddab7d8589ad1) }
|
||||
|
||||
var fileDescriptor_3ceddab7d8589ad1 = []byte{
|
||||
// 523 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x4d, 0x6f, 0xd3, 0x30,
|
||||
0x18, 0xae, 0xd7, 0xd2, 0xad, 0xef, 0x98, 0x60, 0xa1, 0x87, 0x2e, 0x62, 0x69, 0x14, 0xbe, 0x76,
|
||||
0xa0, 0x8e, 0x56, 0x2e, 0x5c, 0x57, 0x81, 0x90, 0x80, 0x08, 0x29, 0x1a, 0x17, 0x2e, 0x55, 0xd2,
|
||||
0x19, 0x2f, 0x6a, 0x13, 0x47, 0xb1, 0x33, 0xb5, 0xfb, 0x15, 0xfb, 0x31, 0xfb, 0x11, 0xd5, 0x4e,
|
||||
0x93, 0xb8, 0x70, 0xe2, 0xa3, 0xfd, 0x13, 0x1c, 0x51, 0x6c, 0xa7, 0xb4, 0x40, 0x87, 0xc4, 0xa9,
|
||||
0x7e, 0xfd, 0x3c, 0x7e, 0xfc, 0xf8, 0x79, 0xdf, 0x06, 0xf6, 0x07, 0x8c, 0xc7, 0x8c, 0xbb, 0x41,
|
||||
0x2e, 0x4e, 0xcf, 0xdd, 0xb3, 0xc3, 0x90, 0x88, 0xe0, 0xd0, 0x15, 0x63, 0x9c, 0x66, 0x4c, 0x30,
|
||||
0xa3, 0xa9, 0x60, 0x2c, 0x61, 0xac, 0x61, 0x73, 0x4f, 0xed, 0xf6, 0x25, 0xc7, 0xd5, 0x14, 0x59,
|
||||
0x98, 0x4d, 0xca, 0x28, 0x53, 0xfb, 0xc5, 0x4a, 0xef, 0xb6, 0x29, 0x63, 0x74, 0x44, 0x5c, 0x59,
|
||||
0x85, 0xf9, 0x47, 0x57, 0x44, 0x31, 0xe1, 0x22, 0x88, 0x53, 0x4d, 0xd8, 0xfb, 0x9d, 0x10, 0x24,
|
||||
0x13, 0x0d, 0x3d, 0xd0, 0x0e, 0xc3, 0x80, 0x13, 0x37, 0x08, 0x07, 0xd1, 0xc2, 0x65, 0x51, 0x28,
|
||||
0x92, 0xf3, 0x09, 0xc1, 0x96, 0xc7, 0xe9, 0xab, 0x2c, 0x48, 0x84, 0xd1, 0x82, 0x4d, 0x5a, 0x2c,
|
||||
0x48, 0xd6, 0x42, 0x36, 0x3a, 0x68, 0xf8, 0x65, 0xf9, 0x0b, 0x21, 0xad, 0x8d, 0x65, 0x84, 0x18,
|
||||
0x1e, 0xec, 0x14, 0x6f, 0x64, 0x59, 0x74, 0x1e, 0x88, 0x88, 0x25, 0xad, 0xaa, 0x8d, 0x0e, 0xb6,
|
||||
0xbb, 0x4d, 0xac, 0x8c, 0xe1, 0xd2, 0x18, 0x3e, 0x4a, 0x26, 0xbd, 0xdd, 0xab, 0xcb, 0xce, 0xce,
|
||||
0xd1, 0x32, 0xdd, 0x5f, 0x3d, 0x6d, 0xbc, 0x00, 0x20, 0xe3, 0x34, 0xca, 0x94, 0x56, 0x4d, 0x6a,
|
||||
0x99, 0x7f, 0x68, 0x1d, 0x97, 0x29, 0xf4, 0xb6, 0xa6, 0x5f, 0xda, 0x95, 0x8b, 0xaf, 0x6d, 0xe4,
|
||||
0x2f, 0x9d, 0x73, 0xde, 0xc0, 0x1d, 0x8f, 0xd3, 0x97, 0x63, 0x32, 0xf0, 0x09, 0x4f, 0x59, 0xc2,
|
||||
0x89, 0xf1, 0x1c, 0xea, 0x19, 0xe1, 0xf9, 0x48, 0xc8, 0xa7, 0x6d, 0x77, 0x6d, 0xac, 0xe3, 0x2f,
|
||||
0xe2, 0xc1, 0x32, 0x11, 0x1d, 0x0f, 0xf6, 0x25, 0xcf, 0xd7, 0x7c, 0x87, 0xc1, 0xa6, 0x16, 0x5b,
|
||||
0x8e, 0x01, 0xad, 0xc6, 0xf0, 0x1a, 0x6a, 0x31, 0xa7, 0xbc, 0xb5, 0x61, 0x57, 0xd7, 0xbe, 0xde,
|
||||
0xbe, 0xba, 0xec, 0xdc, 0xe7, 0x27, 0x43, 0xec, 0x71, 0xfa, 0xd4, 0x56, 0x93, 0xb1, 0x1a, 0x86,
|
||||
0xd4, 0x70, 0x0c, 0xb8, 0x5b, 0xb6, 0xa4, 0xb4, 0xef, 0x04, 0xd0, 0xf0, 0x38, 0xf5, 0xc9, 0x19,
|
||||
0x1b, 0x92, 0xff, 0xea, 0x93, 0x0d, 0xb7, 0x63, 0x4e, 0xfb, 0x62, 0x92, 0x92, 0x7e, 0x9e, 0x8d,
|
||||
0x64, 0x9b, 0x1a, 0x3e, 0xc4, 0x9c, 0x1e, 0x4f, 0x52, 0xf2, 0x3e, 0x1b, 0x39, 0xf7, 0x60, 0x77,
|
||||
0x71, 0x45, 0x79, 0x6f, 0xf7, 0x07, 0x82, 0xaa, 0xc7, 0xa9, 0xf1, 0x0e, 0x6e, 0xa9, 0x19, 0xb1,
|
||||
0xf0, 0xdf, 0x26, 0x1b, 0x97, 0x86, 0xcd, 0xc7, 0x37, 0xe3, 0x8b, 0x7e, 0xbc, 0x85, 0x9a, 0x8c,
|
||||
0x74, 0x7f, 0x2d, 0xbf, 0x80, 0xcd, 0x47, 0x37, 0xc2, 0x0b, 0x35, 0x1f, 0xea, 0x3a, 0x9b, 0xf6,
|
||||
0xda, 0x03, 0x8a, 0x60, 0x3e, 0xf9, 0x07, 0xa1, 0xd4, 0xec, 0xf5, 0xa6, 0xdf, 0xad, 0xca, 0x74,
|
||||
0x66, 0xa1, 0xeb, 0x99, 0x85, 0xbe, 0xcd, 0x2c, 0x74, 0x31, 0xb7, 0x2a, 0xd7, 0x73, 0xab, 0xf2,
|
||||
0x79, 0x6e, 0x55, 0x3e, 0x3c, 0xa4, 0x91, 0x38, 0xcd, 0x43, 0x3c, 0x60, 0xb1, 0xfe, 0x23, 0xeb,
|
||||
0x9f, 0x0e, 0x3f, 0x19, 0xba, 0x63, 0xf5, 0x5d, 0x08, 0xeb, 0x72, 0x00, 0x9e, 0xfd, 0x0c, 0x00,
|
||||
0x00, 0xff, 0xff, 0x5b, 0x69, 0x39, 0xef, 0x2e, 0x04, 0x00, 0x00,
|
||||
// 498 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcb, 0x6e, 0xd3, 0x40,
|
||||
0x14, 0xb5, 0x9b, 0x34, 0x25, 0x13, 0x24, 0xc0, 0x64, 0xe1, 0x1a, 0xea, 0x58, 0xe6, 0x95, 0x05,
|
||||
0x1d, 0xab, 0x61, 0x01, 0xdb, 0x46, 0x42, 0x48, 0x80, 0x85, 0x64, 0xc1, 0x86, 0x4d, 0x64, 0xa7,
|
||||
0xc3, 0xc4, 0x4a, 0xec, 0xb1, 0x7c, 0xc7, 0x25, 0xe9, 0x57, 0xf0, 0x31, 0x7c, 0x44, 0xc4, 0xaa,
|
||||
0x4b, 0x56, 0x08, 0x92, 0x9f, 0x60, 0x89, 0x3c, 0x8f, 0x50, 0x50, 0x5a, 0x24, 0x56, 0x99, 0x3b,
|
||||
0xe7, 0xe4, 0xdc, 0x73, 0xcf, 0xf5, 0xa0, 0x83, 0x31, 0x83, 0x8c, 0x41, 0x10, 0x57, 0x7c, 0x72,
|
||||
0x16, 0x9c, 0x1e, 0x25, 0x84, 0xc7, 0x47, 0x01, 0x9f, 0xe3, 0xa2, 0x64, 0x9c, 0x59, 0x5d, 0x09,
|
||||
0x63, 0x01, 0x63, 0x05, 0x3b, 0xfb, 0xf2, 0x76, 0x24, 0x38, 0x81, 0xa2, 0x88, 0xc2, 0xe9, 0x52,
|
||||
0x46, 0x99, 0xbc, 0xaf, 0x4f, 0xea, 0xb6, 0x47, 0x19, 0xa3, 0x33, 0x12, 0x88, 0x2a, 0xa9, 0x3e,
|
||||
0x04, 0x3c, 0xcd, 0x08, 0xf0, 0x38, 0x2b, 0x14, 0x61, 0xff, 0x6f, 0x42, 0x9c, 0x2f, 0x14, 0x74,
|
||||
0x4f, 0x39, 0x4c, 0x62, 0x20, 0x41, 0x9c, 0x8c, 0xd3, 0x8d, 0xcb, 0xba, 0x50, 0x24, 0x6f, 0xeb,
|
||||
0x18, 0xd2, 0xb5, 0x60, 0xf8, 0x1f, 0xd1, 0xb5, 0x10, 0xe8, 0x8b, 0x32, 0xce, 0xb9, 0x65, 0xa3,
|
||||
0x3d, 0x5a, 0x1f, 0x48, 0x69, 0x9b, 0x9e, 0xd9, 0x6f, 0x47, 0xba, 0xfc, 0x8d, 0x10, 0x7b, 0xe7,
|
||||
0x22, 0x42, 0xac, 0xa7, 0x68, 0x57, 0x1c, 0xed, 0x86, 0x67, 0xf6, 0x3b, 0x83, 0x3b, 0x78, 0x5b,
|
||||
0x32, 0x58, 0xe8, 0x0f, 0x9b, 0xcb, 0x6f, 0x3d, 0x23, 0x92, 0x7c, 0xff, 0x15, 0xba, 0x11, 0x02,
|
||||
0x7d, 0x3e, 0x27, 0xe3, 0x88, 0x40, 0xc1, 0x72, 0x20, 0xd6, 0x33, 0xd4, 0x2a, 0x09, 0x54, 0x33,
|
||||
0x2e, 0xda, 0x77, 0x06, 0x9e, 0x16, 0xab, 0x67, 0xc4, 0x62, 0x2c, 0x2d, 0x18, 0x09, 0x5e, 0xa4,
|
||||
0xf8, 0x3e, 0x43, 0x7b, 0x4a, 0xec, 0xa2, 0x55, 0xf3, 0x4f, 0xab, 0x2f, 0x51, 0x33, 0x03, 0x0a,
|
||||
0xf6, 0x8e, 0xd7, 0xe8, 0x77, 0x06, 0x5d, 0x2c, 0xb3, 0xc5, 0x3a, 0x5b, 0x7c, 0x9c, 0x2f, 0x86,
|
||||
0xde, 0x97, 0xcf, 0x87, 0x77, 0xe1, 0x64, 0x8a, 0x43, 0xa0, 0x8f, 0x3d, 0x39, 0xc4, 0x71, 0xc5,
|
||||
0x27, 0xac, 0x4c, 0xcf, 0x62, 0x9e, 0xb2, 0x3c, 0x12, 0x1a, 0xbe, 0x85, 0x6e, 0xea, 0xd8, 0xb4,
|
||||
0x7d, 0x3f, 0x46, 0xed, 0x10, 0x68, 0x44, 0x4e, 0xd9, 0x94, 0xfc, 0x57, 0x96, 0x1e, 0xba, 0x9e,
|
||||
0x01, 0x1d, 0xf1, 0x45, 0x41, 0x46, 0x55, 0x39, 0x13, 0x91, 0xb6, 0x23, 0x94, 0x01, 0x7d, 0xbb,
|
||||
0x28, 0xc8, 0xbb, 0x72, 0xe6, 0xdf, 0x46, 0xb7, 0x36, 0x2d, 0x74, 0xdf, 0xc1, 0x4f, 0x13, 0x35,
|
||||
0x42, 0xa0, 0xd6, 0x1b, 0xb4, 0x2b, 0xf7, 0xe8, 0x6e, 0x5f, 0x82, 0x36, 0xec, 0x3c, 0xbc, 0x1a,
|
||||
0xdf, 0xec, 0xe3, 0x35, 0x6a, 0x8a, 0x48, 0x0f, 0x2e, 0xe5, 0xd7, 0xb0, 0xf3, 0xe0, 0x4a, 0x78,
|
||||
0xa3, 0x16, 0xa1, 0x96, 0xca, 0xa6, 0x77, 0xe9, 0x1f, 0x24, 0xc1, 0x79, 0xf4, 0x0f, 0x82, 0xd6,
|
||||
0x1c, 0x0e, 0x97, 0x3f, 0x5c, 0x63, 0xb9, 0x72, 0xcd, 0xf3, 0x95, 0x6b, 0x7e, 0x5f, 0xb9, 0xe6,
|
||||
0xa7, 0xb5, 0x6b, 0x9c, 0xaf, 0x5d, 0xe3, 0xeb, 0xda, 0x35, 0xde, 0xdf, 0xa7, 0x29, 0x9f, 0x54,
|
||||
0x09, 0x1e, 0xb3, 0x4c, 0xbd, 0x46, 0xf5, 0x73, 0x08, 0x27, 0xd3, 0x60, 0x2e, 0xdf, 0x41, 0xd2,
|
||||
0x12, 0x1f, 0xc0, 0x93, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xa9, 0xb0, 0x59, 0xf3, 0x03,
|
||||
0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -508,26 +503,16 @@ func (m *MsgGrant) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Expiration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration):])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
i -= n1
|
||||
i = encodeVarintTx(dAtA, i, uint64(n1))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
if m.Authorization != nil {
|
||||
{
|
||||
size, err := m.Authorization.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintTx(dAtA, i, uint64(size))
|
||||
{
|
||||
size, err := m.Grant.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
i -= size
|
||||
i = encodeVarintTx(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
if len(m.Grantee) > 0 {
|
||||
i -= len(m.Grantee)
|
||||
copy(dAtA[i:], m.Grantee)
|
||||
|
@ -739,11 +724,7 @@ func (m *MsgGrant) Size() (n int) {
|
|||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
if m.Authorization != nil {
|
||||
l = m.Authorization.Size()
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Expiration)
|
||||
l = m.Grant.Size()
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
@ -920,7 +901,7 @@ func (m *MsgGrant) Unmarshal(dAtA []byte) error {
|
|||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Authorization", wireType)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Grant", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
|
@ -947,43 +928,7 @@ func (m *MsgGrant) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Authorization == nil {
|
||||
m.Authorization = &types.Any{}
|
||||
}
|
||||
if err := m.Authorization.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Expiration", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTx
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Expiration, dAtA[iNdEx:postIndex]); err != nil {
|
||||
if err := m.Grant.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
|
@ -1067,7 +1012,7 @@ func (m *MsgExecResponse) Unmarshal(dAtA []byte) error {
|
|||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.Result == nil {
|
||||
m.Result = &types1.Result{}
|
||||
m.Result = &types.Result{}
|
||||
}
|
||||
if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
|
@ -1184,7 +1129,7 @@ func (m *MsgExec) Unmarshal(dAtA []byte) error {
|
|||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Msgs = append(m.Msgs, &types.Any{})
|
||||
m.Msgs = append(m.Msgs, &types1.Any{})
|
||||
if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -35,14 +35,14 @@ with particular kinds of accounts.
|
|||
```
|
||||
|
||||
4. Create the keeper. Note, the `x/bank` module depends on the `x/auth` module
|
||||
and a list of blacklisted account addresses which funds are not allowed to be
|
||||
and a list of blocklisted account addresses which funds are not allowed to be
|
||||
sent to. Your application will need to define this method based your needs.
|
||||
|
||||
```go
|
||||
func NewApp(...) *App {
|
||||
// ...
|
||||
app.BankKeeper = bank.NewBaseKeeper(
|
||||
app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(),
|
||||
app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlocklistedAccAddrs(),
|
||||
)
|
||||
}
|
||||
```
|
||||
|
|
|
@ -55,6 +55,7 @@ type BaseKeeper struct {
|
|||
paramSpace paramtypes.Subspace
|
||||
}
|
||||
|
||||
// GetPaginatedTotalSupply queries for the supply, ignoring 0 coins, with a given pagination
|
||||
func (k BaseKeeper) GetPaginatedTotalSupply(ctx sdk.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
supplyStore := prefix.NewStore(store, types.SupplyKey)
|
||||
|
@ -213,7 +214,8 @@ func (k BaseKeeper) GetSupply(ctx sdk.Context, denom string) sdk.Coin {
|
|||
}
|
||||
}
|
||||
|
||||
// GetDenomMetaData retrieves the denomination metadata
|
||||
// GetDenomMetaData retrieves the denomination metadata. returns the metadata and true if the denom exists,
|
||||
// false otherwise.
|
||||
func (k BaseKeeper) GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store = prefix.NewStore(store, types.DenomMetadataKey(denom))
|
||||
|
@ -427,6 +429,7 @@ func (k BaseKeeper) BurnCoins(ctx sdk.Context, moduleName string, amounts sdk.Co
|
|||
return nil
|
||||
}
|
||||
|
||||
// setSupply sets the supply for the given coin
|
||||
func (k BaseKeeper) setSupply(ctx sdk.Context, coin sdk.Coin) {
|
||||
intBytes, err := coin.Amount.Marshal()
|
||||
if err != nil {
|
||||
|
@ -444,6 +447,7 @@ func (k BaseKeeper) setSupply(ctx sdk.Context, coin sdk.Coin) {
|
|||
}
|
||||
}
|
||||
|
||||
// trackDelegation tracks the delegation of the given account if it is a vesting account
|
||||
func (k BaseKeeper) trackDelegation(ctx sdk.Context, addr sdk.AccAddress, balance, amt sdk.Coins) error {
|
||||
acc := k.ak.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
|
@ -460,6 +464,7 @@ func (k BaseKeeper) trackDelegation(ctx sdk.Context, addr sdk.AccAddress, balanc
|
|||
return nil
|
||||
}
|
||||
|
||||
// trackUndelegation trakcs undelegation of the given account if it is a vesting account
|
||||
func (k BaseKeeper) trackUndelegation(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) error {
|
||||
acc := k.ak.GetAccount(ctx, addr)
|
||||
if acc == nil {
|
||||
|
@ -476,6 +481,9 @@ func (k BaseKeeper) trackUndelegation(ctx sdk.Context, addr sdk.AccAddress, amt
|
|||
return nil
|
||||
}
|
||||
|
||||
// IterateTotalSupply iterates over the total supply calling the given cb (callback) function
|
||||
// with the balance of each coin.
|
||||
// The iteration stops if the callback returns true.
|
||||
func (k BaseViewKeeper) IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bool) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
supplyStore := prefix.NewStore(store, types.SupplyKey)
|
||||
|
|
|
@ -111,7 +111,7 @@ func (suite *IntegrationTestSuite) SetupTest() {
|
|||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestSupply() {
|
||||
_, ctx := suite.app, suite.ctx
|
||||
ctx := suite.ctx
|
||||
|
||||
require := suite.Require()
|
||||
|
||||
|
@ -119,7 +119,7 @@ func (suite *IntegrationTestSuite) TestSupply() {
|
|||
authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool))
|
||||
|
||||
initialPower := int64(100)
|
||||
initTokens := suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, initialPower)
|
||||
initTokens := suite.app.StakingKeeper.TokensFromConsensusPower(ctx, initialPower)
|
||||
totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens))
|
||||
|
||||
// set burnerAcc balance
|
||||
|
@ -140,7 +140,7 @@ func (suite *IntegrationTestSuite) TestSupply() {
|
|||
require.Equal(total.String(), "")
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blacklist() {
|
||||
func (suite *IntegrationTestSuite) TestSendCoinsFromModuleToAccount_Blocklist() {
|
||||
ctx := suite.ctx
|
||||
|
||||
// add module accounts to supply keeper
|
||||
|
@ -484,11 +484,11 @@ func (suite *IntegrationTestSuite) TestSendEnabled() {
|
|||
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))
|
||||
suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, barCoin))
|
||||
suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, bondCoin))
|
||||
|
||||
// Both coins should be send enabled.
|
||||
err := app.BankKeeper.SendEnabledCoins(ctx, fooCoin, bondCoin)
|
||||
err := app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin, bondCoin)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Set default send_enabled to !enabled, add a foodenom that overrides default as enabled
|
||||
|
@ -497,20 +497,20 @@ func (suite *IntegrationTestSuite) TestSendEnabled() {
|
|||
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))
|
||||
suite.Require().Equal(enabled, app.BankKeeper.IsSendEnabledCoin(ctx, fooCoin))
|
||||
suite.Require().Equal(!enabled, app.BankKeeper.IsSendEnabledCoin(ctx, barCoin))
|
||||
suite.Require().Equal(!enabled, app.BankKeeper.IsSendEnabledCoin(ctx, bondCoin))
|
||||
|
||||
// Foo coin should be send enabled.
|
||||
err = app.BankKeeper.SendEnabledCoins(ctx, fooCoin)
|
||||
err = app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
// Expect an error when one coin is not send enabled.
|
||||
err = app.BankKeeper.SendEnabledCoins(ctx, fooCoin, bondCoin)
|
||||
err = app.BankKeeper.IsSendEnabledCoins(ctx, fooCoin, bondCoin)
|
||||
suite.Require().Error(err)
|
||||
|
||||
// Expect an error when all coins are not send enabled.
|
||||
err = app.BankKeeper.SendEnabledCoins(ctx, bondCoin, barCoin)
|
||||
err = app.BankKeeper.IsSendEnabledCoins(ctx, bondCoin, barCoin)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
|
||||
|
@ -538,12 +538,9 @@ func (suite *IntegrationTestSuite) TestMsgSendEvents() {
|
|||
|
||||
app.AccountKeeper.SetAccount(ctx, acc)
|
||||
newCoins := sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
|
||||
suite.Require().NoError(simapp.FundAccount(app, ctx, addr, newCoins))
|
||||
|
||||
suite.Require().Error(app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins))
|
||||
|
||||
events := ctx.EventManager().ABCIEvents()
|
||||
suite.Require().Equal(2, len(events))
|
||||
|
||||
suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins))
|
||||
event1 := sdk.Event{
|
||||
Type: types.EventTypeTransfer,
|
||||
Attributes: []abci.EventAttribute{},
|
||||
|
@ -570,17 +567,9 @@ func (suite *IntegrationTestSuite) TestMsgSendEvents() {
|
|||
abci.EventAttribute{Key: []byte(types.AttributeKeySender), Value: []byte(addr.String())},
|
||||
)
|
||||
|
||||
suite.Require().Equal(abci.Event(event1), events[0])
|
||||
suite.Require().Equal(abci.Event(event2), events[1])
|
||||
|
||||
suite.Require().NoError(simapp.FundAccount(app, ctx, addr, sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))))
|
||||
newCoins = sdk.NewCoins(sdk.NewInt64Coin(fooDenom, 50))
|
||||
|
||||
suite.Require().NoError(app.BankKeeper.SendCoins(ctx, addr, addr2, newCoins))
|
||||
|
||||
// events are shifted due to the funding account events
|
||||
events = ctx.EventManager().ABCIEvents()
|
||||
suite.Require().Equal(12, len(events))
|
||||
events := ctx.EventManager().ABCIEvents()
|
||||
suite.Require().Equal(10, len(events))
|
||||
suite.Require().Equal(abci.Event(event1), events[8])
|
||||
suite.Require().Equal(abci.Event(event2), events[9])
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var _ types.MsgServer = msgServer{}
|
|||
func (k msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.MsgSendResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
if err := k.SendEnabledCoins(ctx, msg.Amount...); err != nil {
|
||||
if err := k.IsSendEnabledCoins(ctx, msg.Amount...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ func (k msgServer) MultiSend(goCtx context.Context, msg *types.MsgMultiSend) (*t
|
|||
|
||||
// NOTE: totalIn == totalOut should already have been checked
|
||||
for _, in := range msg.Inputs {
|
||||
if err := k.SendEnabledCoins(ctx, in.Coins...); err != nil {
|
||||
if err := k.IsSendEnabledCoins(ctx, in.Coins...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ type SendKeeper interface {
|
|||
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
|
||||
IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool
|
||||
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
|
||||
|
||||
BlockedAddr(addr sdk.AccAddress) bool
|
||||
}
|
||||
|
@ -131,19 +131,6 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input,
|
|||
// SendCoins transfers amt coins from a sending account to a receiving account.
|
||||
// An error is returned upon failure.
|
||||
func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error {
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeTransfer,
|
||||
sdk.NewAttribute(types.AttributeKeyRecipient, toAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
|
||||
),
|
||||
})
|
||||
|
||||
err := k.subUnlockedCoins(ctx, fromAddr, amt)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -164,6 +151,19 @@ func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAd
|
|||
k.ak.SetAccount(ctx, k.ak.NewAccountWithAddress(ctx, toAddr))
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeTransfer,
|
||||
sdk.NewAttribute(types.AttributeKeyRecipient, toAddr.String()),
|
||||
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, amt.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(types.AttributeKeySender, fromAddr.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -277,20 +277,20 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance
|
|||
return nil
|
||||
}
|
||||
|
||||
// SendEnabledCoins checks the coins provide and returns an ErrSendDisabled if
|
||||
// IsSendEnabledCoins 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 {
|
||||
func (k BaseSendKeeper) IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error {
|
||||
for _, coin := range coins {
|
||||
if !k.SendEnabledCoin(ctx, coin) {
|
||||
if !k.IsSendEnabledCoin(ctx, coin) {
|
||||
return sdkerrors.Wrapf(types.ErrSendDisabled, "%s transfers are currently disabled", coin.Denom)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SendEnabledCoin returns the current SendEnabled status of the provided coin's denom
|
||||
func (k BaseSendKeeper) SendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool {
|
||||
// IsSendEnabledCoin returns the current SendEnabled status of the provided coin's denom
|
||||
func (k BaseSendKeeper) IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool {
|
||||
return k.GetParams(ctx).SendEnabledDenom(coin.Denom)
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange {
|
|||
}
|
||||
|
||||
// RegisterStoreDecoder registers a decoder for supply module's types
|
||||
func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {}
|
||||
func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {}
|
||||
|
||||
// WeightedOperations returns the all the gov module operations with their respective weights.
|
||||
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
|
||||
|
|
|
@ -61,7 +61,7 @@ func SimulateMsgSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Operatio
|
|||
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 {
|
||||
if err := bk.IsSendEnabledCoins(ctx, coins...); err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgSend, err.Error()), nil, nil
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ func SimulateMsgMultiSend(ak types.AccountKeeper, bk keeper.Keeper) simtypes.Ope
|
|||
}
|
||||
|
||||
// Check send_enabled status of each sent coin denom
|
||||
if err := bk.SendEnabledCoins(ctx, totalSentCoins...); err != nil {
|
||||
if err := bk.IsSendEnabledCoins(ctx, totalSentCoins...); err != nil {
|
||||
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgMultiSend, err.Error()), nil, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -12,14 +12,14 @@ require.
|
|||
Best practices dictate careful review of `bank` module code to ensure that
|
||||
permissions are limited in the way that you expect.
|
||||
|
||||
## Blacklisting Addresses
|
||||
## Blocklisting Addresses
|
||||
|
||||
The `x/bank` module accepts a map of addresses that are considered blocklisted
|
||||
from directly and explicitly receiving funds through means such as `MsgSend` and
|
||||
`MsgMultiSend` and direct API calls like `SendCoinsFromModuleToAccount`.
|
||||
|
||||
Typically, these addresses are module accounts. If these addresses receive funds
|
||||
outside of the expected rules of the state machine, invariants are likely to be
|
||||
outside the expected rules of the state machine, invariants are likely to be
|
||||
broken and could result in a halted network.
|
||||
|
||||
By providing the `x/bank` module with a blocklisted set of addresses, an error occurs for the operation if a user or client attempts to directly or indirectly send funds to a blocklisted account, for example, by using [IBC](http://docs.cosmos.network/master/ibc/).
|
||||
|
@ -58,32 +58,30 @@ The base keeper provides full-permission access: the ability to arbitrary modify
|
|||
// Keeper defines a module interface that facilitates the transfer of coins
|
||||
// between accounts.
|
||||
type Keeper interface {
|
||||
SendKeeper
|
||||
|
||||
InitGenesis(sdk.Context, *types.GenesisState)
|
||||
ExportGenesis(sdk.Context) *types.GenesisState
|
||||
|
||||
GetSupply(ctx sdk.Context) exported.SupplyI
|
||||
SetSupply(ctx sdk.Context, supply exported.SupplyI)
|
||||
|
||||
GetDenomMetaData(ctx sdk.Context, denom string) types.Metadata
|
||||
SetDenomMetaData(ctx sdk.Context, denomMetaData types.Metadata)
|
||||
IterateAllDenomMetaData(ctx sdk.Context, cb func(types.Metadata) bool)
|
||||
|
||||
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
|
||||
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
|
||||
DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
|
||||
UndelegateCoinsFromModuleToAccount(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
|
||||
|
||||
DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
MarshalSupply(supplyI exported.SupplyI) ([]byte, error)
|
||||
UnmarshalSupply(bz []byte) (exported.SupplyI, error)
|
||||
|
||||
types.QueryServer
|
||||
SendKeeper
|
||||
|
||||
InitGenesis(sdk.Context, *types.GenesisState)
|
||||
ExportGenesis(sdk.Context) *types.GenesisState
|
||||
|
||||
GetSupply(ctx sdk.Context, denom string) sdk.Coin
|
||||
GetPaginatedTotalSupply(ctx sdk.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error)
|
||||
IterateTotalSupply(ctx sdk.Context, cb func(sdk.Coin) bool)
|
||||
GetDenomMetaData(ctx sdk.Context, denom string) (types.Metadata, bool)
|
||||
SetDenomMetaData(ctx sdk.Context, denomMetaData types.Metadata)
|
||||
IterateAllDenomMetaData(ctx sdk.Context, cb func(types.Metadata) bool)
|
||||
|
||||
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
|
||||
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
|
||||
DelegateCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
|
||||
UndelegateCoinsFromModuleToAccount(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
|
||||
|
||||
DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
|
||||
types.QueryServer
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -96,18 +94,18 @@ accounts. The send keeper does not alter the total supply (mint or burn coins).
|
|||
// SendKeeper defines a module interface that facilitates the transfer of coins
|
||||
// between accounts without the possibility of creating coins.
|
||||
type SendKeeper interface {
|
||||
ViewKeeper
|
||||
|
||||
InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
|
||||
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
|
||||
ViewKeeper
|
||||
|
||||
InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error
|
||||
SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error
|
||||
|
||||
GetParams(ctx sdk.Context) types.Params
|
||||
SetParams(ctx sdk.Context, params types.Params)
|
||||
|
||||
IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool
|
||||
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
|
||||
|
||||
BlockedAddr(addr sdk.AccAddress) bool
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -119,16 +117,16 @@ The view keeper provides read-only access to account balances. The view keeper d
|
|||
// ViewKeeper defines a module interface that facilitates read only access to
|
||||
// account balances.
|
||||
type ViewKeeper interface {
|
||||
ValidateBalance(ctx sdk.Context, addr sdk.AccAddress) error
|
||||
HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool
|
||||
|
||||
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
GetAccountsBalances(ctx sdk.Context) []types.Balance
|
||||
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
||||
LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
|
||||
IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool))
|
||||
IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool))
|
||||
ValidateBalance(ctx sdk.Context, addr sdk.AccAddress) error
|
||||
HasBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coin) bool
|
||||
|
||||
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
GetAccountsBalances(ctx sdk.Context) []types.Balance
|
||||
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
|
||||
LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
|
||||
IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool))
|
||||
IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool))
|
||||
}
|
||||
```
|
||||
|
|
|
@ -6,20 +6,21 @@ order: 3
|
|||
|
||||
## MsgSend
|
||||
|
||||
Send coins from one address to another.
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28
|
||||
|
||||
`handleMsgSend` just runs `inputOutputCoins`.
|
||||
The message will fail under the following conditions:
|
||||
- The coins do not have sending enabled
|
||||
- The `to` address is restricted
|
||||
|
||||
```go
|
||||
handleMsgSend(msg MsgSend)
|
||||
inputSum = 0
|
||||
for input in inputs
|
||||
inputSum += input.Amount
|
||||
outputSum = 0
|
||||
for output in outputs
|
||||
outputSum += output.Amount
|
||||
if inputSum != outputSum:
|
||||
fail with "input/output amount mismatch"
|
||||
## MsgMultiSend
|
||||
|
||||
Send coins from and to a series of different address. If any of the receiving addresses do not correspond to an existing account, a new account is created.
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L33-L39
|
||||
|
||||
The message will fail under the following conditions:
|
||||
- Any of the coins do not have sending enabled
|
||||
- Any of the `to` addresses are restricted
|
||||
- Any of the coins are locked
|
||||
- The inputs and outputs do not correctly correspond to one another
|
||||
|
||||
return inputOutputCoins(msg.Inputs, msg.Outputs)
|
||||
```
|
||||
|
|
|
@ -426,44 +426,44 @@ func init() {
|
|||
func init() { proto.RegisterFile("cosmos/bank/v1beta1/bank.proto", fileDescriptor_dd052eee12edf988) }
|
||||
|
||||
var fileDescriptor_dd052eee12edf988 = []byte{
|
||||
// 587 bytes of a gzipped FileDescriptorProto
|
||||
// 592 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x54, 0xbf, 0x6f, 0xd3, 0x40,
|
||||
0x14, 0xf6, 0x35, 0x8d, 0x49, 0x2f, 0xb0, 0x1c, 0x15, 0x72, 0x2b, 0x61, 0x1b, 0x4b, 0x48, 0x29,
|
||||
0xa2, 0x0e, 0x05, 0xb1, 0x64, 0x41, 0x4a, 0x41, 0xa8, 0x03, 0x02, 0xb9, 0x42, 0x48, 0x30, 0x44,
|
||||
0xe7, 0xdc, 0x35, 0x58, 0xb5, 0xef, 0xac, 0xdc, 0x19, 0xd5, 0xff, 0x01, 0x13, 0x30, 0x32, 0x76,
|
||||
0x66, 0x62, 0xe0, 0x7f, 0xa0, 0x63, 0x05, 0x0b, 0x53, 0x40, 0xc9, 0xc2, 0xdc, 0xbf, 0x00, 0xdd,
|
||||
0x9d, 0xf3, 0xa3, 0x52, 0x40, 0x0c, 0x0c, 0x4c, 0x79, 0xdf, 0x7b, 0xdf, 0xfb, 0xde, 0xd3, 0x77,
|
||||
0xcf, 0x81, 0x6e, 0x9f, 0x8b, 0x8c, 0x8b, 0x76, 0x8c, 0xd9, 0x61, 0xfb, 0xd5, 0x4e, 0x4c, 0x25,
|
||||
0xde, 0xd1, 0x20, 0xcc, 0x87, 0x5c, 0x72, 0x74, 0xd9, 0xd4, 0x43, 0x9d, 0xaa, 0xea, 0x9b, 0xeb,
|
||||
0x03, 0x3e, 0xe0, 0xba, 0xde, 0x56, 0x91, 0xa1, 0x6e, 0x6e, 0x18, 0x6a, 0xcf, 0x14, 0xaa, 0x3e,
|
||||
0x53, 0x9a, 0x4f, 0x11, 0x74, 0x36, 0xa5, 0xcf, 0x13, 0x66, 0xea, 0xc1, 0x57, 0x00, 0xed, 0x27,
|
||||
0x78, 0x88, 0x33, 0x81, 0x0e, 0xe0, 0x45, 0x41, 0x19, 0xe9, 0x51, 0x86, 0xe3, 0x94, 0x12, 0x07,
|
||||
0xf8, 0xb5, 0x56, 0xf3, 0xb6, 0x1f, 0x2e, 0xd9, 0x23, 0xdc, 0xa7, 0x8c, 0x3c, 0x30, 0xbc, 0xee,
|
||||
0xb5, 0xb3, 0x91, 0x77, 0xb5, 0xc4, 0x59, 0xda, 0x09, 0x16, 0xfb, 0x6f, 0xf2, 0x2c, 0x91, 0x34,
|
||||
0xcb, 0x65, 0x19, 0x44, 0x4d, 0x31, 0xe7, 0xa3, 0x17, 0x70, 0x9d, 0xd0, 0x03, 0x5c, 0xa4, 0xb2,
|
||||
0x77, 0x6e, 0xde, 0x8a, 0x0f, 0x5a, 0x8d, 0xee, 0xd6, 0xd9, 0xc8, 0xbb, 0x6e, 0xd4, 0x96, 0xb1,
|
||||
0x16, 0x55, 0x51, 0x45, 0x58, 0x58, 0xa6, 0xb3, 0xfa, 0xfe, 0xd8, 0xb3, 0x82, 0x87, 0xb0, 0xb9,
|
||||
0x90, 0x44, 0xeb, 0xb0, 0x4e, 0x28, 0xe3, 0x99, 0x03, 0x7c, 0xd0, 0x5a, 0x8b, 0x0c, 0x40, 0x0e,
|
||||
0xbc, 0x70, 0x6e, 0x74, 0x34, 0x85, 0x9d, 0x86, 0x12, 0xf9, 0x79, 0xec, 0x81, 0xe0, 0x0d, 0x80,
|
||||
0xf5, 0x3d, 0x96, 0x17, 0x52, 0xb1, 0x31, 0x21, 0x43, 0x2a, 0x44, 0xa5, 0x32, 0x85, 0x08, 0xc3,
|
||||
0xba, 0x32, 0x54, 0x38, 0x2b, 0xda, 0xb0, 0x8d, 0xb9, 0x61, 0x82, 0xce, 0x0c, 0xdb, 0xe5, 0x09,
|
||||
0xeb, 0xde, 0x3a, 0x19, 0x79, 0xd6, 0x87, 0xef, 0x5e, 0x6b, 0x90, 0xc8, 0x97, 0x45, 0x1c, 0xf6,
|
||||
0x79, 0x56, 0xbd, 0x56, 0xf5, 0xb3, 0x2d, 0xc8, 0x61, 0x5b, 0x96, 0x39, 0x15, 0xba, 0x41, 0x44,
|
||||
0x46, 0xb9, 0xd3, 0x78, 0x6d, 0x16, 0xb2, 0x82, 0xb7, 0x00, 0xda, 0x8f, 0x0b, 0xf9, 0x1f, 0x6d,
|
||||
0xf4, 0x11, 0x40, 0x7b, 0xbf, 0xc8, 0xf3, 0xb4, 0x54, 0x73, 0x25, 0x97, 0x38, 0xad, 0x4e, 0xe7,
|
||||
0xdf, 0xce, 0xd5, 0xca, 0x9d, 0xdd, 0x6a, 0x2e, 0xf8, 0xf2, 0x69, 0xfb, 0xee, 0x8d, 0x3f, 0x76,
|
||||
0x1f, 0x99, 0x4f, 0x8b, 0x1e, 0xe5, 0x7c, 0x28, 0x29, 0x09, 0xcd, 0x92, 0x7b, 0x0e, 0x08, 0x9e,
|
||||
0xc1, 0xb5, 0xfb, 0xea, 0x04, 0x9e, 0xb2, 0x44, 0xfe, 0xe6, 0x38, 0x36, 0x61, 0x43, 0x35, 0x32,
|
||||
0xca, 0xa4, 0xbe, 0x8e, 0x4b, 0xd1, 0x0c, 0x6b, 0xe3, 0xd3, 0x04, 0x0b, 0x2a, 0x9c, 0x9a, 0x5f,
|
||||
0xd3, 0xc6, 0x1b, 0x18, 0x7c, 0x06, 0xb0, 0xf1, 0x88, 0x4a, 0x4c, 0xb0, 0xc4, 0xc8, 0x87, 0x4d,
|
||||
0x42, 0x45, 0x7f, 0x98, 0xe4, 0x32, 0xe1, 0xac, 0x92, 0x5f, 0x4c, 0xa1, 0x7b, 0x8a, 0xc1, 0x78,
|
||||
0xd6, 0x2b, 0x58, 0x22, 0xa7, 0xaf, 0xe5, 0x2e, 0xfd, 0xe0, 0x66, 0xfb, 0x46, 0x90, 0x4c, 0x43,
|
||||
0x81, 0x10, 0x5c, 0x55, 0xde, 0x3a, 0x35, 0xad, 0xad, 0x63, 0xb5, 0x1d, 0x49, 0x44, 0x9e, 0xe2,
|
||||
0xd2, 0x59, 0x35, 0x67, 0x51, 0x41, 0xc5, 0x66, 0x38, 0xa3, 0x4e, 0xdd, 0xb0, 0x55, 0x8c, 0xae,
|
||||
0x40, 0x5b, 0x94, 0x59, 0xcc, 0x53, 0xc7, 0xd6, 0xd9, 0x0a, 0x75, 0x77, 0x4f, 0xc6, 0x2e, 0x38,
|
||||
0x1d, 0xbb, 0xe0, 0xc7, 0xd8, 0x05, 0xef, 0x26, 0xae, 0x75, 0x3a, 0x71, 0xad, 0x6f, 0x13, 0xd7,
|
||||
0x7a, 0xbe, 0xf5, 0x37, 0xa6, 0xeb, 0x97, 0x8b, 0x6d, 0xfd, 0x1f, 0x73, 0xe7, 0x57, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xe7, 0x1c, 0xc1, 0x93, 0xeb, 0x04, 0x00, 0x00,
|
||||
0x14, 0xf6, 0x35, 0x8d, 0x49, 0x2f, 0xb0, 0x1c, 0x15, 0x72, 0x23, 0x61, 0x1b, 0x4b, 0x48, 0x29,
|
||||
0xa2, 0x4e, 0x0a, 0x0c, 0x28, 0x0b, 0x52, 0xca, 0x0f, 0x75, 0x40, 0x20, 0x57, 0x08, 0x09, 0x86,
|
||||
0xe8, 0x9c, 0xbb, 0x06, 0xab, 0xf6, 0x9d, 0x95, 0x3b, 0x57, 0xf5, 0x7f, 0xc0, 0x04, 0x8c, 0x8c,
|
||||
0x9d, 0x59, 0xe1, 0x7f, 0xa0, 0x63, 0x05, 0x0b, 0x53, 0x40, 0xc9, 0xc2, 0xdc, 0xbf, 0x00, 0xf9,
|
||||
0xce, 0xf9, 0x51, 0x29, 0x20, 0x06, 0x06, 0xa6, 0xbc, 0xef, 0xbd, 0xef, 0x7d, 0xef, 0xe9, 0xbb,
|
||||
0xe7, 0x40, 0xbb, 0xcf, 0x45, 0xc2, 0x45, 0x2b, 0xc4, 0xec, 0xa0, 0x75, 0xb8, 0x1d, 0x52, 0x89,
|
||||
0xb7, 0x15, 0xf0, 0xd3, 0x21, 0x97, 0x1c, 0x5d, 0xd6, 0x75, 0x5f, 0xa5, 0xca, 0x7a, 0x63, 0x7d,
|
||||
0xc0, 0x07, 0x5c, 0xd5, 0x5b, 0x45, 0xa4, 0xa9, 0x8d, 0x0d, 0x4d, 0xed, 0xe9, 0x42, 0xd9, 0xa7,
|
||||
0x4b, 0xf3, 0x29, 0x82, 0xce, 0xa6, 0xf4, 0x79, 0xc4, 0x74, 0xdd, 0xfb, 0x0a, 0xa0, 0xf9, 0x14,
|
||||
0x0f, 0x71, 0x22, 0xd0, 0x3e, 0xbc, 0x28, 0x28, 0x23, 0x3d, 0xca, 0x70, 0x18, 0x53, 0x62, 0x01,
|
||||
0xb7, 0xd2, 0xac, 0xdf, 0x72, 0xfd, 0x25, 0x7b, 0xf8, 0x7b, 0x94, 0x91, 0x07, 0x9a, 0xd7, 0xbd,
|
||||
0x76, 0x36, 0x72, 0xae, 0xe6, 0x38, 0x89, 0x3b, 0xde, 0x62, 0xff, 0x4d, 0x9e, 0x44, 0x92, 0x26,
|
||||
0xa9, 0xcc, 0xbd, 0xa0, 0x2e, 0xe6, 0x7c, 0xf4, 0x12, 0xae, 0x13, 0xba, 0x8f, 0xb3, 0x58, 0xf6,
|
||||
0xce, 0xcd, 0x5b, 0x71, 0x41, 0xb3, 0xd6, 0xdd, 0x3c, 0x1b, 0x39, 0xd7, 0xb5, 0xda, 0x32, 0xd6,
|
||||
0xa2, 0x2a, 0x2a, 0x09, 0x0b, 0xcb, 0x74, 0x56, 0xdf, 0x1f, 0x3b, 0x86, 0xf7, 0x08, 0xd6, 0x17,
|
||||
0x92, 0x68, 0x1d, 0x56, 0x09, 0x65, 0x3c, 0xb1, 0x80, 0x0b, 0x9a, 0x6b, 0x81, 0x06, 0xc8, 0x82,
|
||||
0x17, 0xce, 0x8d, 0x0e, 0xa6, 0xb0, 0x53, 0x2b, 0x44, 0x7e, 0x1e, 0x3b, 0xc0, 0x7b, 0x03, 0x60,
|
||||
0x75, 0x97, 0xa5, 0x99, 0x2c, 0xd8, 0x98, 0x90, 0x21, 0x15, 0xa2, 0x54, 0x99, 0x42, 0x84, 0x61,
|
||||
0xb5, 0x30, 0x54, 0x58, 0x2b, 0xca, 0xb0, 0x8d, 0xb9, 0x61, 0x82, 0xce, 0x0c, 0xdb, 0xe1, 0x11,
|
||||
0xeb, 0xb6, 0x4f, 0x46, 0x8e, 0xf1, 0xe1, 0xbb, 0xd3, 0x1c, 0x44, 0xf2, 0x55, 0x16, 0xfa, 0x7d,
|
||||
0x9e, 0x94, 0xaf, 0x55, 0xfe, 0x6c, 0x09, 0x72, 0xd0, 0x92, 0x79, 0x4a, 0x85, 0x6a, 0x10, 0x81,
|
||||
0x56, 0xee, 0xd4, 0x5e, 0xeb, 0x85, 0x0c, 0xef, 0x2d, 0x80, 0xe6, 0x93, 0x4c, 0xfe, 0x47, 0x1b,
|
||||
0x7d, 0x04, 0xd0, 0xdc, 0xcb, 0xd2, 0x34, 0xce, 0x8b, 0xb9, 0x92, 0x4b, 0x1c, 0x97, 0xa7, 0xf3,
|
||||
0x6f, 0xe7, 0x2a, 0xe5, 0xce, 0xc3, 0x72, 0x2e, 0xf8, 0xf2, 0x69, 0xeb, 0xee, 0x8d, 0x3f, 0x76,
|
||||
0x1f, 0xe9, 0x4f, 0x2b, 0xa6, 0x03, 0xdc, 0xcf, 0x5b, 0x87, 0xed, 0x3b, 0x6d, 0x5f, 0xef, 0xb9,
|
||||
0x6b, 0x01, 0xef, 0x39, 0x5c, 0xbb, 0x5f, 0x5c, 0xc1, 0x33, 0x16, 0xc9, 0xdf, 0xdc, 0x47, 0x03,
|
||||
0xd6, 0xe8, 0x51, 0xca, 0x19, 0x65, 0x52, 0x1d, 0xc8, 0xa5, 0x60, 0x86, 0x95, 0xf7, 0x71, 0x84,
|
||||
0x05, 0x15, 0x56, 0xc5, 0xad, 0x28, 0xef, 0x35, 0xf4, 0x3e, 0x03, 0x58, 0x7b, 0x4c, 0x25, 0x26,
|
||||
0x58, 0x62, 0xe4, 0xc2, 0x3a, 0xa1, 0xa2, 0x3f, 0x8c, 0x52, 0x19, 0x71, 0x56, 0xca, 0x2f, 0xa6,
|
||||
0xd0, 0xbd, 0x82, 0xc1, 0x78, 0xd2, 0xcb, 0x58, 0x24, 0xa7, 0x0f, 0x66, 0x2f, 0xfd, 0xe6, 0x66,
|
||||
0xfb, 0x06, 0x90, 0x4c, 0x43, 0x81, 0x10, 0x5c, 0x2d, 0xec, 0xb5, 0x2a, 0x4a, 0x5b, 0xc5, 0xc5,
|
||||
0x76, 0x24, 0x12, 0x69, 0x8c, 0x73, 0x6b, 0x55, 0x5f, 0x46, 0x09, 0x0b, 0x36, 0xc3, 0x09, 0xb5,
|
||||
0xaa, 0x9a, 0x5d, 0xc4, 0xe8, 0x0a, 0x34, 0x45, 0x9e, 0x84, 0x3c, 0xb6, 0x4c, 0x95, 0x2d, 0x51,
|
||||
0x77, 0xe7, 0x64, 0x6c, 0x83, 0xd3, 0xb1, 0x0d, 0x7e, 0x8c, 0x6d, 0xf0, 0x6e, 0x62, 0x1b, 0xa7,
|
||||
0x13, 0xdb, 0xf8, 0x36, 0xb1, 0x8d, 0x17, 0x9b, 0x7f, 0xe3, 0xbb, 0x7a, 0xbc, 0xd0, 0x54, 0x7f,
|
||||
0x33, 0xb7, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x03, 0xbf, 0xe9, 0xee, 0x04, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (this *SendEnabled) Equal(that interface{}) bool {
|
||||
|
|
|
@ -21,8 +21,8 @@ const (
|
|||
|
||||
// KVStore keys
|
||||
var (
|
||||
// BalancesPrefix is the for the account balances store. We use a byte
|
||||
// (instead of say `[]]byte("balances")` to save some disk space).
|
||||
// BalancesPrefix is the prefix for the account balances store. We use a byte
|
||||
// (instead of `[]byte("balances")` to save some disk space).
|
||||
BalancesPrefix = []byte{0x02}
|
||||
SupplyKey = []byte{0x00}
|
||||
DenomMetadataPrefix = []byte{0x1}
|
||||
|
@ -35,7 +35,7 @@ func DenomMetadataKey(denom string) []byte {
|
|||
}
|
||||
|
||||
// AddressFromBalancesStore returns an account address from a balances prefix
|
||||
// store. The key must not contain the perfix BalancesPrefix as the prefix store
|
||||
// store. The key must not contain the prefix BalancesPrefix as the prefix store
|
||||
// iterator discards the actual prefix.
|
||||
//
|
||||
// If invalid key is passed, AddressFromBalancesStore returns ErrInvalidKey.
|
||||
|
|
|
@ -660,7 +660,6 @@ $ %s query staking historical-info 5
|
|||
|
||||
params := &types.QueryHistoricalInfoRequest{Height: height}
|
||||
res, err := queryClient.HistoricalInfo(cmd.Context(), params)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryValidator() {
|
|||
},
|
||||
{
|
||||
"happy case",
|
||||
[]string{fmt.Sprintf("%s", val.ValAddress), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
[]string{val.ValAddress.String(), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryDelegations() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryDelegationsTo() {
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryValidatorDelegations() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := []struct {
|
||||
|
@ -755,7 +755,7 @@ func (s *IntegrationTestSuite) TestGetCmdQueryRedelegation() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryRedelegationsFrom() {
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryValidatorRedelegations() {
|
||||
val := s.network.Validators[0]
|
||||
val2 := s.network.Validators[1]
|
||||
|
||||
|
@ -925,7 +925,7 @@ not_bonded_tokens: "0"`, cli.DefaultTokens.Mul(sdk.NewInt(2)).String()),
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewCmdEditValidator() {
|
||||
func (s *IntegrationTestSuite) TestNewEditValidatorCmd() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
details := "bio"
|
||||
|
@ -1041,7 +1041,7 @@ func (s *IntegrationTestSuite) TestNewCmdEditValidator() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewCmdDelegate() {
|
||||
func (s *IntegrationTestSuite) TestNewDelegateCmd() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic("NewAccount", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
||||
|
@ -1123,7 +1123,7 @@ func (s *IntegrationTestSuite) TestNewCmdDelegate() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewCmdRedelegate() {
|
||||
func (s *IntegrationTestSuite) TestNewRedelegateCmd() {
|
||||
val := s.network.Validators[0]
|
||||
val2 := s.network.Validators[1]
|
||||
|
||||
|
@ -1209,7 +1209,7 @@ func (s *IntegrationTestSuite) TestNewCmdRedelegate() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestNewCmdUnbond() {
|
||||
func (s *IntegrationTestSuite) TestNewUnbondCmd() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := []struct {
|
||||
|
|
|
@ -384,6 +384,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) {
|
|||
selfDelegation := types.NewDelegation(addrVals[0].Bytes(), addrVals[0], issuedShares)
|
||||
app.StakingKeeper.SetDelegation(ctx, selfDelegation)
|
||||
|
||||
// add bonded tokens to pool for delegations
|
||||
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||
require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
|
||||
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
|
||||
|
@ -470,6 +471,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
|||
selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares)
|
||||
app.StakingKeeper.SetDelegation(ctx, selfDelegation)
|
||||
|
||||
// add bonded tokens to pool for delegations
|
||||
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||
require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
|
||||
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
|
||||
|
@ -518,7 +520,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) {
|
|||
_, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], remainingTokens.ToDec())
|
||||
require.NoError(t, err)
|
||||
|
||||
// now validator should now be deleted from state
|
||||
// now validator should be deleted from state
|
||||
validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0])
|
||||
require.False(t, found, "%v", validator)
|
||||
}
|
||||
|
@ -556,6 +558,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) {
|
|||
validator, issuedShares = validator.AddTokensFromDel(delTokens)
|
||||
require.Equal(t, delTokens, issuedShares.RoundInt())
|
||||
|
||||
// add bonded tokens to pool for delegations
|
||||
bondedPool := app.StakingKeeper.GetBondedPool(ctx)
|
||||
require.NoError(t, simapp.FundModuleAccount(app, ctx, bondedPool.GetName(), delCoins))
|
||||
app.AccountKeeper.SetModuleAccount(ctx, bondedPool)
|
||||
|
|
|
@ -61,7 +61,7 @@ func (k Querier) Validators(c context.Context, req *types.QueryValidatorsRequest
|
|||
return &types.QueryValidatorsResponse{Validators: validators, Pagination: pageRes}, nil
|
||||
}
|
||||
|
||||
// Validator queries validator info for given validator addr
|
||||
// Validator queries validator info for given validator address
|
||||
func (k Querier) Validator(c context.Context, req *types.QueryValidatorRequest) (*types.QueryValidatorResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
|
@ -380,6 +380,7 @@ func (k Querier) HistoricalInfo(c context.Context, req *types.QueryHistoricalInf
|
|||
return &types.QueryHistoricalInfoResponse{Hist: &hi}, nil
|
||||
}
|
||||
|
||||
// Redelegations queries redelegations of given address
|
||||
func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsRequest) (*types.QueryRedelegationsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
|
@ -410,6 +411,7 @@ func (k Querier) Redelegations(c context.Context, req *types.QueryRedelegationsR
|
|||
return &types.QueryRedelegationsResponse{RedelegationResponses: redelResponses, Pagination: pageRes}, nil
|
||||
}
|
||||
|
||||
// DelegatorValidators queries all validators info for given delegator address
|
||||
func (k Querier) DelegatorValidators(c context.Context, req *types.QueryDelegatorValidatorsRequest) (*types.QueryDelegatorValidatorsResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
|
|
|
@ -84,7 +84,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryValidators() {
|
|||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGRPCValidator() {
|
||||
func (suite *KeeperTestSuite) TestGRPCQueryValidator() {
|
||||
app, ctx, queryClient, vals := suite.app, suite.ctx, suite.queryClient, suite.vals
|
||||
validator, found := app.StakingKeeper.GetValidator(ctx, vals[0].GetOperator())
|
||||
suite.True(found)
|
||||
|
@ -586,7 +586,7 @@ func (suite *KeeperTestSuite) TestGRPCQueryHistoricalInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGRPCQueryRedelegation() {
|
||||
func (suite *KeeperTestSuite) TestGRPCQueryRedelegations() {
|
||||
app, ctx, queryClient, addrs, vals := suite.app, suite.ctx, suite.queryClient, suite.addrs, suite.vals
|
||||
|
||||
addrAcc, addrAcc1 := addrs[0], addrs[1]
|
||||
|
|
|
@ -26,6 +26,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer {
|
|||
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
// CreateValidator defines a method for creating a new validator
|
||||
func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateValidator) (*types.MsgCreateValidatorResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
|
@ -119,6 +120,7 @@ func (k msgServer) CreateValidator(goCtx context.Context, msg *types.MsgCreateVa
|
|||
return &types.MsgCreateValidatorResponse{}, nil
|
||||
}
|
||||
|
||||
// EditValidator defines a method for editing an existing validator
|
||||
func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValidator) (*types.MsgEditValidatorResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
valAddr, err := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
|
@ -181,6 +183,7 @@ func (k msgServer) EditValidator(goCtx context.Context, msg *types.MsgEditValida
|
|||
return &types.MsgEditValidatorResponse{}, nil
|
||||
}
|
||||
|
||||
// Delegate defines a method for performing a delegation of coins from a delegator to a validator
|
||||
func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*types.MsgDelegateResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
valAddr, valErr := sdk.ValAddressFromBech32(msg.ValidatorAddress)
|
||||
|
@ -237,6 +240,7 @@ func (k msgServer) Delegate(goCtx context.Context, msg *types.MsgDelegate) (*typ
|
|||
return &types.MsgDelegateResponse{}, nil
|
||||
}
|
||||
|
||||
// BeginRedelegate defines a method for performing a redelegation of coins from a delegator and source validator to a destination validator
|
||||
func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRedelegate) (*types.MsgBeginRedelegateResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
valSrcAddr, err := sdk.ValAddressFromBech32(msg.ValidatorSrcAddress)
|
||||
|
@ -302,6 +306,7 @@ func (k msgServer) BeginRedelegate(goCtx context.Context, msg *types.MsgBeginRed
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Undelegate defines a method for performing an undelegation from a delegate and a validator
|
||||
func (k msgServer) Undelegate(goCtx context.Context, msg *types.MsgUndelegate) (*types.MsgUndelegateResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||
|
||||
|
|
|
@ -21,18 +21,18 @@ const (
|
|||
historicalEntries = "historical_entries"
|
||||
)
|
||||
|
||||
// GenUnbondingTime randomized UnbondingTime
|
||||
func GenUnbondingTime(r *rand.Rand) (ubdTime time.Duration) {
|
||||
// genUnbondingTime returns randomized UnbondingTime
|
||||
func genUnbondingTime(r *rand.Rand) (ubdTime time.Duration) {
|
||||
return time.Duration(simulation.RandIntBetween(r, 60, 60*60*24*3*2)) * time.Second
|
||||
}
|
||||
|
||||
// GenMaxValidators randomized MaxValidators
|
||||
func GenMaxValidators(r *rand.Rand) (maxValidators uint32) {
|
||||
// genMaxValidators returns randomized MaxValidators
|
||||
func genMaxValidators(r *rand.Rand) (maxValidators uint32) {
|
||||
return uint32(r.Intn(250) + 1)
|
||||
}
|
||||
|
||||
// GetHistEntries randomized HistoricalEntries between 0-100.
|
||||
func GetHistEntries(r *rand.Rand) uint32 {
|
||||
// getHistEntries returns randomized HistoricalEntries between 0-100.
|
||||
func getHistEntries(r *rand.Rand) uint32 {
|
||||
return uint32(r.Intn(int(types.DefaultHistoricalEntries + 1)))
|
||||
}
|
||||
|
||||
|
@ -47,17 +47,17 @@ func RandomizedGenState(simState *module.SimulationState) {
|
|||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, unbondingTime, &unbondTime, simState.Rand,
|
||||
func(r *rand.Rand) { unbondTime = GenUnbondingTime(r) },
|
||||
func(r *rand.Rand) { unbondTime = genUnbondingTime(r) },
|
||||
)
|
||||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, maxValidators, &maxVals, simState.Rand,
|
||||
func(r *rand.Rand) { maxVals = GenMaxValidators(r) },
|
||||
func(r *rand.Rand) { maxVals = genMaxValidators(r) },
|
||||
)
|
||||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, historicalEntries, &histEntries, simState.Rand,
|
||||
func(r *rand.Rand) { histEntries = GetHistEntries(r) },
|
||||
func(r *rand.Rand) { histEntries = getHistEntries(r) },
|
||||
)
|
||||
|
||||
// NOTE: the slashing module need to be defined after the staking module on the
|
||||
|
|
|
@ -68,7 +68,7 @@ func TestRandomizedGenState(t *testing.T) {
|
|||
require.Equal(t, "1", stakingGenesis.Validators[2].MinSelfDelegation.String())
|
||||
}
|
||||
|
||||
// TestRandomizedGenState tests abnormal scenarios of applying RandomizedGenState.
|
||||
// TestRandomizedGenState1 tests abnormal scenarios of applying RandomizedGenState.
|
||||
func TestRandomizedGenState1(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
|
|
|
@ -6,9 +6,8 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
|
@ -18,17 +17,17 @@ func ParamChanges(r *rand.Rand) []simtypes.ParamChange {
|
|||
return []simtypes.ParamChange{
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyMaxValidators),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", GenMaxValidators(r))
|
||||
return fmt.Sprintf("%d", genMaxValidators(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyUnbondingTime),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("\"%d\"", GenUnbondingTime(r))
|
||||
return fmt.Sprintf("\"%d\"", genUnbondingTime(r))
|
||||
},
|
||||
),
|
||||
simulation.NewSimParamChange(types.ModuleName, string(types.KeyHistoricalEntries),
|
||||
func(r *rand.Rand) string {
|
||||
return fmt.Sprintf("%d", GetHistEntries(r))
|
||||
return fmt.Sprintf("%d", getHistEntries(r))
|
||||
},
|
||||
),
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ order: 1
|
|||
|
||||
# State
|
||||
|
||||
## Pool
|
||||
|
||||
Pool is used for tracking bonded and not-bonded token supply of the bond denomination.
|
||||
|
||||
## LastTotalPower
|
||||
|
||||
LastTotalPower tracks the total amounts of bonded tokens recorded during the previous end block.
|
||||
|
|
|
@ -6,16 +6,16 @@ order: 3
|
|||
|
||||
In this section we describe the processing of the staking messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state_transitions.md) section.
|
||||
|
||||
## Msg/CreateValidator
|
||||
## MsgCreateValidator
|
||||
|
||||
A validator is created using the `Msg/CreateValidator` service message.
|
||||
A validator is created using the `MsgCreateValidator` message.
|
||||
The validator must be created with an initial delegation from the operator.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L16-L17
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L35-L51
|
||||
|
||||
This service message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- another validator with this operator address is already registered
|
||||
- another validator with this pubkey is already registered
|
||||
|
@ -26,32 +26,32 @@ This service message is expected to fail if:
|
|||
- the initial `MaxChangeRate` is either negative or > `MaxRate`
|
||||
- the description fields are too large
|
||||
|
||||
This service message creates and stores the `Validator` object at appropriate indexes.
|
||||
This message creates and stores the `Validator` object at appropriate indexes.
|
||||
Additionally a self-delegation is made with the initial tokens delegation
|
||||
tokens `Delegation`. The validator always starts as unbonded but may be bonded
|
||||
in the first end-block.
|
||||
|
||||
## Msg/EditValidator
|
||||
## MsgEditValidator
|
||||
|
||||
The `Description`, `CommissionRate` of a validator can be updated using the
|
||||
`Msg/EditCandidacy` service message.
|
||||
`MsgEditValidator` message.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L19-L20
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L56-L76
|
||||
|
||||
This service message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the initial `CommissionRate` is either negative or > `MaxRate`
|
||||
- the `CommissionRate` has already been updated within the previous 24 hours
|
||||
- the `CommissionRate` is > `MaxChangeRate`
|
||||
- the description fields are too large
|
||||
|
||||
This service message stores the updated `Validator` object.
|
||||
This message stores the updated `Validator` object.
|
||||
|
||||
## Msg/Delegate
|
||||
## MsgDelegate
|
||||
|
||||
Within this service message the delegator provides coins, and in return receives
|
||||
Within this message the delegator provides coins, and in return receives
|
||||
some amount of their validator's (newly created) delegator-shares that are
|
||||
assigned to `Delegation.Shares`.
|
||||
|
||||
|
@ -59,9 +59,9 @@ assigned to `Delegation.Shares`.
|
|||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90
|
||||
|
||||
This service message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the validator is does not exist
|
||||
- the validator does not exist
|
||||
- the `Amount` `Coin` has a denomination different than one defined by `params.BondDenom`
|
||||
- the exchange rate is invalid, meaning the validator has no tokens (due to slashing) but there are outstanding shares
|
||||
- the amount delegated is less than the minimum allowed delegation
|
||||
|
@ -82,20 +82,20 @@ will not be added to the power index until it is unjailed.
|
|||
|
||||
![Delegation sequence](../../../docs/uml/svg/delegation_sequence.svg)
|
||||
|
||||
## Msg/Undelegate
|
||||
## MsgUndelegate
|
||||
|
||||
The `Msg/Undelegate` service message allows delegators to undelegate their tokens from
|
||||
The `MsgUndelegate` message allows delegators to undelegate their tokens from
|
||||
validator.
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L30-L32
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121
|
||||
|
||||
This service message returns a response containing the completion time of the undelegation:
|
||||
This message returns a response containing the completion time of the undelegation:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L123-L126
|
||||
|
||||
This service message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the delegation doesn't exist
|
||||
- the validator doesn't exist
|
||||
|
@ -103,7 +103,7 @@ This service message is expected to fail if:
|
|||
- existing `UnbondingDelegation` has maximum entries as defined by `params.MaxEntries`
|
||||
- the `Amount` has a denomination different than one defined by `params.BondDenom`
|
||||
|
||||
When this service message is processed the following actions occur:
|
||||
When this message is processed the following actions occur:
|
||||
|
||||
- validator's `DelegatorShares` and the delegation's `Shares` are both reduced by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held within the validator
|
||||
|
@ -116,7 +116,7 @@ When this service message is processed the following actions occur:
|
|||
|
||||
![Unbond sequence](../../../docs/uml/svg/unbond_sequence.svg)
|
||||
|
||||
## Msg/BeginRedelegate
|
||||
## MsgBeginRedelegate
|
||||
|
||||
The redelegation command allows delegators to instantly switch validators. Once
|
||||
the unbonding period has passed, the redelegation is automatically completed in
|
||||
|
@ -126,11 +126,11 @@ the EndBlocker.
|
|||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105
|
||||
|
||||
This service message returns a response containing the completion time of the redelegation:
|
||||
This message returns a response containing the completion time of the redelegation:
|
||||
|
||||
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L107-L110
|
||||
|
||||
This service message is expected to fail if:
|
||||
This message is expected to fail if:
|
||||
|
||||
- the delegation doesn't exist
|
||||
- the source or destination validators don't exist
|
||||
|
@ -139,7 +139,7 @@ This service message is expected to fail if:
|
|||
- existing `Redelegation` has maximum entries as defined by `params.MaxEntries`
|
||||
- the `Amount` `Coin` has a denomination different than one defined by `params.BondDenom`
|
||||
|
||||
When this service message is processed the following actions occur:
|
||||
When this message is processed the following actions occur:
|
||||
|
||||
- the source validator's `DelegatorShares` and the delegations `Shares` are both reduced by the message `SharesAmount`
|
||||
- calculate the token worth of the shares remove that amount tokens held within the source validator.
|
||||
|
|
|
@ -18,9 +18,9 @@ The staking module emits the following events:
|
|||
| complete_redelegation | destination_validator | {dstValidatorAddress} |
|
||||
| complete_redelegation | delegator | {delegatorAddress} |
|
||||
|
||||
## Service Messages
|
||||
## Msg's
|
||||
|
||||
### Msg/CreateValidator
|
||||
### MsgCreateValidator
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
| ---------------- | ------------- | ------------------ |
|
||||
|
@ -30,7 +30,7 @@ The staking module emits the following events:
|
|||
| message | action | create_validator |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### Msg/EditValidator
|
||||
### MsgEditValidator
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
| -------------- | ------------------- | ------------------- |
|
||||
|
@ -40,7 +40,7 @@ The staking module emits the following events:
|
|||
| message | action | edit_validator |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### Msg/Delegate
|
||||
### MsgDelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
| -------- | ------------- | ------------------ |
|
||||
|
@ -50,7 +50,7 @@ The staking module emits the following events:
|
|||
| message | action | delegate |
|
||||
| message | sender | {senderAddress} |
|
||||
|
||||
### Msg/Undelegate
|
||||
### MsgUndelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
| ------- | ------------------- | ------------------ |
|
||||
|
@ -63,7 +63,7 @@ The staking module emits the following events:
|
|||
|
||||
- [0] Time is formatted in the RFC3339 standard
|
||||
|
||||
### Msg/BeginRedelegate
|
||||
### MsgBeginRedelegate
|
||||
|
||||
| Type | Attribute Key | Attribute Value |
|
||||
| ---------- | --------------------- | --------------------- |
|
||||
|
|
|
@ -38,11 +38,11 @@ network.
|
|||
- [Delegations](02_state_transitions.md#delegations)
|
||||
- [Slashing](02_state_transitions.md#slashing)
|
||||
3. **[Messages](03_messages.md)**
|
||||
- [Msg/CreateValidator](03_messages.md#msgcreatevalidator)
|
||||
- [Msg/EditValidator](03_messages.md#msgeditvalidator)
|
||||
- [Msg/Delegate](03_messages.md#msgdelegate)
|
||||
- [Msg/BeginUnbonding](03_messages.md#msgbeginunbonding)
|
||||
- [Msg/BeginRedelegate](03_messages.md#msgbeginredelegate)
|
||||
- [MsgCreateValidator](03_messages.md#msgcreatevalidator)
|
||||
- [MsgEditValidator](03_messages.md#msgeditvalidator)
|
||||
- [MsgDelegate](03_messages.md#msgdelegate)
|
||||
- [MsgUndelegate](03_messages.md#msgundelegate)
|
||||
- [MsgBeginRedelegate](03_messages.md#msgbeginredelegate)
|
||||
4. **[Begin-Block](04_begin_block.md)**
|
||||
- [Historical Info Tracking](04_begin_block.md#historical-info-tracking)
|
||||
5. **[End-Block ](05_end_block.md)**
|
||||
|
@ -51,5 +51,5 @@ network.
|
|||
6. **[Hooks](06_hooks.md)**
|
||||
7. **[Events](07_events.md)**
|
||||
- [EndBlocker](07_events.md#endblocker)
|
||||
- [Handlers](07_events.md#handlers)
|
||||
- [Msg's](07_events.md#msg's)
|
||||
8. **[Parameters](08_params.md)**
|
||||
|
|
Loading…
Reference in New Issue