handler, tags, msgs, codec

This commit is contained in:
rigelrozanski 2018-09-18 23:30:00 -04:00
parent bb9e647f95
commit a18b89539a
12 changed files with 356 additions and 44 deletions

View File

@ -1,16 +1,15 @@
# Transactions
## TxWithdrawDelegationRewardsAll
## MsgWithdrawDelegationRewardsAll
When a delegator wishes to withdraw their rewards it must send
`TxWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
`MsgWithdrawDelegationRewardsAll`. Note that parts of this transaction logic are also
triggered each with any change in individual delegations, such as an unbond,
redelegation, or delegation of additional tokens to a specific validator.
```golang
type TxWithdrawDelegationRewardsAll struct {
delegatorAddr sdk.AccAddress
withdrawAddr sdk.AccAddress // address to make the withdrawal to
type MsgWithdrawDelegationRewardsAll struct {
DelegatorAddr sdk.AccAddress
}
func WithdrawDelegationRewardsAll(delegatorAddr, withdrawAddr sdk.AccAddress)
@ -41,16 +40,15 @@ func GetDelegatorRewardsAll(delegatorAddr sdk.AccAddress, height int64) DecCoins
return withdraw
```
## TxWithdrawDelegationReward
## MsgWithdrawDelegationReward
under special circumstances a delegator may wish to withdraw rewards from only
a single validator.
```golang
type TxWithdrawDelegationReward struct {
delegatorAddr sdk.AccAddress
validatorAddr sdk.AccAddress
withdrawAddr sdk.AccAddress // address to make the withdrawal to
type MsgWithdrawDelegationReward struct {
DelegatorAddr sdk.AccAddress
ValidatorAddr sdk.ValAddress
}
func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.AccAddress)
@ -72,19 +70,18 @@ func WithdrawDelegationReward(delegatorAddr, validatorAddr, withdrawAddr sdk.Acc
```
## TxWithdrawValidatorRewardsAll
## MsgWithdrawValidatorRewardsAll
When a validator wishes to withdraw their rewards it must send
`TxWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
`MsgWithdrawValidatorRewardsAll`. Note that parts of this transaction logic are also
triggered each with any change in individual delegations, such as an unbond,
redelegation, or delegation of additional tokens to a specific validator. This
transaction withdraws the validators commission fee, as well as any rewards
earning on their self-delegation.
```
type TxWithdrawValidatorRewardsAll struct {
operatorAddr sdk.AccAddress // validator address to withdraw from
withdrawAddr sdk.AccAddress // address to make the withdrawal to
type MsgWithdrawValidatorRewardsAll struct {
OperatorAddr sdk.ValAddress // validator address to withdraw from
}
func WithdrawValidatorRewardsAll(operatorAddr, withdrawAddr sdk.AccAddress)

View File

@ -1,10 +0,0 @@
package distribution
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// XXX TODO
// Register concrete types on codec codec
func RegisterCodec(cdc *codec.Codec) {
}

View File

@ -1 +1,84 @@
package distribution
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/distribution/tags"
"github.com/cosmos/cosmos-sdk/x/distribution/types"
)
func NewHandler(k keeper.Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
// NOTE msg already has validate basic run
switch msg := msg.(type) {
case types.MsgModifyWithdrawAddress:
return handleMsgModifyWithdrawAddress(ctx, msg, k)
case types.MsgWithdrawDelegatorRewardsAll:
return handleMsgWithdrawDelegatorRewardsAll(ctx, msg, k)
case types.MsgWithdrawDelegatorReward:
return handleMsgWithdrawDelegatorReward(ctx, msg, k)
case types.MsgWithdrawValidatorRewardsAll:
return handleMsgWithdrawValidatorRewardsAll(ctx, msg, k)
default:
return sdk.ErrTxDecode("invalid message parse in distribution module").Result()
}
}
}
//_____________________________________________________________________
// These functions assume everything has been authenticated,
// now we just perform action and save
func handleMsgModifyWithdrawAddress(ctx sdk.Context, msg types.MsgModifyWithdrawAddress, k keeper.Keeper) sdk.Result {
k.SetDelegatorWithdrawAddr(ctx, msg.DelegatorAddr, msg.WithdrawAddress)
tags := sdk.NewTags(
tags.Action, tags.ActionModifyWithdrawAddress,
tags.Delegator, []byte(msg.DelegatorAddr.String()),
)
return sdk.Result{
Tags: tags,
}
}
func handleMsgWithdrawDelegatorRewardsAll(ctx sdk.Context, msg types.MsgWithdrawDelegatorRewardsAll, k keeper.Keeper) sdk.Result {
k.WithdrawDelegationRewardsAll(ctx, msg.DelegatorAddr)
tags := sdk.NewTags(
tags.Action, tags.ActionWithdrawDelegatorRewardsAll,
tags.Delegator, []byte(msg.DelegatorAddr.String()),
)
return sdk.Result{
Tags: tags,
}
}
func handleMsgWithdrawDelegatorReward(ctx sdk.Context, msg types.MsgWithdrawDelegatorReward, k keeper.Keeper) sdk.Result {
k.WithdrawDelegationReward(ctx, msg.DelegatorAddr, msg.ValidatorAddr)
tags := sdk.NewTags(
tags.Action, tags.ActionWithdrawDelegatorReward,
tags.Delegator, []byte(msg.DelegatorAddr.String()),
tags.Validator, []byte(msg.ValidatorAddr.String()),
)
return sdk.Result{
Tags: tags,
}
}
func handleMsgWithdrawValidatorRewardsAll(ctx sdk.Context, msg types.MsgWithdrawValidatorRewardsAll, k keeper.Keeper) sdk.Result {
k.WithdrawValidatorRewardsAll(ctx, msg.ValidatorAddr)
tags := sdk.NewTags(
tags.Action, tags.ActionWithdrawValidatorRewardsAll,
tags.Validator, []byte(msg.ValidatorAddr.String()),
)
return sdk.Result{
Tags: tags,
}
}

View File

@ -34,8 +34,7 @@ func (k Keeper) RemoveValidatorDistInfo(ctx sdk.Context, valAddr sdk.ValAddress)
}
// withdrawal all the validator rewards including the commission
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context,
operatorAddr sdk.ValAddress) {
func (k Keeper) WithdrawValidatorRewardsAll(ctx sdk.Context, operatorAddr sdk.ValAddress) {
// withdraw self-delegation
height := ctx.BlockHeight()

View File

@ -0,0 +1,17 @@
// nolint
package tags
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
ActionModifyWithdrawAddress = []byte("modify-withdraw-address")
ActionWithdrawDelegatorRewardsAll = []byte("withdraw-delegator-rewards-all")
ActionWithdrawDelegatorReward = []byte("withdraw-delegator-reward")
ActionWithdrawValidatorRewardsAll = []byte("withdraw-validator-rewards-all")
Action = sdk.TagAction
Validator = sdk.TagSrcValidator
Delegator = sdk.TagDelegator
)

View File

@ -0,0 +1,24 @@
package types
import (
"github.com/cosmos/cosmos-sdk/codec"
)
// XXX TODO
// Register concrete types on codec codec
func RegisterCodec(cdc *codec.Codec) {
cdc.RegisterConcrete(MsgWithdrawDelegationRewardsAll{}, "cosmos-sdk/MsgWithdrawDelegationRewardsAll", nil)
cdc.RegisterConcrete(MsgWithdrawDelegationReward{}, "cosmos-sdk/MsgWithdrawDelegationReward", nil)
cdc.RegisterConcrete(MsgWithdrawValidatorRewardsAll{}, "cosmos-sdk/MsgWithdrawValidatorRewardsAll", nil)
cdc.RegisterConcrete(MsgModifyWithdrawAddress{}, "cosmos-sdk/MsgModifyWithdrawAddress", nil)
}
// generic sealed codec to be used throughout sdk
var MsgCdc *codec.Codec
func init() {
cdc := codec.New()
RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
MsgCdc = cdc.Seal()
}

175
x/distribution/types/msg.go Normal file
View File

@ -0,0 +1,175 @@
//nolint
package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// name to identify transaction types
const MsgType = "distr"
// Verify interface at compile time
var _, _ sdk.Msg = &MsgModifyWithdrawAddress{}, &MsgWithdrawDelegatorRewardsAll{}
var _, _ sdk.Msg = &MsgWithdrawDelegationReward{}, &MsgWithdrawValidatorRewardsAll{}
//______________________________________________________________________
// msg struct for changing the withdraw address for a delegator (or validator self-delegation)
type MsgModifyWithdrawAddress struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
WithdrawAddr sdk.AccAddress `json:"delegator_addr"`
}
func NewMsgModifyWithdrawAddress(delAddr, withdrawAddr sdk.AccAddress) MsgModifyWithdrawAddress {
return MsgModifyWithdrawAddress{
DelegatorAddr: delAddr,
WithdrawAddr: withdrawAddr,
}
}
func (msg MsgModifyWithdrawAddress) Type() string { return MsgType }
func (msg MsgModifyWithdrawAddress) Name() string { return "withdraw_delegation_rewards_all" }
// Return address that must sign over msg.GetSignBytes()
func (msg MsgModifyWithdrawAddress) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.DelegatorAddr)}
}
// get the bytes for the message signer to sign on
func (msg MsgModifyWithdrawAddress) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
}
// quick validity check
func (msg MsgModifyWithdrawAddress) ValidateBasic() sdk.Error {
if msg.DelegatorAddr == nil {
return ErrNilDelegatorAddr(DefaultCodespace)
}
if msg.WithdrawAddr == nil {
return ErrNilWithdrawAddr(DefaultCodespace)
}
return nil
}
//______________________________________________________________________
// msg struct for delegation withdraw for all of the delegator's delegations
type MsgWithdrawDelegatorRewardsAll struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
}
func NewMsgWithdrawDelegationRewardsAll(delAddr sdk.AccAddress) MsgWithdrawDelegatorRewardsAll {
return MsgWithdrawDelegatorRewardsAll{
DelegatorAddr: delAddr,
}
}
func (msg MsgWithdrawDelegatorRewardsAll) Type() string { return MsgType }
func (msg MsgWithdrawDelegatorRewardsAll) Name() string { return "withdraw_delegation_rewards_all" }
// Return address that must sign over msg.GetSignBytes()
func (msg MsgWithdrawDelegatorRewardsAll) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.DelegatorAddr)}
}
// get the bytes for the message signer to sign on
func (msg MsgWithdrawDelegatorRewardsAll) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
}
// quick validity check
func (msg MsgWithdrawDelegatorRewardsAll) ValidateBasic() sdk.Error {
if msg.DelegatorAddr == nil {
return ErrNilDelegatorAddr(DefaultCodespace)
}
return nil
}
//______________________________________________________________________
// msg struct for delegation withdraw from a single validator
type MsgWithdrawDelegationReward struct {
DelegatorAddr sdk.AccAddress `json:"delegator_addr"`
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
}
func NewMsgWithdrawDelegationReward(delAddr sdk.AccAddress, valAddr sdk.ValAddress) MsgWithdrawDelegationReward {
return MsgWithdrawDelegationReward{
DelegatorAddr: delAddr,
ValidatorAddr: valAddr,
}
}
func (msg MsgWithdrawDelegationReward) Type() string { return MsgType }
func (msg MsgWithdrawDelegationReward) Name() string { return "withdraw_delegation_reward" }
// Return address that must sign over msg.GetSignBytes()
func (msg MsgWithdrawDelegationReward) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.DelegatorAddr)}
}
// get the bytes for the message signer to sign on
func (msg MsgWithdrawDelegationReward) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
}
// quick validity check
func (msg MsgWithdrawDelegationReward) ValidateBasic() sdk.Error {
if msg.DelegatorAddr == nil {
return ErrNilDelegatorAddr(DefaultCodespace)
}
if msg.ValidatorAddr == nil {
return ErrNilValidatorAddr(DefaultCodespace)
}
return nil
}
//______________________________________________________________________
// msg struct for validator withdraw
type MsgWithdrawValidatorRewardsAll struct {
ValidatorAddr sdk.ValAddress `json:"validator_addr"`
}
func NewMsgWithdrawValidatorRewardsAll(valAddr sdk.ValAddress) MsgWithdrawValidatorRewardsAll {
return MsgWithdrawValidatorRewardsAll{
ValidatorAddr: valAddr,
}
}
func (msg MsgWithdrawValidatorRewardsAll) Type() string { return MsgType }
func (msg MsgWithdrawValidatorRewardsAll) Name() string { return "withdraw_validator_rewards_all" }
// Return address that must sign over msg.GetSignBytes()
func (msg MsgWithdrawValidatorRewardsAll) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{sdk.AccAddress(msg.ValidatorAddr.Bytes())}
}
// get the bytes for the message signer to sign on
func (msg MsgWithdrawValidatorRewardsAll) GetSignBytes() []byte {
b, err := MsgCdc.MarshalJSON(msg)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
}
// quick validity check
func (msg MsgWithdrawValidatorRewardsAll) ValidateBasic() sdk.Error {
if msg.ValidatorAddr == nil {
return ErrNilValidatorAddr(DefaultCodespace)
}
return nil
}

View File

@ -87,6 +87,13 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k
return err.Result()
}
// call the hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnValidatorCreated(ctx, validator.OperatorAddr)
accAddr := sdk.AccAddress{validator.OperatorAddr}
k.validatorHooks.OnDelegationCreated(ctx, accAddr, validator.OperatorAddr)
}
tags := sdk.NewTags(
tags.Action, tags.ActionCreateValidator,
tags.DstValidator, []byte(msg.ValidatorAddr.String()),
@ -146,6 +153,11 @@ func handleMsgDelegate(ctx sdk.Context, msg types.MsgDelegate, k keeper.Keeper)
return err.Result()
}
// call the hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnDelegationCreated(ctx, msg.DelegatorAddr, validator.OperatorAddr)
}
tags := sdk.NewTags(
tags.Action, tags.ActionDelegate,
tags.Delegator, []byte(msg.DelegatorAddr.String()),

View File

@ -84,6 +84,12 @@ func (k Keeper) SetDelegation(ctx sdk.Context, delegation types.Delegation) {
// remove a delegation from store
func (k Keeper) RemoveDelegation(ctx sdk.Context, delegation types.Delegation) {
// call the hook if present
if k.hooks != nil {
k.hooks.OnDelegationRemoved(ctx, delegation.DelegatorAddr, delegation.ValidatorAddr)
}
store := ctx.KVStore(k.storeKey)
store.Delete(GetDelegationKey(delegation.DelegatorAddr, delegation.ValidatorAddr))
}
@ -293,6 +299,11 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co
k.SetDelegation(ctx, delegation)
k.UpdateValidator(ctx, validator)
// call the hook if present
if k.hooks != nil {
k.hooks.OnDelegationSharesModified(ctx, delegation.DelegatorAddr, validator.OperatorAddr)
}
return
}
@ -351,6 +362,11 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA
k.RemoveValidator(ctx, validator.OperatorAddr)
}
// call the hook if present
if k.hooks != nil {
k.hooks.OnDelegationSharesModified(ctx, delegation.DelegatorAddr, validator.OperatorAddr)
}
return amount, nil
}

View File

@ -22,12 +22,12 @@ type Keeper struct {
func NewKeeper(cdc *codec.Codec, key, tkey sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
keeper := Keeper{
storeKey: key,
storeTKey: tkey,
cdc: cdc,
bankKeeper: ck,
validatorHooks: nil,
codespace: codespace,
storeKey: key,
storeTKey: tkey,
cdc: cdc,
bankKeeper: ck,
hooks: nil,
codespace: codespace,
}
return keeper
}
@ -37,7 +37,7 @@ func (k Keeper) WithHooks(sh sdk.StakingHooks) Keeper {
if k.stakingHooks != nil {
panic("cannot set validator hooks twice")
}
k.validatorHooks = sh
k.hooks = sh
return k
}

View File

@ -623,8 +623,8 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat
store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr))
// call the unbond hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress())
if k.hooks != nil {
k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress())
}
// return updated validator
@ -658,8 +658,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.
tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI)
// call the bond hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnValidatorBonded(ctx, validator.ConsAddress())
if k.hooks != nil {
k.hooks.OnValidatorBonded(ctx, validator.ConsAddress())
}
// return updated validator
@ -670,8 +670,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.
func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) {
// call the hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnValidatorRemoved(ctx, validator.OperatorAddr)
if k.hooks != nil {
k.hooks.OnValidatorRemoved(ctx, validator.OperatorAddr)
}
// first retrieve the old validator record
@ -741,8 +741,8 @@ func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, addr sdk.ValAddress,
store := ctx.KVStore(k.storeKey)
// call the hook if present
if k.validatorHooks != nil {
k.validatorHooks.OnValidatorCommissionChange(ctx, validator.OperatorAddr)
if k.hooks != nil {
k.hooks.OnValidatorCommissionChange(ctx, validator.OperatorAddr)
}
validator, found := k.GetValidator(addr)

View File

@ -22,6 +22,5 @@ func init() {
cdc := codec.New()
RegisterCodec(cdc)
codec.RegisterCrypto(cdc)
MsgCdc = cdc
//MsgCdc = cdc.Seal() //TODO use when upgraded to go-amino 0.9.10
MsgCdc = cdc.Seal()
}