Skip to content

Commit

Permalink
#13 WIP on improvements to upgrade module
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc committed Mar 25, 2019
1 parent 52f76f6 commit 6ab0c39
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 106 deletions.
22 changes: 19 additions & 3 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import (
"github.com/regen-network/regen-ledger/x/group"
"github.com/regen-network/regen-ledger/x/proposal"
"github.com/regen-network/regen-ledger/x/upgrade"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/log"
"io/ioutil"
"path/filepath"

//"os"

"github.com/cosmos/cosmos-sdk/codec"
Expand Down Expand Up @@ -152,7 +157,11 @@ func NewXrnApp(logger log.Logger, db dbm.DB, postgresUrl string) *xrnApp {

app.espKeeper = esp.NewKeeper(app.espStoreKey, app.agentKeeper, app.geoKeeper, cdc)

app.upgradeKeeper = upgrade.NewKeeper(app.upgradeStoreKey, cdc, 1000)
app.upgradeKeeper = upgrade.NewKeeper(app.upgradeStoreKey, cdc)
app.upgradeKeeper.SetBeforeShutdowner(app.willUpgrade)
app.upgradeKeeper.SetUpgradeHandler("test3", func(ctx sdk.Context, plan upgrade.UpgradePlan) {
ctx.Logger().Info("In upgrade 3 handler!")
})

app.consortiumKeeper = consortium.NewKeeper(app.consortiumStoreKey, cdc, app.agentKeeper, app.upgradeKeeper)

Expand Down Expand Up @@ -230,8 +239,8 @@ func (app *xrnApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.
app.accountKeeper.SetAccount(ctx, acc)
}

for _, group := range genesisState.Groups {
app.agentKeeper.CreateGroup(ctx, group)
for _, g := range genesisState.Groups {
app.agentKeeper.CreateGroup(ctx, g)
}

app.consortiumKeeper.SetValidators(ctx, req.Validators)
Expand All @@ -242,6 +251,13 @@ func (app *xrnApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.
return abci.ResponseInitChain{}
}

func (app *xrnApp) willUpgrade(plan upgrade.UpgradePlan) {
if len(plan.Memo) != 0 {
home := viper.GetString(cli.HomeFlag)
_ = ioutil.WriteFile(filepath.Join(home, "data", "upgrade-info"), []byte(plan.Memo), 0644)
}
}

func (app *xrnApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
app.upgradeKeeper.BeginBlocker(ctx, req)
return abci.ResponseBeginBlock{}
Expand Down
15 changes: 13 additions & 2 deletions testnets/next/genesis.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"genesis_time": "2018-12-19T20:40:06.463846Z",
"chain_id": "xrn-test-2",
"chain_id": "xrn-test-next",
"consensus_params": {
"block_size": {
"max_bytes": "22020096",
Expand Down Expand Up @@ -60,7 +60,18 @@
"sequence": "0"
}
],
"groups": [],
"groups": [
{
"decision_threshold": "1",
"members": [
{
"address": "xrn:1xrsmkqh305m09tc5x73v4t3wtcuqmf6cgy2taw",
"weight": "1"
}
],
"memo": "Regen Consortium"
}
],
"auth": {
"collected_fees": null,
"params": {
Expand Down
28 changes: 22 additions & 6 deletions x/consortium/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import (
)

type ActionScheduleUpgrade struct {
UpgradeInfo upgrade.UpgradeInfo `json:"upgrade_info"`
Plan upgrade.UpgradePlan `json:"upgrade_plan"`
}

type ActionCancelUpgrade struct {
}

/*
Expand All @@ -24,16 +27,29 @@ type ActionChangeValidatorSet struct {

func (action ActionScheduleUpgrade) Route() string { return "consortium" }

func (action ActionScheduleUpgrade) Type() string { return "upgrade" }
func (action ActionScheduleUpgrade) Type() string { return "consortium.upgrade" }

func (action ActionScheduleUpgrade) ValidateBasic() sdk.Error {
if action.UpgradeInfo.Height <= 0 {
return sdk.ErrUnknownRequest("Upgrade height must be greater than 0")
return action.Plan.ValidateBasic()
}

func (action ActionScheduleUpgrade) GetSignBytes() []byte {
b, err := json.Marshal(action)
if err != nil {
panic(err)
}
return sdk.MustSortJSON(b)
}

func (ActionCancelUpgrade) Route() string { return "consortium" }

func (ActionCancelUpgrade) Type() string { return "consortium.cancel-upgrade" }

func (ActionCancelUpgrade) ValidateBasic() sdk.Error {
return nil
}

func (action ActionScheduleUpgrade) GetSignBytes() []byte {
func (action ActionCancelUpgrade) GetSignBytes() []byte {
b, err := json.Marshal(action)
if err != nil {
panic(err)
Expand All @@ -43,7 +59,7 @@ func (action ActionScheduleUpgrade) GetSignBytes() []byte {

func (action ActionChangeValidatorSet) Route() string { return "consortium" }

func (action ActionChangeValidatorSet) Type() string { return "changeValidatorSet" }
func (action ActionChangeValidatorSet) Type() string { return "consortium.changeValidatorSet" }

func (action ActionChangeValidatorSet) ValidateBasic() sdk.Error {
panic("implement me")
Expand Down
27 changes: 19 additions & 8 deletions x/consortium/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,43 @@ import (
proposalcli "github.com/regen-network/regen-ledger/x/proposal/client/cli"
"github.com/regen-network/regen-ledger/x/upgrade"
"github.com/spf13/cobra"
"strconv"
"time"

"github.com/cosmos/cosmos-sdk/codec"
)

func GetCmdProposeUpgrade(cdc *codec.Codec) *cobra.Command {
var timeStr string
var height int64
var memo string

cmd := proposalcli.GetCmdPropose(cdc, func(cmd *cobra.Command, args []string) (action proposal.ProposalAction, e error) {
blockHeightStr := args[0]
blockHeight, err := strconv.ParseInt(blockHeightStr, 10, 64)
if err != nil {
return nil, err
name := args[0]

var t time.Time
var err error
if len(timeStr) != 0 {
t, err = time.Parse(time.RFC3339, timeStr)
if err != nil {
panic(err)
}
}

return consortium.ActionScheduleUpgrade{
UpgradeInfo: upgrade.UpgradeInfo{
Height: blockHeight,
Plan: upgrade.UpgradePlan{
Name: name,
Time: t,
Height: height,
Memo: memo,
},
}, nil
})

cmd.Args = cobra.ExactArgs(1)
cmd.Use = "propose-upgrade <block-height> [--upgrade-memo <memo>]"
cmd.Use = "propose-upgrade <name> [--upgrade-time <time> | --upgrade-height <height>] [--upgrade-memo <memo>]"
cmd.Short = "Propose an ESP version"
cmd.Flags().StringVar(&timeStr, "upgrade-time", "", "The time after which the upgrade must happen in ISO8601/RFC3339 format (omit if using --upgrade-height)")
cmd.Flags().Int64Var(&height, "upgrade-height", 0, "The height at which the upgrade must happen (omit if using --upgrade-time)")
cmd.Flags().StringVar(&memo, "upgrade-memo", "", "Any memo to attach to the upgrade plan such as a git commit hash")
return cmd
}
22 changes: 19 additions & 3 deletions x/consortium/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func (keeper Keeper) CheckProposal(ctx sdk.Context, action proposal.ProposalActi
switch action.(type) {
case ActionScheduleUpgrade:
return true, sdk.Result{Code: sdk.CodeOK}
case ActionCancelUpgrade:
return true, sdk.Result{Code: sdk.CodeOK}
case ActionChangeValidatorSet:
return true, sdk.Result{Code: sdk.CodeOK}
default:
Expand All @@ -46,6 +48,8 @@ func (keeper Keeper) HandleProposal(ctx sdk.Context, action proposal.ProposalAct
switch action := action.(type) {
case ActionScheduleUpgrade:
return keeper.handleActionScheduleUpgrade(ctx, action, voters)
case ActionCancelUpgrade:
return keeper.handleActionCancelUpgrade(ctx, action, voters)
case ActionChangeValidatorSet:
return keeper.handleActionChangeValidatorSet(ctx, action, voters)
default:
Expand All @@ -58,14 +62,26 @@ func (keeper Keeper) handleActionScheduleUpgrade(ctx sdk.Context, action ActionS
if !keeper.agentKeeper.Authorize(ctx, consortiumGroupId, signers) {
return sdk.Result{Code: sdk.CodeUnauthorized}
}
keeper.upgradeKeeper.ScheduleUpgrade(ctx, action.UpgradeInfo)
return sdk.Result{Code: sdk.CodeOK}
err := keeper.upgradeKeeper.ScheduleUpgrade(ctx, action.Plan)
if err != nil {
return err.Result()
}
return sdk.Result{}
}

func (keeper Keeper) handleActionCancelUpgrade(ctx sdk.Context, _ ActionCancelUpgrade, signers []sdk.AccAddress) sdk.Result {
if !keeper.agentKeeper.Authorize(ctx, consortiumGroupId, signers) {
return sdk.Result{Code: sdk.CodeUnauthorized}
}
keeper.upgradeKeeper.ClearUpgradePlan(ctx)
return sdk.Result{}
}

func (keeper Keeper) handleActionChangeValidatorSet(ctx sdk.Context, action ActionChangeValidatorSet, signers []sdk.AccAddress) sdk.Result {
keeper.SetValidators(ctx, action.Validators)
return sdk.Result{Code: sdk.CodeOK}
return sdk.Result{}
}

func (keeper Keeper) GetValidators(ctx sdk.Context) []abci.ValidatorUpdate {
store := ctx.KVStore(keeper.storeKey)
bz := store.Get(keyValidators)
Expand Down
2 changes: 1 addition & 1 deletion x/group/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
// It could be used by a single user to manage multiple devices and setup a multisig policy.
type Group struct {
// The members of the group and their associated weight
Members []Member `json:"addresses,omitempty"`
Members []Member `json:"members,omitempty"`
// Specifies the number of votes that must be accumulated in order for a decision to be made by the group.
// A member gets as many votes as is indicated by their Weight field.
// A big integer is used here to avoid any potential vulnerabilities from overflow errors
Expand Down
7 changes: 6 additions & 1 deletion x/proposal/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import (
type ActionCreator func(cmd *cobra.Command, args []string) (proposal.ProposalAction, error)

func GetCmdPropose(cdc *codec.Codec, actionCreator ActionCreator) *cobra.Command {
return &cobra.Command{
var exec bool

cmd := &cobra.Command{
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc)

Expand All @@ -35,6 +37,7 @@ func GetCmdPropose(cdc *codec.Codec, actionCreator ActionCreator) *cobra.Command
msg := proposal.MsgCreateProposal{
Proposer: account,
Action: action,
Exec: exec,
}
err = msg.ValidateBasic()
if err != nil {
Expand All @@ -46,6 +49,8 @@ func GetCmdPropose(cdc *codec.Codec, actionCreator ActionCreator) *cobra.Command
return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg})
},
}
cmd.Flags().BoolVar(&exec, "exec", false, "try to execute the proposal immediately")
return cmd
}

func getRunVote(cdc *codec.Codec, approve bool) func(cmd *cobra.Command, args []string) error {
Expand Down
14 changes: 11 additions & 3 deletions x/proposal/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,18 @@ func NewHandler(keeper Keeper) sdk.Handler {
}
}


func handleMsgCreateProposal(ctx sdk.Context, keeper Keeper, msg MsgCreateProposal) sdk.Result {
return keeper.Propose(ctx, msg.Proposer, msg.Action)
id, res := keeper.Propose(ctx, msg.Proposer, msg.Action)
if res.Code != sdk.CodeOK {
return res
}
if msg.Exec {
res := keeper.TryExecute(ctx, id)
if res.Code == sdk.CodeOK {
return res
}
}
return res
}

func handleMsgVote(ctx sdk.Context, keeper Keeper, msg MsgVote) sdk.Result {
Expand All @@ -40,4 +49,3 @@ func handleMsgTryExecuteProposal(ctx sdk.Context, keeper Keeper, msg MsgTryExecu
func handleMsgWithdrawProposal(ctx sdk.Context, keeper Keeper, msg MsgWithdrawProposal) sdk.Result {
return keeper.Withdraw(ctx, msg.ProposalId, msg.Proposer)
}

24 changes: 7 additions & 17 deletions x/proposal/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,23 @@ func MustDecodeProposalIDBech32(bech string) []byte {
return id
}

func (keeper Keeper) Propose(ctx sdk.Context, proposer sdk.AccAddress, action ProposalAction) sdk.Result {
func (keeper Keeper) Propose(ctx sdk.Context, proposer sdk.AccAddress, action ProposalAction) ([]byte, sdk.Result) {
canHandle, res := keeper.handler.CheckProposal(ctx, action)

if !canHandle {
return sdk.Result{
Code: sdk.CodeUnknownRequest,
Log: "unknown proposal type",
}
return nil, sdk.ErrUnknownRequest("unknown proposal type").Result()
}

if res.Code != sdk.CodeOK {
return res
return nil, res
}

store := ctx.KVStore(keeper.storeKey)
hashBz := blake2b.Sum256(action.GetSignBytes())
id := hashBz[:]
bech := mustEncodeProposalIDBech32(id)
if store.Has(id) {
return sdk.Result{
Code: sdk.CodeUnknownRequest,
Log: fmt.Sprintf("proposal %s already exists", bech),
}
return id, sdk.ErrUnknownRequest(fmt.Sprintf("proposal %s already exists", bech)).Result()
}

prop := Proposal{
Expand All @@ -69,10 +63,9 @@ func (keeper Keeper) Propose(ctx sdk.Context, proposer sdk.AccAddress, action Pr
keeper.storeProposal(ctx, id, &prop)

res.Tags = res.Tags.
AppendTag("proposal.id", bech).
AppendTag("proposal.id", mustEncodeProposalIDBech32(id)).
AppendTag("proposal.action", action.Type())

return res
return id, res
}

func (keeper Keeper) storeProposal(ctx sdk.Context, id []byte, proposal *Proposal) {
Expand Down Expand Up @@ -168,10 +161,7 @@ func (keeper Keeper) TryExecute(ctx sdk.Context, proposalId []byte) sdk.Result {
proposal, err := keeper.GetProposal(ctx, proposalId)

if err != nil {
return sdk.Result{
Code: sdk.CodeUnknownRequest,
Log: "can't find proposal",
}
return sdk.ErrUnknownRequest("can't find proposal").Result()
}

res := keeper.handler.HandleProposal(ctx, proposal.Action, proposal.Approvers)
Expand Down
Loading

0 comments on commit 6ab0c39

Please sign in to comment.