Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Add interface to remove validator #91

Merged
merged 18 commits into from
Mar 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,7 +804,11 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, txHash string, mode
// Construct usable logs in multi-message transactions.
logs = append(logs, fmt.Sprintf("Msg %d: %s", msgIdx, msgResult.Log))
}

// A tx must only contain one msg. If the msg execution is success, record it
if code == sdk.ABCICodeOK {
routerName := msgs[0].Route()
ctx.RouterCallRecord()[routerName] = true
}
result = sdk.Result{
Code: code,
Data: data,
Expand Down
2 changes: 1 addition & 1 deletion server/tm_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func ShowAddressCmd(ctx *Context) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error {
cfg := ctx.Config
privValidator := pvm.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile())
valAddr := (sdk.ValAddress)(privValidator.GetAddress())
valAddr := (sdk.ConsAddress)(privValidator.GetAddress())

if viper.GetBool(client.FlagJson) {
return printlnJSON(valAddr)
Expand Down
10 changes: 10 additions & 0 deletions types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func NewContext(ms MultiStore, header abci.Header, runTxMode RunTxMode, logger l
c = c.WithTxBytes(nil)
c = c.WithLogger(logger)
c = c.WithVoteInfos(nil)
c = c.WithRouterCallRecord(make(map[string]bool))
return c
}

Expand Down Expand Up @@ -137,6 +138,7 @@ const (
contextKeyLogger
contextKeyVoteInfos
contextKeyAccountCache
contextKeyRouterCallRecord
)

// NOTE: Do not expose MultiStore.
Expand Down Expand Up @@ -183,6 +185,10 @@ func (c Context) AccountCache() AccountCache {
return c.Value(contextKeyAccountCache).(AccountCache)
}

func (c Context) RouterCallRecord() map[string]bool {
return c.Value(contextKeyRouterCallRecord).(map[string]bool)
}

func (c Context) WithMultiStore(ms MultiStore) Context { return c.withValue(contextKeyMultiStore, ms) }

func (c Context) WithBlockHeader(header abci.Header) Context {
Expand Down Expand Up @@ -233,6 +239,10 @@ func (c Context) WithAccountCache(cache AccountCache) Context {
return c.withValue(contextKeyAccountCache, cache)
}

func (c Context) WithRouterCallRecord(record map[string]bool) Context {
return c.withValue(contextKeyRouterCallRecord, record)
}

// Cache the multistore and return a new cached context. The cached context is
// written to the context when writeCache is called.
func (c Context) CacheContext() (cc Context, writeCache func()) {
Expand Down
8 changes: 8 additions & 0 deletions x/gov/client/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ func NormalizeProposalType(proposalType string) string {
return "ParameterChange"
case "SoftwareUpgrade", "software_upgrade":
return "SoftwareUpgrade"
case "ListTradingPair", "list_trading_pair":
return "ListTradingPair"
case "FeeChange", "fee_change":
return "FeeChange"
case "CreateValidator", "create_validator":
return "CreateValidator"
case "RemoveValidator", "remove_validator":
return "RemoveValidator"
}
return ""
}
Expand Down
2 changes: 1 addition & 1 deletion x/gov/msgs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func TestMsgSubmitProposal(t *testing.T) {
{"Test Proposal", "", gov.ProposalTypeText, addrs[0], coinsPos, false},
{"Test Proposal", "the purpose of this proposal is to test", gov.ProposalTypeParameterChange, addrs[0], coinsPos, true},
{"Test Proposal", "the purpose of this proposal is to test", gov.ProposalTypeSoftwareUpgrade, addrs[0], coinsPos, true},
{"Test Proposal", "the purpose of this proposal is to test", 0x06, addrs[0], coinsPos, false},
{"Test Proposal", "the purpose of this proposal is to test", 0x08, addrs[0], coinsPos, false},
{"Test Proposal", "the purpose of this proposal is to test", gov.ProposalTypeText, sdk.AccAddress{}, coinsPos, false},
{"Test Proposal", "the purpose of this proposal is to test", gov.ProposalTypeText, addrs[0], coinsZero, true},
{"Test Proposal", "the purpose of this proposal is to test", gov.ProposalTypeText, addrs[0], coinsNeg, false},
Expand Down
9 changes: 8 additions & 1 deletion x/gov/proposals.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ const (
// ProposalTypeFeeChange belongs to ProposalTypeParameterChange. We use this to make it easily to distinguish。
ProposalTypeFeeChange ProposalKind = 0x05
ProposalTypeCreateValidator ProposalKind = 0x06
ProposalTypeRemoveValidator ProposalKind = 0x07
)

// String to proposalType byte. Returns ff if invalid.
Expand All @@ -136,6 +137,8 @@ func ProposalTypeFromString(str string) (ProposalKind, error) {
return ProposalTypeFeeChange, nil
case "CreateValidator":
return ProposalTypeCreateValidator, nil
case "RemoveValidator":
return ProposalTypeRemoveValidator, nil
default:
return ProposalKind(0xff), errors.Errorf("'%s' is not a valid proposal type", str)
}
Expand All @@ -147,7 +150,9 @@ func validProposalType(pt ProposalKind) bool {
pt == ProposalTypeParameterChange ||
pt == ProposalTypeSoftwareUpgrade ||
pt == ProposalTypeListTradingPair ||
pt == ProposalTypeFeeChange {
pt == ProposalTypeFeeChange ||
pt == ProposalTypeCreateValidator ||
pt == ProposalTypeRemoveValidator {
return true
}
return false
Expand Down Expand Up @@ -200,6 +205,8 @@ func (pt ProposalKind) String() string {
return "FeeChange"
case ProposalTypeCreateValidator:
return "CreateValidator"
case ProposalTypeRemoveValidator:
return "RemoveValidator"
default:
return ""
}
Expand Down
4 changes: 3 additions & 1 deletion x/stake/client/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ const (
FlagNodeID = "node-id"
FlagIP = "ip"

FlagProposalID = "proposal-id"
FlagProposalID = "proposal-id"
FlagConsAddrValidator = "cons-addr-validator"
FlagDeposit = "deposit"

FlagOutputDocument = "output-document" // inspired by wget -O
)
Expand Down
81 changes: 76 additions & 5 deletions x/stake/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
WithCodec(cdc).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))

amounstStr := viper.GetString(FlagAmount)
if amounstStr == "" {
amountStr := viper.GetString(FlagAmount)
if amountStr == "" {
return fmt.Errorf("Must specify amount to stake using --amount")
}
amount, err := sdk.ParseCoin(amounstStr)
amount, err := sdk.ParseCoin(amountStr)
if err != nil {
return err
}
Expand Down Expand Up @@ -102,13 +102,21 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {

proposalId := viper.GetInt64(FlagProposalID)
if proposalId == 0 {
title := ""
depositStr := viper.GetString(FlagDeposit)
if depositStr == "" {
return fmt.Errorf("must specify deposit amount when proposalId is zero using --deposit")
}
deposit, err := sdk.ParseCoin(depositStr)
if err != nil {
return err
}
title := "create validator"
description, err := json.Marshal(msg)
if err != nil {
return err
}
msg = gov.NewMsgSubmitProposal(title, string(description),
gov.ProposalTypeCreateValidator, valAddr, sdk.Coins{amount})
gov.ProposalTypeCreateValidator, valAddr, sdk.Coins{deposit})
} else {
msg = stake.MsgCreateValidatorProposal{
MsgCreateValidator: msg.(stake.MsgCreateValidator),
Expand All @@ -123,6 +131,7 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
cmd.Flags().Int64(FlagProposalID, 0, "id of the CreateValidator proposal")
cmd.Flags().AddFlagSet(fsPk)
cmd.Flags().AddFlagSet(fsAmount)
cmd.Flags().String(FlagDeposit, "", "deposit token amount")
cmd.Flags().AddFlagSet(fsDescriptionCreate)
cmd.Flags().AddFlagSet(fsCommissionCreate)
cmd.Flags().AddFlagSet(fsDelegator)
Expand All @@ -134,6 +143,68 @@ func GetCmdCreateValidator(cdc *codec.Codec) *cobra.Command {
return cmd
}

// GetCmdEditValidator implements the create edit validator command.
func GetCmdRemoveValidator(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "remove-validator",
Short: "remove validator",
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))

launcher, err := cliCtx.GetFromAddress()
if err != nil {
return err
}

validatorAddr, err := sdk.ValAddressFromBech32(viper.GetString(FlagAddressValidator))
if err != nil {
return err
}
validatorConsAddr, err := sdk.ConsAddressFromBech32(viper.GetString(FlagConsAddrValidator))
if err != nil {
return err
}
proposalId := viper.GetInt64(FlagProposalID)

var msg sdk.Msg
msg = stake.NewMsgRemoveValidator(launcher, validatorAddr, validatorConsAddr, proposalId)
if proposalId == 0 {
depositStr := viper.GetString(FlagDeposit)
if depositStr == "" {
return fmt.Errorf("must specify deposit amount when proposalId is zero using --deposit")
}
deposit, err := sdk.ParseCoin(depositStr)
if err != nil {
return err
}
title := "remove validator"
description, err := json.Marshal(msg)
if err != nil {
return err
}
msg = gov.NewMsgSubmitProposal(title, string(description),
gov.ProposalTypeRemoveValidator, launcher, sdk.Coins{deposit})
}

if cliCtx.GenerateOnly {
return utils.PrintUnsignedStdTx(txBldr, cliCtx, []sdk.Msg{msg}, false)
}
// build and sign the transaction, then broadcast to Tendermint
return utils.CompleteAndBroadcastTxCli(txBldr, cliCtx, []sdk.Msg{msg})
},
}

cmd.Flags().Int64(FlagProposalID, 0, "id of the remove validator proposal")
cmd.Flags().String(FlagAddressValidator, "", "validator address")
cmd.Flags().String(FlagConsAddrValidator, "", "validator consensus address")
cmd.Flags().String(FlagDeposit, "", "deposit token amount")

return cmd
}

// GetCmdEditValidator implements the create edit validator command.
func GetCmdEditValidator(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Expand Down
Loading