diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d10be7f1..e866a20b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,8 +4,8 @@ jobs:
test:
strategy:
matrix:
- go-version: [1.15.x]
- os: [ubuntu-latest]
+ go-version: [1.15.x, 1.16.x]
+ os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Install Go
@@ -14,5 +14,5 @@ jobs:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- - name: Run Makefile Tests
- run: make github-ci
\ No newline at end of file
+ - name: Run Go Tests
+ run: go test ./...
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 3cad273e..82b382fd 100644
--- a/Makefile
+++ b/Makefile
@@ -48,6 +48,10 @@ BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
build:
go build -mod=readonly $(BUILD_FLAGS) -o build/emd$(BIN_PREFIX) ./cmd/emd
+
+cosmovisor:
+ go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@latest
+
lint:
golangci-lint run
@@ -59,16 +63,23 @@ fmt:
imp:
gci -w **/*.go
-
install:
go install -mod=readonly $(BUILD_FLAGS) ./cmd/emd
+build-test-upg:
+ docker run --rm --entrypoint cat emoney/cosmovisor /go/bin/cosmovisor > build/cosmovisor
+ chmod +x build/cosmovisor
+ docker run --rm --entrypoint cat emoney/test-upg /go/src/em-ledger/build/emd > "build/emdupg"
+ chmod +x "build/emdupg"
+ docker run --rm --entrypoint cat emoney/test-upg /go/src/em-ledger/build/emd-linux > "build/emdupg-linux"
+ chmod +x "build/emdupg-linux"
+
build-linux:
# Linux images for docker-compose
# CGO_ENABLED=0 added to solve this issue: https://stackoverflow.com/a/36308464
- BIN_PREFIX=-linux LEDGER_ENABLED=false GOOS=linux CGO_ENABLED=0 GOARCH=amd64 $(MAKE) build
+ BIN_PREFIX=-linux LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build
-build-all: build-linux
+build-all: build-linux build-test-upg
$(MAKE) build
build-docker:
@@ -82,7 +93,7 @@ test:
go test -mod=readonly ./...
bdd-test:
- go test -mod=readonly -v -p 1 -timeout 1h --tags="bdd" bdd_test.go multisigauthority_test.go authority_test.go market_test.go buyback_test.go capacity_test.go staking_test.go bep3swap_test.go
+ go test -mod=readonly -v -p 1 -timeout 1h --tags="bdd" bdd_test.go multisigauthority_test.go authority_test.go market_test.go buyback_test.go capacity_test.go staking_test.go bep3swap_test.go upgrade_test.go
github-ci: build-linux
$(MAKE) test
@@ -104,7 +115,7 @@ license:
GO111MODULE=off go get github.com/google/addlicense/
addlicense -f LICENSE .
-.PHONY: build build-linux clean test bdd-test build-docker license
+.PHONY: build build-linux build-test-upg cosmovisor clean test bdd-test build-docker license
###############################################################################
### Protobuf ###
@@ -133,6 +144,4 @@ proto-lint:
proto-check-breaking:
@$(DOCKER_BUF) breaking --against-input $(HTTPS_GIT)#branch=master
-.PHONY: proto-all proto-gen proto-swagger-gen proto-format proto-lint proto-check-breaking
-
-
+.PHONY: proto-all proto-gen proto-swagger-gen proto-format proto-lint proto-check-breaking
\ No newline at end of file
diff --git a/app.go b/app.go
index 9cac70e7..4fe826b3 100644
--- a/app.go
+++ b/app.go
@@ -7,6 +7,12 @@ package emoney
import (
"encoding/json"
"fmt"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+ "time"
+
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
"github.com/cosmos/cosmos-sdk/client/rpc"
@@ -65,11 +71,6 @@ import (
tmos "github.com/tendermint/tendermint/libs/os"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
- "io"
- "net/http"
- "os"
- "path/filepath"
- "time"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
@@ -104,7 +105,6 @@ const (
var (
DefaultNodeHome = os.ExpandEnv("$HOME/.emd")
- // todo (reviewer) : please check the listed modules carefully. This are the defaults + em modules
ModuleBasics = module.NewBasicManager(
auth.AppModuleBasic{},
genutil.AppModuleBasic{},
@@ -342,7 +342,7 @@ func NewApp(
app.inflationKeeper = inflation.NewKeeper(app.appCodec, keys[inflation.StoreKey], app.bankKeeper, app.accountKeeper, app.stakingKeeper, buyback.AccountName, authtypes.FeeCollectorName)
app.lpKeeper = liquidityprovider.NewKeeper(app.appCodec, keys[lptypes.StoreKey], app.bankKeeper)
app.issuerKeeper = issuer.NewKeeper(app.appCodec, keys[issuer.StoreKey], app.lpKeeper, app.inflationKeeper)
- app.authorityKeeper = authority.NewKeeper(app.appCodec, keys[authority.StoreKey], app.issuerKeeper, app.bankKeeper, app)
+ app.authorityKeeper = authority.NewKeeper(app.appCodec, keys[authority.StoreKey], app.issuerKeeper, app.bankKeeper, app, &app.upgradeKeeper)
app.marketKeeper = market.NewKeeper(app.appCodec, keys[market.StoreKey], memKeys[market.StoreKeyIdx], app.accountKeeper, app.bankKeeper)
app.buybackKeeper = buyback.NewKeeper(app.appCodec, keys[buyback.StoreKey], app.marketKeeper, app.accountKeeper, app.stakingKeeper, app.bankKeeper)
app.bep3Keeper = bep3.NewKeeper(app.appCodec, keys[bep3.StoreKey], app.bankKeeper, app.accountKeeper, app.paramsKeeper.Subspace(bep3.ModuleName), GetMaccs())
diff --git a/app_test.go b/app_test.go
index 9c09df51..a15e83e9 100644
--- a/app_test.go
+++ b/app_test.go
@@ -2,23 +2,58 @@ package emoney
import (
"encoding/json"
- sdk "github.com/cosmos/cosmos-sdk/types"
- "github.com/e-money/em-ledger/x/authority"
- "github.com/tendermint/tendermint/libs/rand"
"os"
+ "sync"
"testing"
+ "time"
+
+ upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
+ "github.com/e-money/em-ledger/x/authority"
+ apptypes "github.com/e-money/em-ledger/types"
+
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+ authtypes "github.com/e-money/em-ledger/x/authority/types"
"github.com/stretchr/testify/require"
+ abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
+ "github.com/tendermint/tendermint/libs/rand"
+ tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
-
- abci "github.com/tendermint/tendermint/abci/types"
)
+var configOnce sync.Once
+
func TestSimAppExportAndBlockedAddrs(t *testing.T) {
- encCfg := MakeEncodingConfig()
+ encCfg, db, app, _ := getEmSimApp(t, rand.Bytes(sdk.AddrLen))
+ app.Commit()
+
+ // Making a new app object with the db, so that initchain hasn't been called
+ app2 := NewApp(
+ log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true,
+ map[int64]bool{}, t.TempDir(), 0, encCfg, EmptyAppOptions{},
+ )
+ _, err := app2.ExportAppStateAndValidators(false, []string{})
+ require.NoError(
+ t, err, "ExportAppStateAndValidators should not have an error",
+ )
+}
+
+func getEmSimApp(
+ t *testing.T, authorityAcc sdk.AccAddress,
+) (encCfg EncodingConfig, memDB *dbm.MemDB, eMoneyApp *EMoneyApp, homeFolder string) {
+ t.Helper()
+
+ encCfg = MakeEncodingConfig()
db := dbm.NewMemDB()
- app := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, t.TempDir(), 0, encCfg, EmptyAppOptions{})
+ homeDir := t.TempDir()
+ t.Log("home dir:", homeDir)
+
+ app := NewApp(
+ log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true,
+ map[int64]bool{}, homeDir, 0, encCfg, EmptyAppOptions{},
+ )
for acc := range maccPerms {
require.True(
@@ -29,8 +64,9 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) {
}
genesisState := ModuleBasics.DefaultGenesis(encCfg.Marshaler)
- authorityState := authority.NewGenesisState(rand.Bytes(sdk.AddrLen), sdk.NewDecCoins())
- genesisState[authority.ModuleName] = encCfg.Marshaler.MustMarshalJSON(&authorityState)
+ authorityState := authtypes.GenesisState{AuthorityKey: authorityAcc.String(), MinGasPrices: sdk.NewDecCoins()}
+
+ genesisState["authority"] = encCfg.Marshaler.MustMarshalJSON(&authorityState)
stateBytes, err := json.MarshalIndent(genesisState, "", " ")
require.NoError(t, err)
@@ -42,12 +78,8 @@ func TestSimAppExportAndBlockedAddrs(t *testing.T) {
AppStateBytes: stateBytes,
},
)
- app.Commit()
- // Making a new app object with the db, so that initchain hasn't been called
- app2 := NewApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, t.TempDir(), 0, encCfg, EmptyAppOptions{})
- _, err = app2.ExportAppStateAndValidators(false, []string{})
- require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
+ return encCfg, db, app, homeFolder
}
// EmptyAppOptions is a stub implementing AppOptions
@@ -57,3 +89,318 @@ type EmptyAppOptions struct{}
func (ao EmptyAppOptions) Get(o string) interface{} {
return nil
}
+
+type emAppTests struct {
+ ctx sdk.Context
+ homeDir string
+ app *EMoneyApp
+ authority sdk.AccAddress
+}
+
+func (et emAppTests) initEmApp(t *testing.T) emAppTests {
+ t.Helper()
+
+ var err error
+ et.authority, err = sdk.AccAddressFromBech32("emoney1kt0vh0ttget0xx77g6d3ttnvq2lnxx6vp3uyl0")
+ require.NoError(t, err)
+
+ _, _, app, homeDir := getEmSimApp(t, et.authority)
+
+ et.homeDir = homeDir
+ et.app = app
+ et.ctx = app.BaseApp.NewContext(false, tmproto.Header{
+ Time: time.Now(),
+ Height: 10,
+ })
+
+ return et
+}
+
+func Test_Upgrade(t *testing.T) {
+ configOnce.Do(apptypes.ConfigureSDK)
+
+ tests := []struct {
+ suite emAppTests
+ name string
+ plan upgradetypes.Plan
+ setupUpgCond func(simApp emAppTests, plan *upgradetypes.Plan)
+ expSchedPass bool
+ qrySched bool
+ qryApply bool
+ }{
+ {
+ name: "successful time schedule",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+ plan.Time = simApp.ctx.BlockTime().Add(time.Hour)
+ },
+ expSchedPass: true,
+ },
+ {
+ name: "successful height schedule",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {},
+ expSchedPass: true,
+ },
+ {
+ name: "setting both time and height schedule",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+ plan.Time = simApp.ctx.BlockTime().Add(time.Hour)
+ },
+ expSchedPass: false,
+ },
+ {
+ name: "successful overwrite",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+
+ _, err := simApp.app.authorityKeeper.ScheduleUpgrade(
+ simApp.ctx, simApp.authority, upgradetypes.Plan{
+ Name: "alt-good",
+ Info: "new text here",
+ Height: 543210000,
+ },
+ )
+ require.NoError(t, err)
+ },
+ expSchedPass: true,
+ },
+ {
+ name: "successful overwrite future with earlier date",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+ _, err := simApp.app.authorityKeeper.ScheduleUpgrade(
+ simApp.ctx, simApp.authority, upgradetypes.Plan{
+ Name: "alt-good",
+ Info: "new text here",
+ Height: 543210000,
+ },
+ )
+ require.NoError(t, err)
+ },
+ expSchedPass: true,
+ },
+ {
+ name: "successful overwrite earlier with future date",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 543210000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+ _, err := simApp.app.authorityKeeper.ScheduleUpgrade(
+ simApp.ctx, simApp.authority, upgradetypes.Plan{
+ Name: "alt-good",
+ Info: "new text here",
+ Height: 123450000,
+ },
+ )
+ require.NoError(t, err)
+ },
+ expSchedPass: true,
+ },
+ {
+ name: "unsuccessful schedule: missing plan name",
+ plan: upgradetypes.Plan{
+ Height: 123450000,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {},
+ expSchedPass: false,
+ },
+ {
+ name: "unsuccessful time schedule: initialized, uninitialized due date in past",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {
+ plan.Time = simApp.ctx.BlockTime()
+ },
+ expSchedPass: false,
+ },
+ {
+ name: "unsuccessful height schedule: due date in past",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 1,
+ },
+ setupUpgCond: func(simApp emAppTests, plan *upgradetypes.Plan) {},
+ expSchedPass: false,
+ },
+ {
+ name: "unsuccessful schedule: schedule already executed",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ setupUpgCond: func(simEmApp emAppTests, plan *upgradetypes.Plan) {
+ simEmApp.app.upgradeKeeper.SetUpgradeHandler("all-good", func(_ sdk.Context, _ upgradetypes.Plan) {})
+ simEmApp.app.upgradeKeeper.ApplyUpgrade(
+ simEmApp.ctx, upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ Height: 123450000,
+ },
+ )
+ },
+ expSchedPass: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(
+ tt.name, func(t *testing.T) {
+ tt.suite = emAppTests{}.initEmApp(t)
+
+ // setup test case
+ tt.setupUpgCond(tt.suite, &tt.plan)
+
+ // schedule upgrade plan
+ var err error
+ _, err = tt.suite.app.authorityKeeper.ScheduleUpgrade(
+ tt.suite.ctx, tt.suite.authority, tt.plan,
+ )
+ schedPlan, hasPlan := tt.suite.app.authorityKeeper.GetUpgradePlan(tt.suite.ctx)
+
+ // validate plan side effect
+ if tt.expSchedPass {
+ require.NoError(t, err, "Upgrade() error = %v, expSchedPass %v", err, tt.expSchedPass)
+ require.Truef(t, hasPlan, "hasPlan: %t there should be a plan", hasPlan)
+ require.Equalf(t, schedPlan, tt.plan, "queried %v != %v", schedPlan, tt.plan)
+ } else {
+ require.Falsef(t, hasPlan, "hasPlan: %t plan should not exist", hasPlan)
+ require.NotEqualf(t, schedPlan, tt.plan, "queried %v == %v", schedPlan, tt.plan)
+ }
+
+ // apply and confirm plan deletion
+ if tt.expSchedPass {
+ executePlan(
+ tt.suite.ctx, t, tt.suite.app.upgradeKeeper,
+ tt.suite.app.authorityKeeper, tt.plan,
+ )
+ }
+ },
+ )
+ }
+}
+
+func Test_UpgradeByTime(t *testing.T) {
+
+ configOnce.Do(apptypes.ConfigureSDK)
+
+ tests := []struct {
+ suite emAppTests
+ name string
+ plan upgradetypes.Plan
+ blockTimes []time.Time
+ setupUpgCond func(simApp emAppTests, blockTimes []time.Time, plan *upgradetypes.Plan)
+ expPass bool
+ qrySched bool
+ qryApply bool
+ }{
+ {
+ name: "successful time plan + 1minute",
+ plan: upgradetypes.Plan{
+ Name: "all-good",
+ Info: "some text here",
+ },
+ setupUpgCond: func(simApp emAppTests, blockTimes []time.Time, plan *upgradetypes.Plan) {
+ const duration = 10 * time.Minute
+ plan.Time = simApp.ctx.BlockTime().Add(duration)
+ blockTimes = []time.Time{
+ simApp.ctx.BlockTime(),
+ simApp.ctx.BlockTime().Add(time.Minute),
+ plan.Time.Add(-time.Nanosecond),
+ }
+ },
+ expPass: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(
+ tt.name, func(t *testing.T) {
+ tt.suite = emAppTests{}.initEmApp(t)
+
+ // setup test case
+ tt.setupUpgCond(tt.suite, tt.blockTimes, &tt.plan)
+
+ // schedule upgrade plan
+ var err error
+ _, err = tt.suite.app.authorityKeeper.ScheduleUpgrade(
+ tt.suite.ctx, tt.suite.authority, tt.plan,
+ )
+ schedPlan, hasPlan := tt.suite.app.authorityKeeper.GetUpgradePlan(tt.suite.ctx)
+
+ // validate plan side effect
+ if tt.expPass {
+ require.NoError(t, err, "Upgrade() error = %v, expSchedPass %v", err, tt.expPass)
+ require.Truef(
+ t, hasPlan, "hasPlan: %t there should be a plan",
+ hasPlan,
+ )
+ require.Equalf(
+ t, schedPlan, tt.plan, "queried %v != %v", schedPlan,
+ tt.plan,
+ )
+ } else {
+ require.Falsef(
+ t, hasPlan, "hasPlan: %t plan should not exist", hasPlan,
+ )
+ require.NotEqualf(
+ t, schedPlan, tt.plan, "queried %v == %v", schedPlan,
+ tt.plan,
+ )
+ }
+
+ // advance chain and confirm plan execution
+ tt.suite.app.authorityKeeper.GetUpgradePlan(tt.suite.ctx)
+ for _, blockTime := range tt.blockTimes {
+ tt.suite.ctx = tt.suite.ctx.WithBlockTime(blockTime)
+ require.Falsef(t, schedPlan.ShouldExecute(tt.suite.ctx), "premature timing for executing plan")
+ }
+ // move forward to execution time
+ tt.suite.ctx = tt.suite.ctx.WithBlockTime(schedPlan.Time)
+ require.Truef(t, schedPlan.ShouldExecute(tt.suite.ctx), "plan should be ripe for execution")
+
+ executePlan(
+ tt.suite.ctx, t, tt.suite.app.upgradeKeeper,
+ tt.suite.app.authorityKeeper, tt.plan,
+ )
+ },
+ )
+ }
+}
+
+func executePlan(
+ ctx sdk.Context, t *testing.T, uk upgradekeeper.Keeper, ak authority.Keeper,
+ plan upgradetypes.Plan,
+) {
+ uk.SetUpgradeHandler(plan.Name, func(_ sdk.Context, _ upgradetypes.Plan) {})
+
+ uk.ApplyUpgrade(ctx, plan)
+
+ schedPlan, hasPlan := ak.GetUpgradePlan(ctx)
+ require.Falsef(t, hasPlan, "hasPlan: %t plan should not exist", hasPlan)
+ require.NotEqualf(t, schedPlan, plan, "queried %v == %v", schedPlan, plan)
+}
diff --git a/docs/proto/em/proto-docs.md b/docs/proto/em/proto-docs.md
index 5fbd8c6d..a2f746b1 100644
--- a/docs/proto/em/proto-docs.md
+++ b/docs/proto/em/proto-docs.md
@@ -14,6 +14,8 @@
- [em/authority/v1/query.proto](#em/authority/v1/query.proto)
- [QueryGasPricesRequest](#em.authority.v1.QueryGasPricesRequest)
- [QueryGasPricesResponse](#em.authority.v1.QueryGasPricesResponse)
+ - [QueryUpgradePlanRequest](#em.authority.v1.QueryUpgradePlanRequest)
+ - [QueryUpgradePlanResponse](#em.authority.v1.QueryUpgradePlanResponse)
- [Query](#em.authority.v1.Query)
@@ -24,6 +26,8 @@
- [MsgDestroyIssuerResponse](#em.authority.v1.MsgDestroyIssuerResponse)
- [MsgReplaceAuthority](#em.authority.v1.MsgReplaceAuthority)
- [MsgReplaceAuthorityResponse](#em.authority.v1.MsgReplaceAuthorityResponse)
+ - [MsgScheduleUpgrade](#em.authority.v1.MsgScheduleUpgrade)
+ - [MsgScheduleUpgradeResponse](#em.authority.v1.MsgScheduleUpgradeResponse)
- [MsgSetGasPrices](#em.authority.v1.MsgSetGasPrices)
- [MsgSetGasPricesResponse](#em.authority.v1.MsgSetGasPricesResponse)
@@ -256,6 +260,31 @@
+
+
+
+### QueryUpgradePlanRequest
+
+
+
+
+
+
+
+
+
+### QueryUpgradePlanResponse
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `plan` | [cosmos.upgrade.v1beta1.Plan](#cosmos.upgrade.v1beta1.Plan) | | |
+
+
+
+
+
@@ -271,6 +300,7 @@
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `GasPrices` | [QueryGasPricesRequest](#em.authority.v1.QueryGasPricesRequest) | [QueryGasPricesResponse](#em.authority.v1.QueryGasPricesResponse) | | GET|/e-money/authority/v1/gasprices|
+| `UpgradePlan` | [QueryUpgradePlanRequest](#em.authority.v1.QueryUpgradePlanRequest) | [QueryUpgradePlanResponse](#em.authority.v1.QueryUpgradePlanResponse) | | GET|/e-money/authority/v1/upgrade_plan|
@@ -367,6 +397,32 @@
+
+
+### MsgScheduleUpgrade
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `authority` | [string](#string) | | |
+| `plan` | [cosmos.upgrade.v1beta1.Plan](#cosmos.upgrade.v1beta1.Plan) | | |
+
+
+
+
+
+
+
+
+### MsgScheduleUpgradeResponse
+
+
+
+
+
+
+
### MsgSetGasPrices
@@ -410,6 +466,7 @@
| `DestroyIssuer` | [MsgDestroyIssuer](#em.authority.v1.MsgDestroyIssuer) | [MsgDestroyIssuerResponse](#em.authority.v1.MsgDestroyIssuerResponse) | | |
| `SetGasPrices` | [MsgSetGasPrices](#em.authority.v1.MsgSetGasPrices) | [MsgSetGasPricesResponse](#em.authority.v1.MsgSetGasPricesResponse) | | |
| `ReplaceAuthority` | [MsgReplaceAuthority](#em.authority.v1.MsgReplaceAuthority) | [MsgReplaceAuthorityResponse](#em.authority.v1.MsgReplaceAuthorityResponse) | | |
+| `ScheduleUpgrade` | [MsgScheduleUpgrade](#em.authority.v1.MsgScheduleUpgrade) | [MsgScheduleUpgradeResponse](#em.authority.v1.MsgScheduleUpgradeResponse) | | |
diff --git a/multisigauthority_test.go b/multisigauthority_test.go
index ae35a723..3b14cd75 100644
--- a/multisigauthority_test.go
+++ b/multisigauthority_test.go
@@ -101,14 +101,6 @@ var _ = Describe("Authority", func() {
)
Expect(err).To(BeNil())
- // create/revoke issuer with both the former and the new authority
- // former singlesig first
- ok = nt.AuthCreatesIssuer(emcli, keystore.Authority, key1)
- Expect(ok).To(BeTrue())
- _, success, err = emcli.AuthorityDestroyIssuer(keystore.Authority, key1)
- Expect(success).To(BeTrue())
- Expect(err).ToNot(HaveOccurred())
-
// current multisig authority now
// create-issuer
execAuthMSigTx(
diff --git a/networks/.gitignore b/networks/.gitignore
new file mode 100644
index 00000000..0763333a
--- /dev/null
+++ b/networks/.gitignore
@@ -0,0 +1 @@
+.emd/
\ No newline at end of file
diff --git a/networks/docker/Makefile b/networks/docker/Makefile
index e3196410..459c7d14 100644
--- a/networks/docker/Makefile
+++ b/networks/docker/Makefile
@@ -1,8 +1,16 @@
# Makefile for the "emdnode" docker image.
-all: emdnode
+all: emdnode cosmovisor test-upg
emdnode:
docker build --tag emoney/emdnode emdnode
-.PHONY: all emdnode
\ No newline at end of file
+cosmovisor:
+ docker build cosmovisor --tag emoney/cosmovisor
+
+test-upg:
+ docker build test-upg --build-arg branch=$$(git rev-parse --abbrev-ref HEAD) --build-arg version=test-upg-0.2.0 --tag emoney/test-upg
+
+# todo (reviewer): please note the rest-server is not a command anymore. Please enable `api` section in `app.toml` instead
+
+.PHONY: all emdnode cosmovisor test-upg
\ No newline at end of file
diff --git a/networks/docker/cosmovisor/Dockerfile b/networks/docker/cosmovisor/Dockerfile
new file mode 100644
index 00000000..d72cac76
--- /dev/null
+++ b/networks/docker/cosmovisor/Dockerfile
@@ -0,0 +1,7 @@
+# This software is Copyright (c) 2019-2021 e-Money A/S. It is not offered under an open source license.
+#
+# Please contact partners@e-money.com for licensing related questions.
+
+FROM golang:1.16-buster AS build-env
+
+RUN go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@latest
\ No newline at end of file
diff --git a/networks/docker/emdnode/Dockerfile b/networks/docker/emdnode/Dockerfile
index 59ffbe7a..75486c1c 100644
--- a/networks/docker/emdnode/Dockerfile
+++ b/networks/docker/emdnode/Dockerfile
@@ -2,11 +2,11 @@
#
# Please contact partners@e-money.com for licensing related questions.
-FROM alpine:3.7
+FROM ubuntu:18.04
-RUN apk update && \
- apk upgrade && \
- apk --no-cache add curl jq file
+RUN apt-get update && \
+ apt-get -y upgrade && \
+ apt-get -y install curl jq file
VOLUME /emoney
WORKDIR /emoney
@@ -15,5 +15,4 @@ ENTRYPOINT ["/usr/bin/wrapper.sh"]
CMD ["start"]
STOPSIGNAL SIGTERM
-COPY wrapper.sh /usr/bin/wrapper.sh
-
+COPY wrapper.sh /usr/bin/wrapper.sh
\ No newline at end of file
diff --git a/networks/docker/emdnode/wrapper.sh b/networks/docker/emdnode/wrapper.sh
index da42ae87..6e87dd6e 100755
--- a/networks/docker/emdnode/wrapper.sh
+++ b/networks/docker/emdnode/wrapper.sh
@@ -10,9 +10,6 @@
BINARY=/emoney/${BINARY:-emd-linux}
ID=${ID:-0}
LOG=${LOG:-emd.log}
-# LOGLEVEL=${LOGLEVEL:-emz:info,x/inflation:info,x/liquidityprovider:info,main:info,state:info,*:error}
-# TODO (reviewer) : the SDK uses the zap logger now. without fine grained configuration options. There should be an open issue in the repo already
-LOGLEVEL=info
##
## Assert linux binary
##
@@ -31,11 +28,24 @@ fi
##
export EMDHOME="/emoney/node${ID}"
-if [ -d "`dirname ${EMDHOME}/${LOG}`" ]; then
- "$BINARY" --home "$EMDHOME" "$@" --log_level ${LOGLEVEL} --trace --pruning=nothing | tee "${EMDHOME}/${LOG}"
+# setup cosmovisor
+mkdir -p "$EMDHOME/cosmovisor/genesis/bin"
+cp /emoney/emd-linux "$EMDHOME/cosmovisor/genesis/bin"
+
+export DAEMON_ALLOW_DOWNLOAD_BINARIES=true
+export DAEMON_RESTART_AFTER_UPGRADE=true
+export DAEMON_HOME=$EMDHOME
+# link chain launcher to cosmovisor with linux emd binary
+export DAEMON_NAME=emd-linux
+BINARY=/emoney/cosmovisor
+UPG_LOC="$EMDHOME"/cosmovisor/upgrades/test-upg-0.2.0/bin
+mkdir -p "$UPG_LOC"
+cp /emoney/emdupg-linux "$UPG_LOC"/emd-linux
+
+if [ -d "$(dirname "${EMDHOME}"/"${LOG}")" ]; then
+ "$BINARY" --home "$EMDHOME" "$@" | tee "${EMDHOME}/${LOG}"
else
- "$BINARY" --home "$EMDHOME" "$@" --log_level ${LOGLEVEL} --trace --pruning=nothing
+ "$BINARY" --home "$EMDHOME" "$@"
fi
-chmod 777 -R /emoney
-
+chmod 777 -R /emoney
\ No newline at end of file
diff --git a/networks/docker/test-upg/Dockerfile b/networks/docker/test-upg/Dockerfile
new file mode 100644
index 00000000..d8cb6108
--- /dev/null
+++ b/networks/docker/test-upg/Dockerfile
@@ -0,0 +1,17 @@
+FROM golang:1.16-buster
+
+ARG branch
+ARG version
+
+# checkout and build linux binary
+RUN cd /go/src && \
+ git clone https://github.com/e-money/em-ledger.git && \
+ cd em-ledger && \
+ git checkout $branch && \
+ sed -i -e '/bep3.NewKeeper/r networks/upg/upgfunc.txt' app.go && \
+ git tag $version && \
+ BIN_PREFIX=-linux LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 make build
+
+# build MacOS binary
+WORKDIR /go/src/em-ledger
+RUN LEDGER_ENABLED=false GOOS=darwin GOARCH=amd64 make build
\ No newline at end of file
diff --git a/networks/upg/README.md b/networks/upg/README.md
new file mode 100644
index 00000000..58a04c70
--- /dev/null
+++ b/networks/upg/README.md
@@ -0,0 +1,76 @@
+## Guide for testing the upgrade module
+#### Overview
+This document is an interactive guide for testing the upgrade module with a single docker-less e-money node.
+
+Please note if you'd rather test the upgrade module within the **e-money local-testnet** run:
+
+```shell
+cd em-ledger
+make build-docker
+make build-all
+go test -v --tags="bdd" bdd_test.go upgrade_test.go
+```
+
+Two new docker images defined in em-ledger/networks/docker:
+
+1. `emoney/cosmovisor` which builds a linux cosmovisor binary for use within the e-money local-testnet.
+
+2. `emoney/test-upg` which builds a test upgrade mode with a trivial upgrade module handler changing the gas-fees as part of the upgrade migration process.
+
+Note these scripts at **em-ledger/networks/upg**:
+* `README.md` (this doc)
+* `startcv` (starts a single e-money node with cosmovisor)
+* `upg-sched` schedule an upgrade by passing the upgrade block height
+* `upg-sched-srv` optional documentation setup and schedule command for upgrading with server downloaded binary
+* `upgfunc.txt` Go snippet to be inserted as the upgrade module handler in the *upgrade* binary.
+
+### Components installation
+Build the revamped Docker, Linux artifacts
+```shell
+make build-docker
+make build-all
+```
+As a result these artifacts generate within the build folder
+```shell
+.rwxrwxr-x 1 15M usr 3 Aug 13:06 cosmovisor
+.rwxrwxr-x 1 60M usr 3 Aug 13:06 emd
+.rwxrwxr-x 1 61M usr 3 Aug 13:06 emd-linux
+.rwxrwxr-x 1 60M usr 3 Aug 13:06 emdupg
+.rwxrwxr-x 1 60M usr 3 Aug 13:06 emdupg-linux
+```
+`emdupg` is the *upgrade* emd binary* with the migration handler setting the gas-prices upon the chain upgrade.
+
+**The code for the upgrade handler is checked-in the *`upgrade-emd-test`* branch.*
+### Install cosmovisor
+
+#### For interactive testing and general use
+Please note, the cosmovisor binary built above is a `linux` binary for use within the *local-testnet*
+```shell
+go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@latest
+
+# test installation success
+cosmovisor version
+DAEMON_NAME is not set
+```
+
+### Launch network to upgrade
+```shell
+# Optionally in a separate pane or terminal tab
+cd networks/upg
+./startcv
+
+cd networks/upg
+# schedule upgrade at future block height 6
+# if you overshoot retry with lower block height
+./upg-sched 6
+
+# wait for the upgrade
+# check version, upgraded gas-prices
+.emd/cosmovisor/current/bin/emd version # test-upg-0.2.0
+.emd/cosmovisor/current/bin/emd q authority gas-prices
+min_gas_prices:
+- amount: "1.000000000000000000"
+ denom: ungm
+
+#success!
+```
diff --git a/networks/upg/cpemd b/networks/upg/cpemd
new file mode 100755
index 00000000..48ef406a
--- /dev/null
+++ b/networks/upg/cpemd
@@ -0,0 +1,49 @@
+#!/bin/zsh
+
+# Copying the upgrade and present/soon to be legacy binary in the cosmovisor genesis folder
+# Note the cosmovisor folder structure before the upgrade
+# em-ledger/networks/upg/.emd/cosmovisor
+# ├── current -> /Users/user/go/src/github.com/e-money/em-ledger/networks/upg/.emd/cosmovisor/genesis/bin/emd
+# ├── genesis
+# │ └── bin
+# │ └── emd
+# └── upgrades
+# └── test-upg-0.2.0
+# └── bin
+# └── emd
+
+set -e
+
+# cosmovisor constant
+export DAEMON_NAME=emd
+
+mkdir -p .emd
+export DAEMON_HOME=$PWD/.emd
+pushd -q ../../
+EM_LEDGER_LOC=$PWD
+popd -q
+
+echo "node home: $DAEMON_HOME"
+
+# copy soon to be the legacy binary
+COSMOVISOR_HOME="$EM_LEDGER_LOC"/networks/upg/.emd/cosmovisor
+
+# clean up previous sticky upgrade
+rm -f "$COSMOVISOR_HOME"/current
+
+mkdir -p "$COSMOVISOR_HOME"/genesis/bin
+cp "$EM_LEDGER_LOC"/build/emd "$COSMOVISOR_HOME"/genesis/bin
+UPG_LOC="$COSMOVISOR_HOME"/upgrades/test-upg-0.2.0/bin
+
+mkdir -p "$UPG_LOC"
+if [ "$(uname)" = "Linux" ]; then
+ cp "$EM_LEDGER_LOC"/build/emdupg-linux "$UPG_LOC"/emd
+else
+ cp "$EM_LEDGER_LOC"/build/emdupg "$UPG_LOC"/emd
+fi
+
+echo "legacy or current binary:"
+ls "$COSMOVISOR_HOME"/genesis/bin/emd
+echo "upgrade binary:"
+ls "$UPG_LOC"/emd
+echo "current version: $(cosmovisor version)"
\ No newline at end of file
diff --git a/networks/upg/startcv b/networks/upg/startcv
new file mode 100755
index 00000000..3a070e80
--- /dev/null
+++ b/networks/upg/startcv
@@ -0,0 +1,53 @@
+#!/bin/zsh
+
+set -ev
+
+##### em-ledger single node cosmovisor setup
+export DAEMON_NAME=emd
+export DAEMON_ALLOW_DOWNLOAD_BINARIES=true
+export DAEMON_RESTART_AFTER_UPGRADE=true
+
+# optionally uncomment to copy future upgrade binary in location if
+# auto-downloading is not available as a primary or none at all
+# by default we assume it is on and the upgrade binary is not available
+# locally: DAEMON_RESTART_AFTER_UPGRADE=true
+#./cpupgemd
+
+EMD_NODE=$PWD/.emd
+EMD=../../build/emd
+
+# do not do this in production
+# do not delete cosmovisor if it exists
+rm -rf "$EMD_NODE"/config
+rm -rf "$EMD_NODE"/data
+rm -rf "$EMD_NODE"/keyring-test
+
+./cpemd
+
+$EMD unsafe-reset-all --home=$EMD_NODE
+
+$EMD init test --chain-id=test --home="$EMD_NODE" --overwrite
+$EMD keys add validator --keyring-backend=test --home="$EMD_NODE"
+$EMD add-genesis-account "$($EMD keys show validator -a --keyring-backend=test --home="$EMD_NODE")" 1000000000stake,1000000000ungm --home=$EMD_NODE
+$EMD gentx validator 500000000stake --keyring-backend=test --home="$EMD_NODE" --chain-id=test
+
+# create genesis emoney1xue7fm6es84jze49grm4slhlmr4ffz8a3u7g3t to set the authority later
+AUTH_SEED="fuel public electric luxury short upper quit edge ginger need olive gesture time useful stadium exhaust since team pond wool type flat focus narrow"
+(echo "$AUTH_SEED"; echo "$AUTH_SEED") | $EMD keys add authoritykey --recover --keyring-backend=test --home="$EMD_NODE"
+AUTHORITY_ADDR=$($EMD keys show authoritykey -a --keyring-backend=test --home="$EMD_NODE")
+$EMD add-genesis-account "$AUTHORITY_ADDR" 1000000000000ungm --home=$EMD_NODE
+
+$EMD collect-gentxs --home="$EMD_NODE"
+
+# set the auth address as the chain authority
+AUTHORITY_ADDR_VAL=".app_state.authority.key=\"$AUTHORITY_ADDR\""
+jq $AUTHORITY_ADDR_VAL < "$EMD_NODE"/config/genesis.json > "$EMD_NODE"/config/tmp_genesis.json
+mv "$EMD_NODE"/config/tmp_genesis.json "$EMD_NODE"/config/genesis.json
+
+export DAEMON_HOME=$EMD_NODE
+
+echo "node home: $DAEMON_HOME"
+
+cosmovisor version
+
+cosmovisor start --home="$DAEMON_HOME"
\ No newline at end of file
diff --git a/networks/upg/upg-sched b/networks/upg/upg-sched
new file mode 100755
index 00000000..7ac23143
--- /dev/null
+++ b/networks/upg/upg-sched
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# $1 : choose a future block height to upgrade
+
+set -e
+
+EMD=.emd/cosmovisor/current/bin/emd
+
+$EMD version
+$EMD q authority gas-prices --home=.emd --node tcp://localhost:26657 --chain-id test
+$EMD q authority upgrade-plan --home=.emd --node tcp://localhost:26657 --chain-id test
+
+# schedule upgrade
+$EMD tx authority schedule-upgrade authoritykey test-upg-0.2.0 --upgrade-height "$1" --yes --from authoritykey --home=".emd" --node tcp://localhost:26657 --chain-id test --keyring-backend test
+
+# confirm upg plan
+$EMD q authority upgrade-plan --home=.emd --node tcp://localhost:26657 --chain-id test
+
+# ---------- after upgrade --------->
+$EMD q authority gas-prices --home=.emd --node tcp://localhost:26657 --chain-id test
+#$EMD q authority upgrade-plan --home=.emd --node tcp://localhost:26657 --chain-id test # is nil again
+$EMD version # test-upg-0.2.0
diff --git a/networks/upg/upg-sched-srv b/networks/upg/upg-sched-srv
new file mode 100755
index 00000000..e50be5ea
--- /dev/null
+++ b/networks/upg/upg-sched-srv
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+set -ev
+
+# Preconditions server auto download:
+# export DAEMON_ALLOW_DOWNLOAD_BINARIES=true
+# make emdupg
+# mkdir -p /srv/upgemd/test-upg-0.2.0
+# cp build/emdupg /srv/upgemd/test-upg-0.2.0
+# zip /srv/upgemd/test-upg-0.2.0/emd.zip /srv/upgemd/test-upg-0.2.0/emd
+# save sha value to clipboard
+# sha256sum /srv/upgemd/test-upg-0.2.0/emd.zip | xsel -i -b
+# cd /srv/upgemd
+# start a web server in the
+# python3 -m http.server 8765
+
+EMD=.emd/cosmovisor/current/bin/emd
+
+# choose a future height
+$EMD tx authority schedule-upgrade authoritykey test-upg-0.2.0 --upgrade-height 6 --upgrade-info '{"binaries":{"linux/amd64":"http://localhost:8765/test-upg-0.2.0/emd.zip?checksum=sha256:cadd5b52fe90a04e20b2cbb93291b0d1d0204f17b64b2215eb09f5dc78a127f1"}}' --yes --from authoritykey --home="$DAEMON_HOME" --node tcp://localhost:26657 --chain-id test --keyring-backend test
\ No newline at end of file
diff --git a/networks/upg/upgfunc.txt b/networks/upg/upgfunc.txt
new file mode 100644
index 00000000..1830bbda
--- /dev/null
+++ b/networks/upg/upgfunc.txt
@@ -0,0 +1,31 @@
+
+ /*
+ * This is a test handler for trying out cosmovisor
+ * Setting gas to One ungm
+ **/
+ const testUpgradeHandler = "test-upg-0.2.0"
+ app.upgradeKeeper.SetUpgradeHandler(testUpgradeHandler, func(ctx sdk.Context, plan upgradetypes.Plan) {
+ genesisAuth := app.authorityKeeper.GetAuthoritySet(ctx)
+ if genesisAuth.Address == "" {
+ panic("authority should be set in genesis")
+ }
+
+ authAcc, err := sdk.AccAddressFromBech32(genesisAuth.Address)
+ if err != nil {
+ panic(err)
+ }
+
+ newGas := sdk.DecCoins{
+ sdk.NewDecCoin("ungm", sdk.OneInt()),
+ }
+
+ _, err = app.authorityKeeper.SetGasPrices(ctx, authAcc, newGas)
+ if err != nil {
+ panic(err)
+ }
+
+ gasPrices := app.authorityKeeper.GetGasPrices(ctx)
+ if gasPrices.Empty() || !gasPrices.IsEqual(newGas) {
+ panic(fmt.Sprintf("expected Gas: %+v != store Gas: %+v", newGas, gasPrices))
+ }
+ })
diff --git a/networks/utils/startemd b/networks/utils/startemd
new file mode 100755
index 00000000..3c10687e
--- /dev/null
+++ b/networks/utils/startemd
@@ -0,0 +1,44 @@
+#!/bin/zsh
+
+set -ev
+
+# locate emd binary
+if [[ -f $PWD/../../build/emd ]]; then
+ EMD_NODE=$PWD/.emd
+ pushd -q ../../build
+ # save absolute path of emd required by cosmovisor
+ EMD=$PWD/emd
+ popd -q
+else
+ echo "emd binary not found in $PWD. Please run make to create the emd binary"
+ exit 1
+fi
+
+# destructive
+# do not do this in production
+rm -rf "$EMD_NODE"/config
+rm -rf "$EMD_NODE"/data
+rm -rf "$EMD_NODE"/keyring-test
+# do not delete cosmovisor if it exists
+
+$EMD unsafe-reset-all --home=$EMD_NODE
+
+$EMD init test --chain-id=test --home="$EMD_NODE" --overwrite
+$EMD keys add validator --keyring-backend=test --home="$EMD_NODE"
+$EMD add-genesis-account "$($EMD keys show validator -a --keyring-backend=test --home="$EMD_NODE")" 1000000000stake,1000000000ungm --home=$EMD_NODE
+$EMD gentx validator 500000000stake --keyring-backend=test --home="$EMD_NODE" --chain-id=test
+
+# create genesis emoney1xue7fm6es84jze49grm4slhlmr4ffz8a3u7g3t to set the authority later
+AUTH_SEED="fuel public electric luxury short upper quit edge ginger need olive gesture time useful stadium exhaust since team pond wool type flat focus narrow"
+(echo "$AUTH_SEED"; echo "$AUTH_SEED") | $EMD keys add authoritykey --recover --keyring-backend=test --home="$EMD_NODE"
+AUTHORITY_ADDR=$($EMD keys show authoritykey -a --keyring-backend=test --home="$EMD_NODE")
+$EMD add-genesis-account "$AUTHORITY_ADDR" 1000000000000ungm --home=$EMD_NODE
+
+$EMD collect-gentxs --home="$EMD_NODE"
+
+# set the auth address as the chain authority
+AUTHORITY_ADDR_VAL=".app_state.authority.key=\"$AUTHORITY_ADDR\""
+jq $AUTHORITY_ADDR_VAL < "$EMD_NODE"/config/genesis.json > "$EMD_NODE"/config/tmp_genesis.json
+mv "$EMD_NODE"/config/tmp_genesis.json "$EMD_NODE"/config/genesis.json
+
+$EMD start --home="$EMD_NODE"
\ No newline at end of file
diff --git a/networktest/emcli.go b/networktest/emcli.go
index 76671dc3..a5a7e830 100644
--- a/networktest/emcli.go
+++ b/networktest/emcli.go
@@ -51,6 +51,12 @@ func (cli Emcli) AuthorityCreateIssuer(authority, issuer Key, denoms ...string)
return execCmdWithInput(args, KeyPwd)
}
+func (cli Emcli) UpgSchedByHeight(authority Key, planName string, height int64) (string, bool, error) {
+ args := cli.addTransactionFlags("tx", "authority", "schedule-upgrade",
+ authority.name, planName, "--upgrade-height", strconv.FormatInt(height, 10))
+ return execCmdWithInput(args, KeyPwd)
+}
+
func (cli Emcli) AuthorityDestroyIssuer(authority, issuer Key) (string, bool, error) {
args := cli.addTransactionFlags("tx", "authority", "destroy-issuer", authority.name, issuer.GetAddress())
return execCmdWithInput(args, KeyPwd)
@@ -63,6 +69,7 @@ func (cli Emcli) CustomCommand(params ...string) (string, error) {
for _, param := range params {
if re.MatchString(param) {
checkTxRes = false
+ break
}
}
args := cli.addTransactionFlags(params...)
@@ -81,6 +88,11 @@ func (cli Emcli) AuthoritySetMinGasPrices(authority Key, minGasPrices string, pa
return execCmdWithInput(args, KeyPwd)
}
+func (cli Emcli) QueryUpgSched() ([]byte, error) {
+ args := cli.addQueryFlags("query", "authority", "upgrade-plan")
+ return execCmdAndCollectResponse(args)
+}
+
func (cli Emcli) QueryBuybackBalance() ([]byte, error) {
args := cli.addQueryFlags("query", "buyback", "balance")
return execCmdAndCollectResponse(args)
diff --git a/proto/em/authority/v1/query.proto b/proto/em/authority/v1/query.proto
index e942eddf..9bacb134 100644
--- a/proto/em/authority/v1/query.proto
+++ b/proto/em/authority/v1/query.proto
@@ -4,6 +4,7 @@ package em.authority.v1;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
import "google/api/annotations.proto";
+import "cosmos/upgrade/v1beta1/upgrade.proto";
option go_package = "github.com/e-money/em-ledger/x/authority/types";
@@ -11,6 +12,10 @@ service Query {
rpc GasPrices(QueryGasPricesRequest) returns (QueryGasPricesResponse) {
option (google.api.http).get = "/e-money/authority/v1/gasprices";
};
+
+ rpc UpgradePlan(QueryUpgradePlanRequest) returns (QueryUpgradePlanResponse){
+ option (google.api.http).get = "/e-money/authority/v1/upgrade_plan";
+ }
}
message QueryGasPricesRequest {}
@@ -24,3 +29,12 @@ message QueryGasPricesResponse {
(gogoproto.nullable) = false
];
}
+
+message QueryUpgradePlanRequest {}
+
+message QueryUpgradePlanResponse {
+ cosmos.upgrade.v1beta1.Plan plan = 1 [
+ (gogoproto.moretags) = "yaml:\"plan\"",
+ (gogoproto.nullable) = false
+ ];
+}
\ No newline at end of file
diff --git a/proto/em/authority/v1/tx.proto b/proto/em/authority/v1/tx.proto
index f95d77db..1dd46a20 100644
--- a/proto/em/authority/v1/tx.proto
+++ b/proto/em/authority/v1/tx.proto
@@ -3,6 +3,7 @@ package em.authority.v1;
import "gogoproto/gogo.proto";
import "cosmos/base/v1beta1/coin.proto";
+import "cosmos/upgrade/v1beta1/upgrade.proto";
option go_package = "github.com/e-money/em-ledger/x/authority/types";
@@ -15,6 +16,8 @@ service Msg {
rpc SetGasPrices(MsgSetGasPrices) returns (MsgSetGasPricesResponse);
rpc ReplaceAuthority(MsgReplaceAuthority) returns (MsgReplaceAuthorityResponse);
+
+ rpc ScheduleUpgrade(MsgScheduleUpgrade) returns (MsgScheduleUpgradeResponse);
}
message MsgCreateIssuer {
@@ -51,4 +54,14 @@ message MsgReplaceAuthority {
message MsgReplaceAuthorityResponse {
string new_authority_address = 1 [ (gogoproto.moretags) = "yaml:\"new_authority_address\"" ];
-}
\ No newline at end of file
+}
+
+message MsgScheduleUpgrade {
+ string authority = 1 [ (gogoproto.moretags) = "yaml:\"authority\"" ];
+ cosmos.upgrade.v1beta1.Plan plan = 2 [
+ (gogoproto.moretags) = "yaml:\"plan\"",
+ (gogoproto.nullable) = false
+ ];
+}
+
+message MsgScheduleUpgradeResponse {}
\ No newline at end of file
diff --git a/upgrade_test.go b/upgrade_test.go
new file mode 100644
index 00000000..3d9b4061
--- /dev/null
+++ b/upgrade_test.go
@@ -0,0 +1,67 @@
+// This software is Copyright (c) 2019-2020 e-Money A/S. It is not offered under an open source license.
+//
+// Please contact partners@e-money.com for licensing related questions.
+
+// +build bdd
+
+package emoney_test
+
+import (
+ nt "github.com/e-money/em-ledger/networktest"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/tidwall/gjson"
+)
+
+var _ = Describe("Upgrade", func() {
+ emcli := testnet.NewEmcli()
+
+ var Authority = testnet.Keystore.Authority
+
+ Describe("Authority manages issuers", func() {
+ It("creates a new testnet", createNewTestnet)
+
+ It("upgrade nodes and confirm", func() {
+ const (
+ name = "test-upg-0.2.0"
+ )
+
+ chainHeight, err := nt.GetHeight()
+ Expect(err).ToNot(HaveOccurred())
+
+ const upgDelta = 5
+ upgHeight := chainHeight + upgDelta
+
+ _, success, err := emcli.UpgSchedByHeight(Authority, name,
+ upgHeight,
+ )
+ Expect(err).ToNot(HaveOccurred())
+ Expect(success).To(BeTrue())
+
+ bz, err := emcli.QueryUpgSched()
+ Expect(err).ToNot(HaveOccurred())
+
+ upgPlan := gjson.ParseBytes(bz).Get("plan")
+
+ resName := upgPlan.Get("name").Str
+ Expect(resName).To(Equal(name))
+ resUpgHeight := upgPlan.Get("height").Int()
+ Expect(resUpgHeight).To(BeEquivalentTo(upgHeight))
+
+ // wait till the upgrade
+ newHeight, err := nt.IncChain(upgDelta + 1)
+ Expect(err).ToNot(HaveOccurred())
+ Expect(newHeight > chainHeight+upgDelta).To(BeTrue())
+
+ // if we made it here, the upgrade succeeded
+ bz, err = emcli.QueryUpgSched()
+ Expect(err).ToNot(HaveOccurred())
+
+ // assert that the upgrade plan zeroed out
+ upgPlan = gjson.ParseBytes(bz).Get("plan")
+
+ resName = upgPlan.Get("name").Str
+ Expect(resName).To(HaveLen(0))
+ })
+ })
+})
diff --git a/x/authority/client/cli/query.go b/x/authority/client/cli/query.go
index b31faf9b..6aacfccf 100644
--- a/x/authority/client/cli/query.go
+++ b/x/authority/client/cli/query.go
@@ -22,6 +22,7 @@ func GetQueryCmd() *cobra.Command {
cmd.AddCommand(
GetGasPricesCmd(),
+ GetUpgradePlanCmd(),
)
return cmd
@@ -50,3 +51,27 @@ func GetGasPricesCmd() *cobra.Command {
flags.AddQueryFlagsToCmd(cmd)
return cmd
}
+
+func GetUpgradePlanCmd() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "upgrade-plan",
+ Short: "Query the current upgrade plan",
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, _ []string) error {
+ clientCtx, err := client.GetClientQueryContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ queryClient := types.NewQueryClient(clientCtx)
+ res, err := queryClient.UpgradePlan(cmd.Context(), &types.QueryUpgradePlanRequest{})
+ if err != nil {
+ return err
+ }
+
+ return clientCtx.PrintProto(res)
+ },
+ }
+ flags.AddQueryFlagsToCmd(cmd)
+ return cmd
+}
diff --git a/x/authority/client/cli/tx.go b/x/authority/client/cli/tx.go
index df4a9e27..6022a5b6 100644
--- a/x/authority/client/cli/tx.go
+++ b/x/authority/client/cli/tx.go
@@ -5,10 +5,15 @@
package cli
import (
+ "time"
+
+ sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
+
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
+ upgtypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
"github.com/e-money/em-ledger/util"
"github.com/e-money/em-ledger/x/authority/types"
"github.com/spf13/cobra"
@@ -26,6 +31,7 @@ func GetTxCmd() *cobra.Command {
getCmdDestroyIssuer(),
getCmdSetGasPrices(),
GetCmdReplaceAuthority(),
+ GetCmdScheduleUpgrade(),
)
return authorityCmds
@@ -171,3 +177,88 @@ For a 24-hour grace period the former authority key is equivalent to the new one
flags.AddTxFlagsToCmd(cmd)
return cmd
}
+
+const (
+ UpgHeight = "upgrade-height"
+ UpgTime = "upgrade-time"
+ UpgInfo = "upgrade-info"
+)
+
+func GetCmdScheduleUpgrade() *cobra.Command {
+ var (
+ upgHeightVal int64
+ upgInfoVal string
+ )
+
+ cmd := &cobra.Command{
+ Use: "schedule-upgrade [authority_key_or_address] plan_name",
+ Short: "Schedule a software upgrade",
+ Example: `emd tx authority schedule-upgrade someplan --upgrade-height 2001 --from emoney1xue7fm6es84jze49grm4slhlmr4ffz8a3u7g3t 0.43
+emd tx authority schedule-upgrade sdk-v0.43.0 --upgrade-height 2001 --from emoney1xue7fm6es84jze49grm4slhlmr4ffz8a3u7g3t --upgrade-info '{"binaries":{"linux/amd64":"http://localhost:8765/test-upg-0.2.0/emd.zip?checksum=sha256:cadd5b52fe90a04e20b2cbb93291b0d1d0204f17b64b2215eb09f5dc78a127f1"}}'`,
+ Long: `Schedule a software upgrade by submitting a unique plan name that
+ has not been used before with either an absolute block height or block time. An
+upgrade handler should be defined at the upgraded binary. Optionally If you set DAEMON_ALLOW_DOWNLOAD_BINARIES=on pass
+the upgraded binary download url with the --upgrade-info flag i.e., --upgrade-info '{"binaries":{"linux/amd64":"http://localhost:8765/test-upg-0.2.0/emd.zip?checksum=sha256:cadd5b52fe90a04e20b2cbb93291b0d1d0204f17b64b2215eb09f5dc78a127f1"}}'`,
+ Args: cobra.RangeArgs(1, 2),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ err := cmd.Flags().Set(flags.FlagFrom, args[0])
+ if err != nil {
+ return err
+ }
+
+ if err := validateUpgFlags(UpgHeight, upgHeightVal); err != nil {
+ return err
+ }
+
+ clientCtx, err := client.GetClientTxContext(cmd)
+ if err != nil {
+ return err
+ }
+
+ msg := &types.MsgScheduleUpgrade{
+ Authority: clientCtx.GetFromAddress().String(),
+ Plan: upgtypes.Plan{
+ Name: args[1],
+ Time: time.Unix(0, 0),
+ Height: upgHeightVal,
+ Info: upgInfoVal,
+ },
+ }
+
+ if err := msg.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
+ },
+ }
+ f := cmd.Flags()
+ f.Int64VarP(&upgHeightVal, UpgHeight, "n", 0, "Upgrade block height number")
+ f.StringVarP(
+ &upgInfoVal, UpgInfo, "i", "", "Upgrade info",
+ )
+
+ flags.AddTxFlagsToCmd(cmd)
+ return cmd
+}
+
+func validateUpgFlags(upgHeight string, upgHeightVal int64) error {
+ if upgHeightVal == 0 {
+ return sdkerrors.Wrapf(
+ types.ErrMissingFlag,
+ "need to specify --%s", upgHeight,
+ )
+ }
+
+ flagsSet := 0
+ if upgHeightVal != 0 {
+ flagsSet++
+ }
+ if flagsSet != 1 {
+ return sdkerrors.Wrapf(
+ sdkerrors.ErrInvalidRequest,
+ "specify only one of the flags: --%s", upgHeight)
+ }
+
+ return nil
+}
diff --git a/x/authority/client/cli/tx_test.go b/x/authority/client/cli/tx_replace_test.go
similarity index 93%
rename from x/authority/client/cli/tx_test.go
rename to x/authority/client/cli/tx_replace_test.go
index 5c54424e..974209ed 100644
--- a/x/authority/client/cli/tx_test.go
+++ b/x/authority/client/cli/tx_replace_test.go
@@ -3,11 +3,14 @@ package cli_test
import (
"bytes"
"fmt"
+ "sort"
+ "strings"
+
bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
"github.com/e-money/em-ledger/x/authority/client/cli"
"github.com/e-money/em-ledger/x/authority/types"
- "sort"
- "strings"
+
+ "testing"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
@@ -20,22 +23,21 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
"github.com/stretchr/testify/suite"
- "testing"
)
-type IntegrationTestSuite struct {
+type ReplacementTestSuite struct {
suite.Suite
cfg network.Config
network *network.Network
}
-func (s *IntegrationTestSuite) SetupSuite() {
+func (s *ReplacementTestSuite) SetupSuite() {
s.T().Log("setting up integration test suite")
cfg := network.DefaultConfig()
cfg.LegacyAmino.RegisterConcrete(&types.MsgReplaceAuthority{}, "MsgReplaceAuthority", nil)
- cfg.InterfaceRegistry.RegisterImplementations((*sdk.Msg)(nil),&types.MsgReplaceAuthority{})
+ cfg.InterfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &types.MsgReplaceAuthority{})
cfg.NumValidators = 2
s.cfg = cfg
@@ -59,12 +61,12 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.Require().NoError(err)
}
-func (s *IntegrationTestSuite) TearDownSuite() {
+func (s *ReplacementTestSuite) TearDownSuite() {
s.T().Log("tearing down integration test suite")
s.network.Cleanup()
}
-func (s *IntegrationTestSuite) TestReplaceAuth() {
+func (s *ReplacementTestSuite) TestReplaceAuth() {
val1 := *s.network.Validators[0]
// Generate 2 accounts and a multisig.
@@ -109,7 +111,7 @@ func (s *IntegrationTestSuite) TestReplaceAuth() {
authkeys := []string{acc1UID, acc2UID, acc3UID}
multisigThreshold := len(authkeys) - 1
// generate new multisig authority key
- for _, keyname := range authkeys{
+ for _, keyname := range authkeys {
k, err := kb.Key(keyname)
s.Require().NoError(err)
@@ -130,7 +132,7 @@ func (s *IntegrationTestSuite) TestReplaceAuth() {
fmt.Println("New authority multisig key:", newAuthMultiSigAcc.GetAddress().String())
- // set the multisig acount in the state
+ // set the multisig account in the state
sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10)
_, err = bankcli.MsgSendExec(
val1.ClientCtx,
@@ -153,7 +155,7 @@ func (s *IntegrationTestSuite) TestReplaceAuth() {
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
}
- multiGeneratedTx, err := sdkcli.ExecTestCLICmd(val1.ClientCtx, cli.GetCmdReplaceAuthority(),args)
+ multiGeneratedTx, err := sdkcli.ExecTestCLICmd(val1.ClientCtx, cli.GetCmdReplaceAuthority(), args)
s.Require().NoError(err)
// Save tx to file
@@ -208,6 +210,6 @@ func (s *IntegrationTestSuite) TestReplaceAuth() {
s.Require().NoError(s.network.WaitForNextBlock())
}
-func TestIntegrationTestSuite(t *testing.T) {
- suite.Run(t, new(IntegrationTestSuite))
-}
\ No newline at end of file
+func TestReplacementTestSuite(t *testing.T) {
+ suite.Run(t, new(ReplacementTestSuite))
+}
diff --git a/x/authority/client/cli/tx_upg_test.go b/x/authority/client/cli/tx_upg_test.go
new file mode 100644
index 00000000..205b546c
--- /dev/null
+++ b/x/authority/client/cli/tx_upg_test.go
@@ -0,0 +1,172 @@
+package cli_test
+
+import (
+ "fmt"
+ "strings"
+
+ bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
+ "github.com/e-money/em-ledger/x/authority/client/cli"
+ "github.com/e-money/em-ledger/x/authority/types"
+
+ "testing"
+
+ "github.com/cosmos/cosmos-sdk/client/flags"
+ "github.com/cosmos/cosmos-sdk/crypto/hd"
+ "github.com/cosmos/cosmos-sdk/crypto/keyring"
+ kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig"
+ cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
+ "github.com/cosmos/cosmos-sdk/testutil"
+ sdkcli "github.com/cosmos/cosmos-sdk/testutil/cli"
+ "github.com/cosmos/cosmos-sdk/testutil/network"
+ sdk "github.com/cosmos/cosmos-sdk/types"
+ authtest "github.com/cosmos/cosmos-sdk/x/auth/client/testutil"
+ "github.com/stretchr/testify/suite"
+)
+
+type UpgTestSuite struct {
+ suite.Suite
+
+ cfg network.Config
+ network *network.Network
+}
+
+func (s *UpgTestSuite) SetupSuite() {
+ s.T().Log("setting up integration test suite")
+
+ cfg := network.DefaultConfig()
+ cfg.LegacyAmino.RegisterConcrete(&types.MsgScheduleUpgrade{}, "MsgScheduleUpgrade", nil)
+ cfg.InterfaceRegistry.RegisterImplementations((*sdk.Msg)(nil), &types.MsgScheduleUpgrade{})
+ cfg.NumValidators = 2
+
+ s.cfg = cfg
+ s.network = network.New(s.T(), cfg)
+
+ kb := s.network.Validators[0].ClientCtx.Keyring
+ _, _, err := kb.NewMnemonic("newAccount", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
+ s.Require().NoError(err)
+
+ account1, _, err := kb.NewMnemonic("newAccount1", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
+ s.Require().NoError(err)
+
+ account2, _, err := kb.NewMnemonic("newAccount2", keyring.English, sdk.FullFundraiserPath, hd.Secp256k1)
+ s.Require().NoError(err)
+
+ // Create multisig authority key
+ multi := kmultisig.NewLegacyAminoPubKey(2, []cryptotypes.PubKey{account1.GetPubKey(), account2.GetPubKey()})
+ _, err = kb.SaveMultisig("multi", multi)
+ s.Require().NoError(err)
+
+ _, err = s.network.WaitForHeight(1)
+ s.Require().NoError(err)
+}
+
+func (s *UpgTestSuite) TearDownSuite() {
+ s.T().Log("tearing down integration test suite")
+ s.network.Cleanup()
+}
+
+func (s *UpgTestSuite) TestScheduleUpgrade() {
+ val1 := *s.network.Validators[0]
+
+ // Generate 2 accounts and a multisig.
+ const (
+ acc1UID = "newAccount1"
+ acc2UID = "newAccount2"
+ msigUID = "multi"
+ )
+
+ account1, err := val1.ClientCtx.Keyring.Key(acc1UID)
+ s.Require().NoError(err)
+ fmt.Println("acc 1:", account1.GetAddress().String())
+
+ account2, err := val1.ClientCtx.Keyring.Key(acc2UID)
+ s.Require().NoError(err)
+ fmt.Println("acc 2:", account2.GetAddress().String())
+
+ authMultiSigAcc, err := val1.ClientCtx.Keyring.Key(msigUID)
+ s.Require().NoError(err)
+ s.Require().Equal(keyring.TypeMulti, authMultiSigAcc.GetType())
+ fmt.Println("multi:", authMultiSigAcc.GetAddress().String())
+
+ // set the multisig account in the state
+ sendTokens := sdk.NewInt64Coin(s.cfg.BondDenom, 10)
+ _, err = bankcli.MsgSendExec(
+ val1.ClientCtx,
+ val1.Address,
+ authMultiSigAcc.GetAddress(),
+ sdk.NewCoins(sendTokens),
+ fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
+ fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
+ fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
+ fmt.Sprintf("--gas=%d", flags.DefaultGasLimit),
+ )
+
+ // Generate the unsigned multisig transaction json with the existing authority key.
+ args := []string{
+ authMultiSigAcc.GetAddress().String(),
+ "test1",
+ fmt.Sprintf("--%s=100", cli.UpgHeight),
+ fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
+ fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
+ fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
+ fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
+ }
+
+ multiGeneratedTx, err := sdkcli.ExecTestCLICmd(val1.ClientCtx, cli.GetCmdScheduleUpgrade(), args)
+ s.Require().NoError(err)
+
+ // Save tx to file
+ multiGeneratedTxFile := testutil.WriteToNewTempFile(s.T(), multiGeneratedTx.String())
+
+ // Sign with account1
+ val1.ClientCtx.HomeDir = strings.Replace(val1.ClientCtx.HomeDir, "simd", "simcli", 1)
+ account1Signature, err := authtest.TxSignExec(
+ val1.ClientCtx, account1.GetAddress(), multiGeneratedTxFile.Name(),
+ "--multisig", authMultiSigAcc.GetAddress().String(),
+ )
+ s.Require().NoError(err)
+
+ sign1File := testutil.WriteToNewTempFile(s.T(), account1Signature.String())
+
+ // Sign with account2
+ account2Signature, err := authtest.TxSignExec(
+ val1.ClientCtx, account2.GetAddress(), multiGeneratedTxFile.Name(),
+ "--multisig", authMultiSigAcc.GetAddress().String(),
+ )
+ s.Require().NoError(err)
+
+ sign2File := testutil.WriteToNewTempFile(s.T(), account2Signature.String())
+
+ // Does not work in offline mode.
+ _, err = authtest.TxMultiSignExec(
+ val1.ClientCtx, authMultiSigAcc.GetName(), multiGeneratedTxFile.Name(),
+ "--offline", sign1File.Name(), sign2File.Name(),
+ )
+ s.Require().EqualError(
+ err,
+ "couldn't verify signature: unable to verify single signer signature",
+ )
+
+ val1.ClientCtx.Offline = false
+ multiSigWith2Signatures, err := authtest.TxMultiSignExec(
+ val1.ClientCtx, authMultiSigAcc.GetName(), multiGeneratedTxFile.Name(),
+ sign1File.Name(), sign2File.Name(),
+ )
+ s.Require().NoError(err)
+
+ // Write the output to disk
+ signedTxFile := testutil.WriteToNewTempFile(s.T(), multiSigWith2Signatures.String())
+
+ _, err = authtest.TxValidateSignaturesExec(val1.ClientCtx, signedTxFile.Name())
+ s.Require().NoError(err)
+
+ val1.ClientCtx.BroadcastMode = flags.BroadcastBlock
+ _, err = authtest.TxBroadcastExec(val1.ClientCtx, signedTxFile.Name())
+ s.Require().NoError(err)
+
+ s.Require().NoError(s.network.WaitForNextBlock())
+}
+
+func TestUpgTestSuite(t *testing.T) {
+ suite.Run(t, new(UpgTestSuite))
+}
diff --git a/x/authority/handler.go b/x/authority/handler.go
index e86827dd..f39a0f92 100644
--- a/x/authority/handler.go
+++ b/x/authority/handler.go
@@ -36,6 +36,10 @@ func newHandler(k Keeper) sdk.Handler {
res, err := msgServer.ReplaceAuthority(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
+ case *types.MsgScheduleUpgrade:
+ res, err := msgServer.ScheduleUpgrade(sdk.WrapSDKContext(ctx), msg)
+ return sdk.WrapServiceResult(ctx, res, err)
+
default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
}
diff --git a/x/authority/keeper/grpc_query.go b/x/authority/keeper/grpc_query.go
index fb1823b9..541de1cb 100644
--- a/x/authority/keeper/grpc_query.go
+++ b/x/authority/keeper/grpc_query.go
@@ -2,6 +2,7 @@ package keeper
import (
"context"
+
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/e-money/em-ledger/x/authority/types"
"google.golang.org/grpc/codes"
@@ -18,3 +19,14 @@ func (k Keeper) GasPrices(c context.Context, req *types.QueryGasPricesRequest) (
gasPrices := k.GetGasPrices(ctx)
return &types.QueryGasPricesResponse{MinGasPrices: gasPrices}, nil
}
+
+func (k Keeper) UpgradePlan(c context.Context, req *types.QueryUpgradePlanRequest) (*types.QueryUpgradePlanResponse, error) {
+ if req == nil {
+ return nil, status.Error(codes.InvalidArgument, "empty request")
+ }
+
+ ctx := sdk.UnwrapSDKContext(c)
+ plan, _ := k.GetUpgradePlan(ctx)
+
+ return &types.QueryUpgradePlanResponse{Plan: plan}, nil
+}
diff --git a/x/authority/keeper/grpc_query_test.go b/x/authority/keeper/grpc_query_test.go
index 4acd1267..4981718f 100644
--- a/x/authority/keeper/grpc_query_test.go
+++ b/x/authority/keeper/grpc_query_test.go
@@ -3,6 +3,8 @@ package keeper
import (
"testing"
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/e-money/em-ledger/x/authority/types"
@@ -41,3 +43,39 @@ func TestQueryGasPrices(t *testing.T) {
})
}
}
+
+func TestQueryUpgradePlan(t *testing.T) {
+ encConfig := MakeTestEncodingConfig()
+ ctx, keeper, _, _ := createTestComponentWithEncodingConfig(t, encConfig)
+
+ authority := mustParseAddress("emoney1kt0vh0ttget0xx77g6d3ttnvq2lnxx6vp3uyl0")
+ keeper.BootstrapAuthority(ctx, authority)
+
+ expPlan := upgradetypes.Plan{
+ Name: "expPlan 8",
+ Height: 1000,
+ }
+ _, err := keeper.ScheduleUpgrade(ctx, authority, expPlan)
+ require.NoError(t, err)
+
+ queryHelper := baseapp.NewQueryServerTestHelper(ctx, encConfig.InterfaceRegistry)
+ types.RegisterQueryServer(queryHelper, keeper)
+ queryClient := types.NewQueryClient(queryHelper)
+
+ specs := map[string]struct {
+ req *types.QueryUpgradePlanRequest
+ }{
+ "all good": {
+ req: &types.QueryUpgradePlanRequest{},
+ },
+ "nil param": {},
+ }
+ for name, spec := range specs {
+ t.Run(name, func(t *testing.T) {
+ gotRsp, gotErr := queryClient.UpgradePlan(sdk.WrapSDKContext(ctx), spec.req)
+ require.NoError(t, gotErr)
+ require.NotNil(t, gotRsp)
+ assert.Equal(t, expPlan, gotRsp.Plan)
+ })
+ }
+}
diff --git a/x/authority/keeper/keeper.go b/x/authority/keeper/keeper.go
index 1c106066..ba4958f9 100644
--- a/x/authority/keeper/keeper.go
+++ b/x/authority/keeper/keeper.go
@@ -8,6 +8,8 @@ import (
"errors"
"sync"
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+
"github.com/cosmos/cosmos-sdk/codec"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/e-money/em-ledger/x/authority/types"
@@ -24,22 +26,28 @@ const (
var _ authorityKeeper = Keeper{}
type Keeper struct {
- cdc codec.BinaryMarshaler
- storeKey sdk.StoreKey
- ik issuer.Keeper
- bankKeeper types.BankKeeper
- gpk types.GasPricesKeeper
+ cdc codec.BinaryMarshaler
+ storeKey sdk.StoreKey
+ ik issuer.Keeper
+ bankKeeper types.BankKeeper
+ upgradeKeeper types.UpgradeKeeper
+ gpk types.GasPricesKeeper
gasPricesInit *sync.Once
}
-func NewKeeper(cdc codec.BinaryMarshaler, storeKey sdk.StoreKey, issuerKeeper issuer.Keeper, bankKeeper types.BankKeeper, gasPricesKeeper types.GasPricesKeeper) Keeper {
+func NewKeeper(
+ cdc codec.BinaryMarshaler, storeKey sdk.StoreKey,
+ issuerKeeper issuer.Keeper, bankKeeper types.BankKeeper,
+ gasPricesKeeper types.GasPricesKeeper, upgradeKeeper types.UpgradeKeeper,
+) Keeper {
return Keeper{
- cdc: cdc,
- ik: issuerKeeper,
- bankKeeper: bankKeeper,
- gpk: gasPricesKeeper,
- storeKey: storeKey,
+ cdc: cdc,
+ ik: issuerKeeper,
+ bankKeeper: bankKeeper,
+ gpk: gasPricesKeeper,
+ storeKey: storeKey,
+ upgradeKeeper: upgradeKeeper,
gasPricesInit: new(sync.Once),
}
@@ -207,3 +215,22 @@ func (k Keeper) replaceAuthority(ctx sdk.Context, authority, newAuthority sdk.Ac
return &sdk.Result{Events: ctx.EventManager().ABCIEvents()}, nil
}
+
+func (k Keeper) ScheduleUpgrade(
+ ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan,
+) (*sdk.Result, error) {
+ if err := k.ValidateAuthority(ctx, authority); err != nil {
+ return nil, err
+ }
+
+ if err := k.upgradeKeeper.ScheduleUpgrade(ctx, plan); err != nil {
+ return nil, err
+ }
+
+ return &sdk.Result{Events: ctx.EventManager().ABCIEvents()}, nil
+}
+
+func (k Keeper) GetUpgradePlan(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool) {
+
+ return k.upgradeKeeper.GetUpgradePlan(ctx)
+}
diff --git a/x/authority/keeper/keeper_test.go b/x/authority/keeper/keeper_test.go
index e75737f8..ac4250df 100644
--- a/x/authority/keeper/keeper_test.go
+++ b/x/authority/keeper/keeper_test.go
@@ -7,6 +7,10 @@ package keeper
import (
"testing"
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
+
+ upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
+
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
@@ -392,6 +396,7 @@ func createTestComponentWithEncodingConfig(t *testing.T, encConfig simappparams.
tkeyParams = sdk.NewTransientStoreKey("transient_params")
keyIssuer = sdk.NewKVStoreKey(issuer.ModuleName)
keyLp = sdk.NewKVStoreKey(liquidityprovider.ModuleName)
+ keyUpg = sdk.NewKVStoreKey(upgradetypes.StoreKey)
blockedAddr = make(map[string]bool)
)
@@ -403,6 +408,7 @@ func createTestComponentWithEncodingConfig(t *testing.T, encConfig simappparams.
ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyIssuer, sdk.StoreTypeIAVL, db)
ms.MountStoreWithDB(keyLp, sdk.StoreTypeIAVL, db)
+ ms.MountStoreWithDB(keyUpg, sdk.StoreTypeIAVL, db)
err := ms.LoadLatestVersion()
require.NoError(t, err)
@@ -422,6 +428,8 @@ func createTestComponentWithEncodingConfig(t *testing.T, encConfig simappparams.
)
lpk = liquidityprovider.NewKeeper(encConfig.Marshaler, keyLp, bk)
ik = issuer.NewKeeper(encConfig.Marshaler, keyIssuer, lpk, mockInflationKeeper{})
+
+ upgK = upgradekeeper.NewKeeper(map[int64]bool{}, keyUpg, encConfig.Marshaler, t.TempDir())
)
bk.SetSupply(ctx, banktypes.NewSupply(
@@ -431,7 +439,7 @@ func createTestComponentWithEncodingConfig(t *testing.T, encConfig simappparams.
)))
gpk := new(mockGasPricesKeeper)
- keeper := NewKeeper(encConfig.Marshaler, authKey, ik, bk, gpk)
+ keeper := NewKeeper(encConfig.Marshaler, authKey, ik, bk, gpk, upgK)
return ctx, keeper, ik, gpk
}
diff --git a/x/authority/keeper/msg_server.go b/x/authority/keeper/msg_server.go
index a3a6ebb4..36f11943 100644
--- a/x/authority/keeper/msg_server.go
+++ b/x/authority/keeper/msg_server.go
@@ -2,6 +2,9 @@ package keeper
import (
"context"
+ "fmt"
+
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@@ -15,6 +18,8 @@ type authorityKeeper interface {
destroyIssuer(ctx sdk.Context, authority sdk.AccAddress, issuerAddress sdk.AccAddress) (*sdk.Result, error)
replaceAuthority(ctx sdk.Context, authority, newAuthority sdk.AccAddress) (*sdk.Result, error)
SetGasPrices(ctx sdk.Context, authority sdk.AccAddress, gasprices sdk.DecCoins) (*sdk.Result, error)
+ ScheduleUpgrade(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error)
+ GetUpgradePlan(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool)
}
type msgServer struct {
k authorityKeeper
@@ -108,3 +113,33 @@ func (m msgServer) ReplaceAuthority(goCtx context.Context, msg *types.MsgReplace
return &types.MsgReplaceAuthorityResponse{}, nil
}
+
+func (m msgServer) ScheduleUpgrade(
+ goCtx context.Context, msg *types.MsgScheduleUpgrade,
+) (*types.MsgScheduleUpgradeResponse, error) {
+
+ ctx := sdk.UnwrapSDKContext(goCtx)
+
+ authority, err := sdk.AccAddressFromBech32(msg.Authority)
+ if err != nil {
+ return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "authority")
+ }
+
+ if msg.Plan.Time.Unix() != 0 {
+ return nil, sdkerrors.Wrap(
+ types.ErrPlanTimeIsSet,
+ fmt.Sprintf("Plan time: %s", msg.Plan.Time.String()),
+ )
+ }
+
+ result, err := m.k.ScheduleUpgrade(ctx, authority, msg.Plan)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, e := range result.Events {
+ ctx.EventManager().EmitEvent(sdk.Event(e))
+ }
+
+ return &types.MsgScheduleUpgradeResponse{}, nil
+}
diff --git a/x/authority/keeper/msg_server_test.go b/x/authority/keeper/msg_server_test.go
index 399ec124..b06a8833 100644
--- a/x/authority/keeper/msg_server_test.go
+++ b/x/authority/keeper/msg_server_test.go
@@ -4,6 +4,9 @@ import (
"context"
"errors"
"testing"
+ "time"
+
+ upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/e-money/em-ledger/x/authority/types"
@@ -284,6 +287,136 @@ func TestSetGasPrices(t *testing.T) {
})
}
}
+
+func TestScheduleUpgrade(t *testing.T) {
+ var (
+ authorityAddr = mustParseAddress("emoney1kt0vh0ttget0xx77g6d3ttnvq2lnxx6vp3uyl0")
+ gotAuthority sdk.AccAddress
+ gotPlan upgradetypes.Plan
+ )
+
+ keeper := authorityKeeperMock{}
+ svr := NewMsgServerImpl(&keeper)
+
+ specs := map[string]struct {
+ req *types.MsgScheduleUpgrade
+ mockFn func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error)
+ expErr bool
+ expEvents sdk.Events
+ }{
+ "all good": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: authorityAddr.String(),
+ Plan: upgradetypes.Plan{
+ Name: "plan8",
+ Height: 100,
+ Time: time.Unix(0, 0),
+ },
+ },
+ mockFn: func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error) {
+ gotAuthority, gotPlan = authority, plan
+ return &sdk.Result{
+ Events: []abcitypes.Event{{
+ Type: "testing",
+ Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}},
+ }},
+ }, nil
+ },
+ expEvents: sdk.Events{{
+ Type: "testing",
+ Attributes: []abcitypes.EventAttribute{{Key: []byte("foo"), Value: []byte("bar")}},
+ }},
+ },
+ "authority missing": {
+ req: &types.MsgScheduleUpgrade{
+ Plan: upgradetypes.Plan{
+ Name: "test1",
+ Height: 100,
+ },
+ },
+ expErr: true,
+ },
+ "authority invalid": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: "invalid",
+ Plan: upgradetypes.Plan{
+ Name: "test1",
+ Height: 100,
+ },
+ },
+ expErr: true,
+ },
+ "invalid height value": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: authorityAddr.String(),
+ Plan: upgradetypes.Plan{
+ Name: "test1",
+ Height: -100,
+ },
+ },
+ mockFn: func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error) {
+ return nil, errors.New("testing")
+ },
+ expErr: true,
+ },
+ "missing height": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: authorityAddr.String(),
+ Plan: upgradetypes.Plan{
+ Name: "test1",
+ },
+ },
+ mockFn: func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error) {
+ return nil, errors.New("testing")
+ },
+ expErr: true,
+ },
+ "missing plan name": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: authorityAddr.String(),
+ Plan: upgradetypes.Plan{
+ Height: 1,
+ },
+ },
+ mockFn: func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error) {
+ return nil, errors.New("testing")
+ },
+ expErr: true,
+ },
+ "featuring both time and height": {
+ req: &types.MsgScheduleUpgrade{
+ Authority: authorityAddr.String(),
+ Plan: upgradetypes.Plan{
+ Name: "test1",
+ Time: time.Now(),
+ Height: 1,
+ },
+ },
+ mockFn: func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error) {
+ return nil, errors.New("testing")
+ },
+ expErr: true,
+ },
+ }
+
+ for name, spec := range specs {
+ t.Run(name, func(t *testing.T) {
+ keeper.scheduleUpgradefn = spec.mockFn
+ eventManager := sdk.NewEventManager()
+ ctx := sdk.Context{}.WithContext(context.Background()).WithEventManager(eventManager)
+ _, gotErr := svr.ScheduleUpgrade(sdk.WrapSDKContext(ctx), spec.req)
+ if spec.expErr {
+ require.Error(t, gotErr)
+ return
+ }
+ require.NoError(t, gotErr)
+ assert.Equal(t, spec.expEvents, eventManager.Events())
+ assert.Equal(t, spec.req.Authority, gotAuthority.String())
+ assert.Equal(t, spec.req.Plan, gotPlan)
+ })
+ }
+}
+
func TestReplaceAuth(t *testing.T) {
var (
authorityAddr = mustParseAddress("emoney1kt0vh0ttget0xx77g6d3ttnvq2lnxx6vp3uyl0")
@@ -400,6 +533,9 @@ type authorityKeeperMock struct {
destroyIssuerfn func(ctx sdk.Context, authority sdk.AccAddress, issuerAddress sdk.AccAddress) (*sdk.Result, error)
SetGasPricesfn func(ctx sdk.Context, authority sdk.AccAddress, gasprices sdk.DecCoins) (*sdk.Result, error)
replaceAuthorityfn func(ctx sdk.Context, authority, newAuthority sdk.AccAddress) (*sdk.Result, error)
+ scheduleUpgradefn func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error)
+ getUpgradePlanfn func(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool)
+ applyUpgradefn func(ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan) (*sdk.Result, error)
}
func (a authorityKeeperMock) createIssuer(ctx sdk.Context, authority sdk.AccAddress, issuerAddress sdk.AccAddress, denoms []string) (*sdk.Result, error) {
@@ -430,3 +566,31 @@ func (a authorityKeeperMock) replaceAuthority(ctx sdk.Context, authority, newAut
return a.replaceAuthorityfn(ctx, authority, newAuthority)
}
+
+func (a authorityKeeperMock) ScheduleUpgrade(
+ ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan,
+) (*sdk.Result, error) {
+ if a.scheduleUpgradefn == nil {
+ panic("not expected to be called")
+ }
+
+ return a.scheduleUpgradefn(ctx, authority, plan)
+}
+
+func (a authorityKeeperMock) GetUpgradePlan(ctx sdk.Context) (plan upgradetypes.Plan, havePlan bool) {
+ if a.getUpgradePlanfn == nil {
+ panic("not expected to be called")
+ }
+
+ return a.getUpgradePlanfn(ctx)
+}
+
+func (a authorityKeeperMock) ApplyUpgrade(
+ ctx sdk.Context, authority sdk.AccAddress, plan upgradetypes.Plan,
+) (*sdk.Result, error) {
+ if a.applyUpgradefn == nil {
+ panic("not expected to be called")
+ }
+
+ return a.applyUpgradefn(ctx, authority, plan)
+}
diff --git a/x/authority/types/codec.go b/x/authority/types/codec.go
index b3633d6f..14d21e74 100644
--- a/x/authority/types/codec.go
+++ b/x/authority/types/codec.go
@@ -26,6 +26,7 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&MsgDestroyIssuer{}, "e-money/MsgDestroyIssuer", nil)
cdc.RegisterConcrete(&MsgSetGasPrices{}, "e-money/MsgSetGasPrices", nil)
cdc.RegisterConcrete(&MsgReplaceAuthority{}, "e-money/MsgReplaceAuthority", nil)
+ cdc.RegisterConcrete(&MsgScheduleUpgrade{}, "e-money/MsgScheduleUpgrade", nil)
}
func RegisterInterfaces(registry types.InterfaceRegistry) {
@@ -34,6 +35,7 @@ func RegisterInterfaces(registry types.InterfaceRegistry) {
&MsgDestroyIssuer{},
&MsgSetGasPrices{},
&MsgReplaceAuthority{},
+ &MsgScheduleUpgrade{},
)
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
}
diff --git a/x/authority/types/errors.go b/x/authority/types/errors.go
index 17df36a5..622cc3b6 100644
--- a/x/authority/types/errors.go
+++ b/x/authority/types/errors.go
@@ -9,11 +9,12 @@ import (
)
var (
- ErrNotAuthority = sdkerrors.Register(ModuleName, 1, "not an authority")
- ErrNoDenomsSpecified = sdkerrors.Register(ModuleName, 2, "No denominations specified in authority call")
- ErrInvalidDenom = sdkerrors.Register(ModuleName, 3, "Invalid denomination found")
- ErrNoAuthorityConfigured = sdkerrors.Register(ModuleName, 4, "No authority configured")
- ErrInvalidGasPrices = sdkerrors.Register(ModuleName, 5, "Invalid gas prices")
- ErrUnknownDenom = sdkerrors.Register(ModuleName, 6, "Unknown denomination specified")
- ErrSameAuthorityConfigured = sdkerrors.Register(ModuleName, 7, "Authority already configured")
+ ErrNotAuthority = sdkerrors.Register(ModuleName, 1, "not an authority")
+ ErrNoDenomsSpecified = sdkerrors.Register(ModuleName, 2, "No denominations specified in authority call")
+ ErrInvalidDenom = sdkerrors.Register(ModuleName, 3, "Invalid denomination found")
+ ErrNoAuthorityConfigured = sdkerrors.Register(ModuleName, 4, "No authority configured")
+ ErrInvalidGasPrices = sdkerrors.Register(ModuleName, 5, "Invalid gas prices")
+ ErrUnknownDenom = sdkerrors.Register(ModuleName, 6, "Unknown denomination specified")
+ ErrMissingFlag = sdkerrors.Register(ModuleName, 7, "missing flag")
+ ErrPlanTimeIsSet = sdkerrors.Register(ModuleName, 8, "upgrade plan cannot set time")
)
diff --git a/x/authority/types/expected_keepers.go b/x/authority/types/expected_keepers.go
index 79c34c7e..cc5103b6 100644
--- a/x/authority/types/expected_keepers.go
+++ b/x/authority/types/expected_keepers.go
@@ -7,6 +7,7 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank/exported"
+ "github.com/cosmos/cosmos-sdk/x/upgrade/types"
)
type (
@@ -17,4 +18,12 @@ type (
BankKeeper interface {
GetSupply(ctx sdk.Context) exported.SupplyI
}
+
+ UpgradeKeeper interface {
+ ApplyUpgrade(ctx sdk.Context, plan types.Plan)
+ GetUpgradePlan(ctx sdk.Context) (plan types.Plan, havePlan bool)
+ HasHandler(name string) bool
+ ScheduleUpgrade(ctx sdk.Context, plan types.Plan) error
+ SetUpgradeHandler(name string, upgradeHandler types.UpgradeHandler)
+ }
)
diff --git a/x/authority/types/msgs.go b/x/authority/types/msgs.go
index fe61de93..832942c7 100644
--- a/x/authority/types/msgs.go
+++ b/x/authority/types/msgs.go
@@ -14,6 +14,7 @@ var (
_ sdk.Msg = &MsgDestroyIssuer{}
_ sdk.Msg = &MsgSetGasPrices{}
_ sdk.Msg = &MsgReplaceAuthority{}
+ _ sdk.Msg = &MsgScheduleUpgrade{}
)
func (msg MsgDestroyIssuer) Type() string { return "destroy_issuer" }
@@ -24,6 +25,8 @@ func (msg MsgSetGasPrices) Type() string { return "set_gas_prices" }
func (msg MsgReplaceAuthority) Type() string { return "replace_authority" }
+func (msg MsgScheduleUpgrade) Type() string { return "schedule_upgrade" }
+
func (msg MsgDestroyIssuer) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(msg.Issuer); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid issuer address (%s)", err)
@@ -76,6 +79,18 @@ func (msg MsgReplaceAuthority) ValidateBasic() error {
return nil
}
+func (msg MsgScheduleUpgrade) ValidateBasic() error {
+ if _, err := sdk.AccAddressFromBech32(msg.Authority); err != nil {
+ return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address (%s)", err)
+ }
+
+ if err := msg.Plan.ValidateBasic(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
func (msg MsgDestroyIssuer) GetSigners() []sdk.AccAddress {
from, err := sdk.AccAddressFromBech32(msg.Authority)
if err != nil {
@@ -108,6 +123,14 @@ func (msg MsgReplaceAuthority) GetSigners() []sdk.AccAddress {
return []sdk.AccAddress{from}
}
+func (msg MsgScheduleUpgrade) GetSigners() []sdk.AccAddress {
+ from, err := sdk.AccAddressFromBech32(msg.Authority)
+ if err != nil {
+ panic(err)
+ }
+ return []sdk.AccAddress{from}
+}
+
func (msg MsgDestroyIssuer) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
}
@@ -124,6 +147,10 @@ func (msg MsgReplaceAuthority) GetSignBytes() []byte {
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
}
+func (msg MsgScheduleUpgrade) GetSignBytes() []byte {
+ return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
+}
+
func (msg MsgDestroyIssuer) Route() string { return ModuleName }
func (msg MsgCreateIssuer) Route() string { return ModuleName }
@@ -131,3 +158,5 @@ func (msg MsgCreateIssuer) Route() string { return ModuleName }
func (msg MsgSetGasPrices) Route() string { return ModuleName }
func (msg MsgReplaceAuthority) Route() string { return ModuleName }
+
+func (msg MsgScheduleUpgrade) Route() string { return ModuleName }
diff --git a/x/authority/types/query.pb.go b/x/authority/types/query.pb.go
index a2c00546..0c7c15e3 100644
--- a/x/authority/types/query.pb.go
+++ b/x/authority/types/query.pb.go
@@ -8,6 +8,7 @@ import (
fmt "fmt"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
types "github.com/cosmos/cosmos-sdk/types"
+ types1 "github.com/cosmos/cosmos-sdk/x/upgrade/types"
_ "github.com/gogo/protobuf/gogoproto"
grpc1 "github.com/gogo/protobuf/grpc"
proto "github.com/gogo/protobuf/proto"
@@ -110,39 +111,127 @@ func (m *QueryGasPricesResponse) GetMinGasPrices() github_com_cosmos_cosmos_sdk_
return nil
}
+type QueryUpgradePlanRequest struct {
+}
+
+func (m *QueryUpgradePlanRequest) Reset() { *m = QueryUpgradePlanRequest{} }
+func (m *QueryUpgradePlanRequest) String() string { return proto.CompactTextString(m) }
+func (*QueryUpgradePlanRequest) ProtoMessage() {}
+func (*QueryUpgradePlanRequest) Descriptor() ([]byte, []int) {
+ return fileDescriptor_d766145e8bc7b365, []int{2}
+}
+func (m *QueryUpgradePlanRequest) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QueryUpgradePlanRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QueryUpgradePlanRequest.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QueryUpgradePlanRequest) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QueryUpgradePlanRequest.Merge(m, src)
+}
+func (m *QueryUpgradePlanRequest) XXX_Size() int {
+ return m.Size()
+}
+func (m *QueryUpgradePlanRequest) XXX_DiscardUnknown() {
+ xxx_messageInfo_QueryUpgradePlanRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QueryUpgradePlanRequest proto.InternalMessageInfo
+
+type QueryUpgradePlanResponse struct {
+ Plan types1.Plan `protobuf:"bytes,1,opt,name=plan,proto3" json:"plan" yaml:"plan"`
+}
+
+func (m *QueryUpgradePlanResponse) Reset() { *m = QueryUpgradePlanResponse{} }
+func (m *QueryUpgradePlanResponse) String() string { return proto.CompactTextString(m) }
+func (*QueryUpgradePlanResponse) ProtoMessage() {}
+func (*QueryUpgradePlanResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_d766145e8bc7b365, []int{3}
+}
+func (m *QueryUpgradePlanResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *QueryUpgradePlanResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_QueryUpgradePlanResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *QueryUpgradePlanResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_QueryUpgradePlanResponse.Merge(m, src)
+}
+func (m *QueryUpgradePlanResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *QueryUpgradePlanResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_QueryUpgradePlanResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_QueryUpgradePlanResponse proto.InternalMessageInfo
+
+func (m *QueryUpgradePlanResponse) GetPlan() types1.Plan {
+ if m != nil {
+ return m.Plan
+ }
+ return types1.Plan{}
+}
+
func init() {
proto.RegisterType((*QueryGasPricesRequest)(nil), "em.authority.v1.QueryGasPricesRequest")
proto.RegisterType((*QueryGasPricesResponse)(nil), "em.authority.v1.QueryGasPricesResponse")
+ proto.RegisterType((*QueryUpgradePlanRequest)(nil), "em.authority.v1.QueryUpgradePlanRequest")
+ proto.RegisterType((*QueryUpgradePlanResponse)(nil), "em.authority.v1.QueryUpgradePlanResponse")
}
func init() { proto.RegisterFile("em/authority/v1/query.proto", fileDescriptor_d766145e8bc7b365) }
var fileDescriptor_d766145e8bc7b365 = []byte{
- // 379 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0xbf, 0x8b, 0x13, 0x41,
- 0x14, 0xc7, 0x77, 0xfc, 0x05, 0xae, 0xa2, 0xb0, 0x18, 0x95, 0x18, 0x76, 0x75, 0x0b, 0x23, 0x48,
- 0x66, 0xd8, 0xd8, 0xa5, 0x8c, 0x82, 0x16, 0x16, 0x9a, 0xd2, 0x26, 0xcc, 0x6e, 0x1e, 0x93, 0xc1,
- 0xcc, 0xbc, 0xcd, 0xce, 0x6c, 0x70, 0x5b, 0xc1, 0xda, 0x80, 0x8d, 0xa5, 0xb5, 0x9d, 0xff, 0x45,
- 0xca, 0x80, 0xcd, 0x55, 0xb9, 0x23, 0xb9, 0xbf, 0xe0, 0xfe, 0x82, 0x23, 0xbb, 0x49, 0x48, 0xc2,
- 0xc1, 0x55, 0xbb, 0xf0, 0x79, 0x7c, 0xe7, 0xfb, 0x79, 0xcf, 0x7d, 0x06, 0x8a, 0xf1, 0xdc, 0x0e,
- 0x31, 0x93, 0xb6, 0x60, 0x93, 0x88, 0x8d, 0x73, 0xc8, 0x0a, 0x9a, 0x66, 0x68, 0xd1, 0x7b, 0x08,
- 0x8a, 0xee, 0x20, 0x9d, 0x44, 0xf5, 0x47, 0x02, 0x05, 0x96, 0x8c, 0xad, 0xff, 0xaa, 0xb1, 0xba,
- 0x9f, 0xa0, 0x51, 0x68, 0x58, 0xcc, 0x0d, 0xb0, 0x49, 0x14, 0x83, 0xe5, 0x11, 0x4b, 0x50, 0xea,
- 0x0d, 0x6f, 0x08, 0x44, 0x31, 0x02, 0xc6, 0x53, 0xc9, 0xb8, 0xd6, 0x68, 0xb9, 0x95, 0xa8, 0x4d,
- 0x45, 0xc3, 0x27, 0x6e, 0xed, 0xf3, 0xfa, 0xcd, 0xf7, 0xdc, 0x7c, 0xca, 0x64, 0x02, 0xa6, 0x07,
- 0xe3, 0x1c, 0x8c, 0x0d, 0xff, 0x11, 0xf7, 0xf1, 0x31, 0x31, 0x29, 0x6a, 0x03, 0xde, 0x94, 0xb8,
- 0x0f, 0x94, 0xd4, 0x7d, 0xc1, 0x4d, 0x3f, 0x2d, 0xd1, 0x53, 0xf2, 0xfc, 0xe6, 0xab, 0x7b, 0xed,
- 0x06, 0xad, 0xba, 0xd0, 0x75, 0x17, 0xba, 0xe9, 0x42, 0xdf, 0x41, 0xf2, 0x16, 0xa5, 0xee, 0x7e,
- 0x9c, 0x2d, 0x02, 0xe7, 0x62, 0x11, 0xd4, 0x0a, 0xae, 0x46, 0x9d, 0xf0, 0x30, 0x21, 0xfc, 0x7b,
- 0x1a, 0xbc, 0x16, 0xd2, 0x0e, 0xf3, 0x98, 0x26, 0xa8, 0xd8, 0x46, 0xaa, 0xfa, 0xb4, 0xcc, 0xe0,
- 0x2b, 0xb3, 0x45, 0x0a, 0x66, 0x1b, 0x66, 0x7a, 0xf7, 0x95, 0xd4, 0xbb, 0x6a, 0x9d, 0x5b, 0xbf,
- 0xff, 0x04, 0x4e, 0xfb, 0x27, 0x71, 0x6f, 0x97, 0x9d, 0xbd, 0x1f, 0xc4, 0xbd, 0xbb, 0xa3, 0xde,
- 0x4b, 0x7a, 0xb4, 0x4a, 0x7a, 0xa5, 0x73, 0xbd, 0x79, 0xed, 0x5c, 0xb5, 0x81, 0xb0, 0xf9, 0xfd,
- 0xff, 0xf9, 0xaf, 0x1b, 0x2f, 0xbc, 0x80, 0x41, 0x4b, 0xa1, 0x86, 0xe2, 0xf0, 0x8a, 0x82, 0x9b,
- 0xca, 0xaa, 0xfb, 0x61, 0xb6, 0xf4, 0xc9, 0x7c, 0xe9, 0x93, 0xb3, 0xa5, 0x4f, 0xa6, 0x2b, 0xdf,
- 0x99, 0xaf, 0x7c, 0xe7, 0x64, 0xe5, 0x3b, 0x5f, 0xe8, 0x9e, 0xec, 0x36, 0x04, 0x54, 0x6b, 0x04,
- 0x03, 0x01, 0x19, 0xfb, 0xb6, 0x17, 0x58, 0x8a, 0xc7, 0x77, 0xca, 0x7b, 0xbd, 0xb9, 0x0c, 0x00,
- 0x00, 0xff, 0xff, 0x25, 0x0c, 0xa6, 0x7e, 0x33, 0x02, 0x00, 0x00,
+ // 478 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3f, 0x6f, 0xd3, 0x40,
+ 0x18, 0xc6, 0x7d, 0xa5, 0x20, 0x71, 0x45, 0x20, 0x19, 0x4a, 0x43, 0xa8, 0xec, 0x62, 0x55, 0xb4,
+ 0x80, 0x72, 0xa7, 0x94, 0xad, 0x63, 0x00, 0xc1, 0xc0, 0x50, 0x22, 0xb1, 0xb0, 0x44, 0x17, 0xe7,
+ 0xd5, 0xf5, 0x84, 0xef, 0xce, 0xf5, 0x9d, 0x23, 0xbc, 0x22, 0xb1, 0xa2, 0x4a, 0x2c, 0x8c, 0x9d,
+ 0xd9, 0xf8, 0x16, 0x1d, 0x2b, 0xb1, 0x30, 0x15, 0x94, 0xf0, 0x09, 0xf8, 0x04, 0xc8, 0xf6, 0x39,
+ 0xa4, 0x6d, 0x24, 0x98, 0x12, 0xeb, 0x79, 0xff, 0xfc, 0x9e, 0xe7, 0x5e, 0x7c, 0x17, 0x24, 0x65,
+ 0xb9, 0xdd, 0xd7, 0x99, 0xb0, 0x05, 0x1d, 0x77, 0xe9, 0x41, 0x0e, 0x59, 0x41, 0xd2, 0x4c, 0x5b,
+ 0xed, 0xdf, 0x00, 0x49, 0x66, 0x22, 0x19, 0x77, 0xdb, 0xb7, 0xb8, 0xe6, 0xba, 0xd2, 0x68, 0xf9,
+ 0xaf, 0x2e, 0x6b, 0x07, 0xb1, 0x36, 0x52, 0x1b, 0x3a, 0x64, 0x06, 0xe8, 0xb8, 0x3b, 0x04, 0xcb,
+ 0xba, 0x34, 0xd6, 0x42, 0x39, 0x7d, 0x9d, 0x6b, 0xcd, 0x13, 0xa0, 0x2c, 0x15, 0x94, 0x29, 0xa5,
+ 0x2d, 0xb3, 0x42, 0x2b, 0xe3, 0xd4, 0x4d, 0xd7, 0x9d, 0xa7, 0x3c, 0x63, 0xa3, 0xbf, 0x03, 0xdc,
+ 0x77, 0x5d, 0x15, 0xad, 0xe1, 0xd5, 0x57, 0x25, 0xd9, 0x73, 0x66, 0xf6, 0x32, 0x11, 0x83, 0xe9,
+ 0xc3, 0x41, 0x0e, 0xc6, 0x46, 0x5f, 0x11, 0xbe, 0x7d, 0x5e, 0x31, 0xa9, 0x56, 0x06, 0xfc, 0x43,
+ 0x84, 0xaf, 0x4b, 0xa1, 0x06, 0x9c, 0x99, 0x41, 0x5a, 0x49, 0x2d, 0xb4, 0x71, 0x69, 0x7b, 0x65,
+ 0x67, 0x9d, 0xd4, 0x3b, 0x49, 0x49, 0x4c, 0xdc, 0x42, 0xf2, 0x14, 0xe2, 0x27, 0x5a, 0xa8, 0xde,
+ 0xcb, 0xe3, 0xd3, 0xd0, 0xfb, 0x7d, 0x1a, 0xae, 0x16, 0x4c, 0x26, 0xbb, 0xd1, 0xd9, 0x09, 0xd1,
+ 0x97, 0x1f, 0xe1, 0x23, 0x2e, 0xec, 0x7e, 0x3e, 0x24, 0xb1, 0x96, 0xd4, 0xc1, 0xd7, 0x3f, 0x1d,
+ 0x33, 0x7a, 0x4b, 0x6d, 0x91, 0x82, 0x69, 0x86, 0x99, 0xfe, 0x35, 0x29, 0xd4, 0x0c, 0x6d, 0x77,
+ 0xf9, 0xf3, 0x51, 0xe8, 0x45, 0x77, 0xf0, 0x5a, 0x85, 0xfc, 0xba, 0xb6, 0xb8, 0x97, 0x30, 0xd5,
+ 0xd8, 0x61, 0xb8, 0x75, 0x51, 0x72, 0x7e, 0x9e, 0xe1, 0xe5, 0x34, 0x61, 0xaa, 0x85, 0x36, 0xd0,
+ 0xbc, 0x89, 0x26, 0xa8, 0xc6, 0x47, 0xd9, 0xd3, 0xbb, 0xe9, 0x4c, 0xac, 0xd4, 0x26, 0xca, 0xbe,
+ 0xa8, 0x5f, 0xb5, 0xef, 0x1c, 0x2d, 0xe1, 0xcb, 0xd5, 0x0e, 0xff, 0x03, 0xc2, 0x57, 0x67, 0x6c,
+ 0xfe, 0x7d, 0x72, 0xee, 0xb9, 0xc9, 0xc2, 0xc4, 0xdb, 0x5b, 0xff, 0xac, 0xab, 0x79, 0xa3, 0xad,
+ 0xf7, 0xdf, 0x7e, 0x7d, 0x5a, 0xba, 0xe7, 0x87, 0x14, 0x3a, 0x52, 0x2b, 0x28, 0xce, 0x5e, 0x1a,
+ 0x67, 0xa6, 0xce, 0xd4, 0xff, 0x88, 0xf0, 0xca, 0x9c, 0x61, 0x7f, 0x7b, 0xf1, 0x86, 0x8b, 0x71,
+ 0xb5, 0x1f, 0xfc, 0x47, 0xa5, 0xa3, 0x79, 0x58, 0xd1, 0x6c, 0xfa, 0xd1, 0x62, 0x1a, 0x97, 0xe2,
+ 0xa0, 0x8c, 0xa8, 0xf7, 0xe2, 0x78, 0x12, 0xa0, 0x93, 0x49, 0x80, 0x7e, 0x4e, 0x02, 0x74, 0x38,
+ 0x0d, 0xbc, 0x93, 0x69, 0xe0, 0x7d, 0x9f, 0x06, 0xde, 0x1b, 0x32, 0xf7, 0xf6, 0xcd, 0x1c, 0x90,
+ 0x9d, 0x04, 0x46, 0x1c, 0x32, 0xfa, 0x6e, 0x6e, 0x66, 0x75, 0x07, 0xc3, 0x2b, 0xd5, 0xf9, 0x3e,
+ 0xfe, 0x13, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x52, 0x20, 0x32, 0x68, 0x03, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -158,6 +247,7 @@ const _ = grpc.SupportPackageIsVersion4
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
GasPrices(ctx context.Context, in *QueryGasPricesRequest, opts ...grpc.CallOption) (*QueryGasPricesResponse, error)
+ UpgradePlan(ctx context.Context, in *QueryUpgradePlanRequest, opts ...grpc.CallOption) (*QueryUpgradePlanResponse, error)
}
type queryClient struct {
@@ -177,9 +267,19 @@ func (c *queryClient) GasPrices(ctx context.Context, in *QueryGasPricesRequest,
return out, nil
}
+func (c *queryClient) UpgradePlan(ctx context.Context, in *QueryUpgradePlanRequest, opts ...grpc.CallOption) (*QueryUpgradePlanResponse, error) {
+ out := new(QueryUpgradePlanResponse)
+ err := c.cc.Invoke(ctx, "/em.authority.v1.Query/UpgradePlan", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// QueryServer is the server API for Query service.
type QueryServer interface {
GasPrices(context.Context, *QueryGasPricesRequest) (*QueryGasPricesResponse, error)
+ UpgradePlan(context.Context, *QueryUpgradePlanRequest) (*QueryUpgradePlanResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
@@ -189,6 +289,9 @@ type UnimplementedQueryServer struct {
func (*UnimplementedQueryServer) GasPrices(ctx context.Context, req *QueryGasPricesRequest) (*QueryGasPricesResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GasPrices not implemented")
}
+func (*UnimplementedQueryServer) UpgradePlan(ctx context.Context, req *QueryUpgradePlanRequest) (*QueryUpgradePlanResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method UpgradePlan not implemented")
+}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
@@ -212,6 +315,24 @@ func _Query_GasPrices_Handler(srv interface{}, ctx context.Context, dec func(int
return interceptor(ctx, in, info, handler)
}
+func _Query_UpgradePlan_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(QueryUpgradePlanRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(QueryServer).UpgradePlan(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/em.authority.v1.Query/UpgradePlan",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(QueryServer).UpgradePlan(ctx, req.(*QueryUpgradePlanRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "em.authority.v1.Query",
HandlerType: (*QueryServer)(nil),
@@ -220,6 +341,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{
MethodName: "GasPrices",
Handler: _Query_GasPrices_Handler,
},
+ {
+ MethodName: "UpgradePlan",
+ Handler: _Query_UpgradePlan_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "em/authority/v1/query.proto",
@@ -285,6 +410,62 @@ func (m *QueryGasPricesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
+func (m *QueryUpgradePlanRequest) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QueryUpgradePlanRequest) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QueryUpgradePlanRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
+func (m *QueryUpgradePlanResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *QueryUpgradePlanResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *QueryUpgradePlanResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.Plan.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintQuery(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ return len(dAtA) - i, nil
+}
+
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
@@ -320,6 +501,26 @@ func (m *QueryGasPricesResponse) Size() (n int) {
return n
}
+func (m *QueryUpgradePlanRequest) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
+func (m *QueryUpgradePlanResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = m.Plan.Size()
+ n += 1 + l + sovQuery(uint64(l))
+ return n
+}
+
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -460,6 +661,139 @@ func (m *QueryGasPricesResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *QueryUpgradePlanRequest) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QueryUpgradePlanRequest: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QueryUpgradePlanRequest: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *QueryUpgradePlanResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: QueryUpgradePlanResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: QueryUpgradePlanResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Plan", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowQuery
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthQuery
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if err := m.Plan.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipQuery(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthQuery
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipQuery(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
diff --git a/x/authority/types/query.pb.gw.go b/x/authority/types/query.pb.gw.go
index d0945e5a..56e60801 100644
--- a/x/authority/types/query.pb.gw.go
+++ b/x/authority/types/query.pb.gw.go
@@ -51,6 +51,24 @@ func local_request_Query_GasPrices_0(ctx context.Context, marshaler runtime.Mars
}
+func request_Query_UpgradePlan_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QueryUpgradePlanRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := client.UpgradePlan(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ return msg, metadata, err
+
+}
+
+func local_request_Query_UpgradePlan_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq QueryUpgradePlanRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := server.UpgradePlan(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -80,6 +98,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
})
+ mux.Handle("GET", pattern_Query_UpgradePlan_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_Query_UpgradePlan_0(rctx, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_UpgradePlan_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -141,13 +182,37 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
})
+ mux.Handle("GET", pattern_Query_UpgradePlan_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ rctx, err := runtime.AnnotateContext(ctx, mux, req)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_Query_UpgradePlan_0(rctx, inboundMarshaler, client, req, pathParams)
+ ctx = runtime.NewServerMetadataContext(ctx, md)
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Query_UpgradePlan_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
var (
pattern_Query_GasPrices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"e-money", "authority", "v1", "gasprices"}, "", runtime.AssumeColonVerbOpt(true)))
+
+ pattern_Query_UpgradePlan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"e-money", "authority", "v1", "upgrade_plan"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_Query_GasPrices_0 = runtime.ForwardResponseMessage
+
+ forward_Query_UpgradePlan_0 = runtime.ForwardResponseMessage
)
diff --git a/x/authority/types/tx.pb.go b/x/authority/types/tx.pb.go
index ada314cd..ac06bf9f 100644
--- a/x/authority/types/tx.pb.go
+++ b/x/authority/types/tx.pb.go
@@ -8,6 +8,7 @@ import (
fmt "fmt"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
types "github.com/cosmos/cosmos-sdk/types"
+ types1 "github.com/cosmos/cosmos-sdk/x/upgrade/types"
_ "github.com/gogo/protobuf/gogoproto"
grpc1 "github.com/gogo/protobuf/grpc"
proto "github.com/gogo/protobuf/proto"
@@ -398,6 +399,94 @@ func (m *MsgReplaceAuthorityResponse) GetNewAuthorityAddress() string {
return ""
}
+type MsgScheduleUpgrade struct {
+ Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty" yaml:"authority"`
+ Plan types1.Plan `protobuf:"bytes,2,opt,name=plan,proto3" json:"plan" yaml:"plan"`
+}
+
+func (m *MsgScheduleUpgrade) Reset() { *m = MsgScheduleUpgrade{} }
+func (m *MsgScheduleUpgrade) String() string { return proto.CompactTextString(m) }
+func (*MsgScheduleUpgrade) ProtoMessage() {}
+func (*MsgScheduleUpgrade) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1601f633ca5d263c, []int{8}
+}
+func (m *MsgScheduleUpgrade) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgScheduleUpgrade) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgScheduleUpgrade.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgScheduleUpgrade) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgScheduleUpgrade.Merge(m, src)
+}
+func (m *MsgScheduleUpgrade) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgScheduleUpgrade) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgScheduleUpgrade.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgScheduleUpgrade proto.InternalMessageInfo
+
+func (m *MsgScheduleUpgrade) GetAuthority() string {
+ if m != nil {
+ return m.Authority
+ }
+ return ""
+}
+
+func (m *MsgScheduleUpgrade) GetPlan() types1.Plan {
+ if m != nil {
+ return m.Plan
+ }
+ return types1.Plan{}
+}
+
+type MsgScheduleUpgradeResponse struct {
+}
+
+func (m *MsgScheduleUpgradeResponse) Reset() { *m = MsgScheduleUpgradeResponse{} }
+func (m *MsgScheduleUpgradeResponse) String() string { return proto.CompactTextString(m) }
+func (*MsgScheduleUpgradeResponse) ProtoMessage() {}
+func (*MsgScheduleUpgradeResponse) Descriptor() ([]byte, []int) {
+ return fileDescriptor_1601f633ca5d263c, []int{9}
+}
+func (m *MsgScheduleUpgradeResponse) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *MsgScheduleUpgradeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_MsgScheduleUpgradeResponse.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *MsgScheduleUpgradeResponse) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_MsgScheduleUpgradeResponse.Merge(m, src)
+}
+func (m *MsgScheduleUpgradeResponse) XXX_Size() int {
+ return m.Size()
+}
+func (m *MsgScheduleUpgradeResponse) XXX_DiscardUnknown() {
+ xxx_messageInfo_MsgScheduleUpgradeResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_MsgScheduleUpgradeResponse proto.InternalMessageInfo
+
func init() {
proto.RegisterType((*MsgCreateIssuer)(nil), "em.authority.v1.MsgCreateIssuer")
proto.RegisterType((*MsgCreateIssuerResponse)(nil), "em.authority.v1.MsgCreateIssuerResponse")
@@ -407,48 +496,55 @@ func init() {
proto.RegisterType((*MsgSetGasPricesResponse)(nil), "em.authority.v1.MsgSetGasPricesResponse")
proto.RegisterType((*MsgReplaceAuthority)(nil), "em.authority.v1.MsgReplaceAuthority")
proto.RegisterType((*MsgReplaceAuthorityResponse)(nil), "em.authority.v1.MsgReplaceAuthorityResponse")
+ proto.RegisterType((*MsgScheduleUpgrade)(nil), "em.authority.v1.MsgScheduleUpgrade")
+ proto.RegisterType((*MsgScheduleUpgradeResponse)(nil), "em.authority.v1.MsgScheduleUpgradeResponse")
}
func init() { proto.RegisterFile("em/authority/v1/tx.proto", fileDescriptor_1601f633ca5d263c) }
var fileDescriptor_1601f633ca5d263c = []byte{
- // 569 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xc1, 0x6e, 0xd3, 0x40,
- 0x10, 0x8d, 0x1b, 0xa9, 0x52, 0x97, 0x46, 0x6d, 0xdd, 0x20, 0x8c, 0xa9, 0xec, 0xb0, 0xe2, 0x90,
- 0x0a, 0xe2, 0x55, 0xc2, 0x01, 0x09, 0x89, 0x43, 0xd3, 0x4a, 0x94, 0x43, 0x24, 0x64, 0x38, 0x45,
- 0x42, 0x91, 0xe3, 0x0c, 0xae, 0x45, 0xec, 0x0d, 0x9e, 0x4d, 0xda, 0xdc, 0x41, 0xe2, 0xc8, 0x6f,
- 0xc0, 0x97, 0xf4, 0x82, 0xd4, 0x23, 0x27, 0x83, 0x92, 0x3f, 0xc8, 0x17, 0xa0, 0x7a, 0x13, 0x27,
- 0x0e, 0x96, 0x8a, 0x7a, 0xe0, 0x94, 0xc8, 0xef, 0xbd, 0x99, 0x37, 0x3b, 0x6f, 0x97, 0x68, 0x10,
- 0x30, 0x67, 0x28, 0xce, 0x78, 0xe4, 0x8b, 0x31, 0x1b, 0xd5, 0x99, 0xb8, 0xb0, 0x06, 0x11, 0x17,
- 0x5c, 0xdd, 0x81, 0xc0, 0x4a, 0x11, 0x6b, 0x54, 0xd7, 0xcb, 0x1e, 0xf7, 0x78, 0x82, 0xb1, 0xeb,
- 0x7f, 0x92, 0xa6, 0x1b, 0x2e, 0xc7, 0x80, 0x23, 0xeb, 0x3a, 0x08, 0x6c, 0x54, 0xef, 0x82, 0x70,
- 0xea, 0xcc, 0xe5, 0x7e, 0x28, 0x71, 0xfa, 0x4d, 0x21, 0x3b, 0x2d, 0xf4, 0x8e, 0x23, 0x70, 0x04,
- 0xbc, 0x42, 0x1c, 0x42, 0xa4, 0x36, 0xc8, 0x56, 0x5a, 0x59, 0x53, 0x2a, 0x4a, 0x75, 0xab, 0x59,
- 0x9e, 0xc5, 0xe6, 0xee, 0xd8, 0x09, 0xfa, 0xcf, 0x69, 0x0a, 0x51, 0x7b, 0x49, 0x53, 0x0f, 0xc9,
- 0xa6, 0x9f, 0xa8, 0xb5, 0x8d, 0x44, 0xb0, 0x37, 0x8b, 0xcd, 0x92, 0x14, 0xc8, 0xef, 0xd4, 0x9e,
- 0x13, 0xd4, 0x67, 0xa4, 0xd4, 0x83, 0x90, 0x07, 0x7e, 0xe8, 0x08, 0x9f, 0x87, 0xa8, 0x15, 0x2b,
- 0xc5, 0xac, 0x22, 0x81, 0x91, 0xda, 0x59, 0x1e, 0xbd, 0x4f, 0xee, 0xad, 0x59, 0xb5, 0x01, 0x07,
- 0x3c, 0x44, 0xa0, 0x1f, 0xc9, 0x6e, 0x0b, 0xbd, 0x13, 0x40, 0x11, 0xf1, 0xf1, 0x7f, 0x19, 0x83,
- 0xea, 0x44, 0x5b, 0x6f, 0x99, 0xda, 0xf9, 0x21, 0x4f, 0xf5, 0x0d, 0x88, 0x97, 0x0e, 0xbe, 0x8e,
- 0x7c, 0x17, 0xf0, 0x56, 0x76, 0x3e, 0x2b, 0x84, 0x78, 0x0e, 0x76, 0x06, 0x49, 0x09, 0x6d, 0xa3,
- 0x52, 0xac, 0xde, 0x69, 0x1c, 0x58, 0x72, 0xa7, 0xd6, 0xf5, 0x4e, 0xad, 0xf9, 0x4e, 0xad, 0x13,
- 0x70, 0x8f, 0xb9, 0x1f, 0x36, 0x4f, 0x2f, 0x63, 0xb3, 0x30, 0x8b, 0xcd, 0x3d, 0x59, 0x77, 0xa9,
- 0xa6, 0xdf, 0x7f, 0x99, 0x8f, 0x3d, 0x5f, 0x9c, 0x0d, 0xbb, 0x96, 0xcb, 0x03, 0x36, 0x0f, 0x86,
- 0xfc, 0xa9, 0x61, 0xef, 0x03, 0x13, 0xe3, 0x01, 0xe0, 0xa2, 0x10, 0xda, 0x5b, 0xde, 0xc2, 0xfb,
- 0xfc, 0xe4, 0x57, 0xc7, 0x49, 0x47, 0xfd, 0xa2, 0x90, 0xfd, 0x16, 0x7a, 0x36, 0x0c, 0xfa, 0x8e,
- 0x0b, 0x47, 0xa9, 0xf5, 0xdb, 0x8c, 0xfb, 0x82, 0x94, 0x42, 0x38, 0xef, 0x2c, 0x75, 0x72, 0x09,
- 0xda, 0x2c, 0x36, 0xcb, 0x52, 0x97, 0x81, 0xa9, 0xbd, 0x1d, 0xc2, 0x79, 0xda, 0x92, 0x22, 0x79,
- 0x90, 0xe3, 0x64, 0xe1, 0x54, 0x7d, 0x4b, 0xee, 0x66, 0xe4, 0x1d, 0xa7, 0xd7, 0x8b, 0x00, 0x71,
- 0xee, 0xae, 0x32, 0x8b, 0xcd, 0x83, 0x9c, 0x2e, 0x0b, 0x1a, 0xb5, 0xf7, 0x57, 0xbb, 0x1d, 0xc9,
- 0xaf, 0x8d, 0x4f, 0x45, 0x52, 0x6c, 0xa1, 0xa7, 0xb6, 0xc9, 0x76, 0xe6, 0x12, 0x55, 0xac, 0xb5,
- 0x0b, 0x6a, 0xad, 0x65, 0x57, 0xaf, 0xde, 0xc4, 0x48, 0x9d, 0xbf, 0x23, 0xa5, 0x6c, 0xb4, 0x1f,
- 0xe6, 0x49, 0x33, 0x14, 0xfd, 0xf0, 0x46, 0x4a, 0x5a, 0xbe, 0x4d, 0xb6, 0x33, 0x49, 0xcd, 0xb5,
- 0xbe, 0xca, 0xc8, 0xb7, 0x9e, 0x17, 0x0f, 0xf5, 0x3d, 0xd9, 0xfd, 0x2b, 0x1a, 0x8f, 0xf2, 0xd4,
- 0xeb, 0x2c, 0xfd, 0xc9, 0xbf, 0xb0, 0x16, 0x7d, 0x9a, 0xa7, 0x97, 0x13, 0x43, 0xb9, 0x9a, 0x18,
- 0xca, 0xef, 0x89, 0xa1, 0x7c, 0x9d, 0x1a, 0x85, 0xab, 0xa9, 0x51, 0xf8, 0x39, 0x35, 0x0a, 0x6d,
- 0x6b, 0x25, 0xf3, 0x50, 0x0b, 0x78, 0x08, 0x63, 0x06, 0x41, 0xad, 0x0f, 0x3d, 0x0f, 0x22, 0x76,
- 0xb1, 0xf2, 0xbc, 0x26, 0xf9, 0xef, 0x6e, 0x26, 0x0f, 0xe3, 0xd3, 0x3f, 0x01, 0x00, 0x00, 0xff,
- 0xff, 0x3b, 0x36, 0x40, 0x46, 0x7b, 0x05, 0x00, 0x00,
+ // 656 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x4f, 0xd4, 0x4e,
+ 0x18, 0xde, 0xb2, 0xbf, 0x90, 0x30, 0xb0, 0x01, 0x0a, 0xbf, 0x58, 0x2b, 0x69, 0xd7, 0x91, 0x03,
+ 0x04, 0x69, 0xb3, 0x78, 0x30, 0x31, 0xf1, 0xc0, 0x82, 0x11, 0x0f, 0x9b, 0x90, 0xaa, 0x17, 0x12,
+ 0x43, 0x66, 0xdb, 0xd7, 0xd2, 0xd8, 0x76, 0x6a, 0xa7, 0x0b, 0xec, 0x07, 0x30, 0xf1, 0xa6, 0x5f,
+ 0x43, 0x3f, 0x09, 0x17, 0x13, 0x8e, 0x9e, 0xaa, 0x81, 0x93, 0xd7, 0xfd, 0x04, 0x66, 0x3b, 0x6d,
+ 0xb7, 0x2d, 0x4d, 0x20, 0x7b, 0xf0, 0xb4, 0xdb, 0x79, 0x9f, 0xe7, 0x7d, 0x9f, 0xf7, 0xdf, 0x0c,
+ 0x92, 0xc0, 0xd3, 0xc9, 0x20, 0x3a, 0xa1, 0xa1, 0x13, 0x0d, 0xf5, 0xd3, 0x8e, 0x1e, 0x9d, 0x6b,
+ 0x41, 0x48, 0x23, 0x2a, 0x2e, 0x82, 0xa7, 0xe5, 0x16, 0xed, 0xb4, 0x23, 0xaf, 0xda, 0xd4, 0xa6,
+ 0x89, 0x4d, 0x1f, 0xff, 0xe3, 0x30, 0x59, 0x31, 0x29, 0xf3, 0x28, 0xd3, 0xfb, 0x84, 0x81, 0x7e,
+ 0xda, 0xe9, 0x43, 0x44, 0x3a, 0xba, 0x49, 0x1d, 0x3f, 0xb5, 0xaf, 0xa7, 0xf6, 0x41, 0x60, 0x87,
+ 0xc4, 0x9a, 0x40, 0xd2, 0x6f, 0x8e, 0xc2, 0xdf, 0x04, 0xb4, 0xd8, 0x63, 0xf6, 0x5e, 0x08, 0x24,
+ 0x82, 0x57, 0x8c, 0x0d, 0x20, 0x14, 0x77, 0xd0, 0x5c, 0x1e, 0x5f, 0x12, 0xda, 0xc2, 0xc6, 0x5c,
+ 0x77, 0x75, 0x14, 0xab, 0x4b, 0x43, 0xe2, 0xb9, 0xcf, 0x70, 0x6e, 0xc2, 0xc6, 0x04, 0x26, 0x6e,
+ 0xa2, 0x59, 0x27, 0x61, 0x4b, 0x33, 0x09, 0x61, 0x79, 0x14, 0xab, 0x2d, 0x4e, 0xe0, 0xe7, 0xd8,
+ 0x48, 0x01, 0xe2, 0x53, 0xd4, 0xb2, 0xc0, 0xa7, 0x9e, 0xe3, 0x93, 0xc8, 0xa1, 0x3e, 0x93, 0x9a,
+ 0xed, 0x66, 0x99, 0x91, 0x98, 0x19, 0x36, 0xca, 0x38, 0x7c, 0x1f, 0xdd, 0xab, 0x48, 0x35, 0x80,
+ 0x05, 0xd4, 0x67, 0x80, 0x3f, 0xa2, 0xa5, 0x1e, 0xb3, 0xf7, 0x81, 0x45, 0x21, 0x1d, 0xfe, 0x93,
+ 0x34, 0xb0, 0x8c, 0xa4, 0x6a, 0xc8, 0x5c, 0xce, 0x0f, 0x5e, 0xd5, 0xd7, 0x10, 0xbd, 0x24, 0xec,
+ 0x30, 0x74, 0x4c, 0x60, 0x53, 0xc9, 0xf9, 0x24, 0x20, 0x64, 0x13, 0x76, 0x1c, 0x24, 0x2e, 0xa4,
+ 0x99, 0x76, 0x73, 0x63, 0x7e, 0x67, 0x4d, 0xe3, 0x9d, 0xd5, 0xc6, 0x9d, 0xd7, 0xd2, 0xb6, 0x6a,
+ 0xfb, 0x60, 0xee, 0x51, 0xc7, 0xef, 0x1e, 0x5c, 0xc4, 0x6a, 0x63, 0x14, 0xab, 0xcb, 0xdc, 0xef,
+ 0x84, 0x8d, 0xbf, 0xff, 0x52, 0xb7, 0x6c, 0x27, 0x3a, 0x19, 0xf4, 0x35, 0x93, 0x7a, 0x7a, 0x3a,
+ 0x1e, 0xfc, 0x67, 0x9b, 0x59, 0x1f, 0xf4, 0x68, 0x18, 0x00, 0xcb, 0x1c, 0x31, 0x63, 0xce, 0xce,
+ 0xb4, 0xa7, 0x95, 0x2f, 0xa6, 0x93, 0xa7, 0xfa, 0x59, 0x40, 0x2b, 0x3d, 0x66, 0x1b, 0x10, 0xb8,
+ 0xc4, 0x84, 0xdd, 0x5c, 0xfa, 0x34, 0xe9, 0x3e, 0x47, 0x2d, 0x1f, 0xce, 0x8e, 0x27, 0x3c, 0xde,
+ 0x04, 0x69, 0x14, 0xab, 0xab, 0x9c, 0x57, 0x32, 0x63, 0x63, 0xc1, 0x87, 0xb3, 0x3c, 0x24, 0x66,
+ 0xe8, 0x41, 0x8d, 0x92, 0x4c, 0xa9, 0xf8, 0x06, 0xfd, 0x5f, 0xa2, 0x1f, 0x13, 0xcb, 0x0a, 0x81,
+ 0xb1, 0x54, 0x5d, 0x7b, 0x14, 0xab, 0x6b, 0x35, 0x51, 0x32, 0x18, 0x36, 0x56, 0x8a, 0xd1, 0x76,
+ 0xd3, 0xd3, 0x2f, 0x02, 0x12, 0xc7, 0xb5, 0x31, 0x4f, 0xc0, 0x1a, 0xb8, 0xf0, 0x96, 0x6f, 0xd7,
+ 0x54, 0xe9, 0xbf, 0x40, 0xff, 0x05, 0x2e, 0xf1, 0x93, 0xac, 0x0b, 0x6d, 0xce, 0x16, 0x36, 0xeb,
+ 0xf4, 0xa1, 0x4b, 0xfc, 0xee, 0x4a, 0xda, 0xe6, 0x79, 0xee, 0x70, 0xcc, 0xc3, 0x46, 0x42, 0xc7,
+ 0x6b, 0x48, 0xbe, 0x29, 0x28, 0xab, 0xc2, 0xce, 0x9f, 0x26, 0x6a, 0xf6, 0x98, 0x2d, 0x1e, 0xa1,
+ 0x85, 0xd2, 0xd2, 0xb7, 0xb5, 0xca, 0xb5, 0xa3, 0x55, 0x76, 0x4d, 0xde, 0xb8, 0x0d, 0x91, 0x57,
+ 0xfa, 0x1d, 0x6a, 0x95, 0x57, 0xf1, 0x61, 0x1d, 0xb5, 0x04, 0x91, 0x37, 0x6f, 0x85, 0xe4, 0xee,
+ 0x8f, 0xd0, 0x42, 0x69, 0xb3, 0x6a, 0xa5, 0x17, 0x11, 0xf5, 0xd2, 0xeb, 0xc6, 0x59, 0x7c, 0x8f,
+ 0x96, 0x6e, 0x8c, 0xf2, 0x7a, 0x1d, 0xbb, 0x8a, 0x92, 0x1f, 0xdf, 0x05, 0x95, 0xc7, 0x31, 0xd1,
+ 0x62, 0x75, 0x64, 0x1e, 0xd5, 0x8a, 0x2c, 0x83, 0xe4, 0xad, 0x3b, 0x80, 0xb2, 0x20, 0xdd, 0x83,
+ 0x8b, 0x2b, 0x45, 0xb8, 0xbc, 0x52, 0x84, 0xdf, 0x57, 0x8a, 0xf0, 0xf5, 0x5a, 0x69, 0x5c, 0x5e,
+ 0x2b, 0x8d, 0x9f, 0xd7, 0x4a, 0xe3, 0x48, 0x2b, 0x5c, 0x04, 0xb0, 0xed, 0x51, 0x1f, 0x86, 0x3a,
+ 0x78, 0xdb, 0x2e, 0x58, 0x36, 0x84, 0xfa, 0x79, 0xe1, 0x65, 0x4a, 0x2e, 0x85, 0xfe, 0x6c, 0xf2,
+ 0x5a, 0x3c, 0xf9, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x82, 0x0d, 0xef, 0xdc, 0xb6, 0x06, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -467,6 +563,7 @@ type MsgClient interface {
DestroyIssuer(ctx context.Context, in *MsgDestroyIssuer, opts ...grpc.CallOption) (*MsgDestroyIssuerResponse, error)
SetGasPrices(ctx context.Context, in *MsgSetGasPrices, opts ...grpc.CallOption) (*MsgSetGasPricesResponse, error)
ReplaceAuthority(ctx context.Context, in *MsgReplaceAuthority, opts ...grpc.CallOption) (*MsgReplaceAuthorityResponse, error)
+ ScheduleUpgrade(ctx context.Context, in *MsgScheduleUpgrade, opts ...grpc.CallOption) (*MsgScheduleUpgradeResponse, error)
}
type msgClient struct {
@@ -513,12 +610,22 @@ func (c *msgClient) ReplaceAuthority(ctx context.Context, in *MsgReplaceAuthorit
return out, nil
}
+func (c *msgClient) ScheduleUpgrade(ctx context.Context, in *MsgScheduleUpgrade, opts ...grpc.CallOption) (*MsgScheduleUpgradeResponse, error) {
+ out := new(MsgScheduleUpgradeResponse)
+ err := c.cc.Invoke(ctx, "/em.authority.v1.Msg/ScheduleUpgrade", in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// MsgServer is the server API for Msg service.
type MsgServer interface {
CreateIssuer(context.Context, *MsgCreateIssuer) (*MsgCreateIssuerResponse, error)
DestroyIssuer(context.Context, *MsgDestroyIssuer) (*MsgDestroyIssuerResponse, error)
SetGasPrices(context.Context, *MsgSetGasPrices) (*MsgSetGasPricesResponse, error)
ReplaceAuthority(context.Context, *MsgReplaceAuthority) (*MsgReplaceAuthorityResponse, error)
+ ScheduleUpgrade(context.Context, *MsgScheduleUpgrade) (*MsgScheduleUpgradeResponse, error)
}
// UnimplementedMsgServer can be embedded to have forward compatible implementations.
@@ -537,6 +644,9 @@ func (*UnimplementedMsgServer) SetGasPrices(ctx context.Context, req *MsgSetGasP
func (*UnimplementedMsgServer) ReplaceAuthority(ctx context.Context, req *MsgReplaceAuthority) (*MsgReplaceAuthorityResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ReplaceAuthority not implemented")
}
+func (*UnimplementedMsgServer) ScheduleUpgrade(ctx context.Context, req *MsgScheduleUpgrade) (*MsgScheduleUpgradeResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ScheduleUpgrade not implemented")
+}
func RegisterMsgServer(s grpc1.Server, srv MsgServer) {
s.RegisterService(&_Msg_serviceDesc, srv)
@@ -614,6 +724,24 @@ func _Msg_ReplaceAuthority_Handler(srv interface{}, ctx context.Context, dec fun
return interceptor(ctx, in, info, handler)
}
+func _Msg_ScheduleUpgrade_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(MsgScheduleUpgrade)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(MsgServer).ScheduleUpgrade(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: "/em.authority.v1.Msg/ScheduleUpgrade",
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(MsgServer).ScheduleUpgrade(ctx, req.(*MsgScheduleUpgrade))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
var _Msg_serviceDesc = grpc.ServiceDesc{
ServiceName: "em.authority.v1.Msg",
HandlerType: (*MsgServer)(nil),
@@ -634,6 +762,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{
MethodName: "ReplaceAuthority",
Handler: _Msg_ReplaceAuthority_Handler,
},
+ {
+ MethodName: "ScheduleUpgrade",
+ Handler: _Msg_ScheduleUpgrade_Handler,
+ },
},
Streams: []grpc.StreamDesc{},
Metadata: "em/authority/v1/tx.proto",
@@ -902,6 +1034,69 @@ func (m *MsgReplaceAuthorityResponse) MarshalToSizedBuffer(dAtA []byte) (int, er
return len(dAtA) - i, nil
}
+func (m *MsgScheduleUpgrade) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgScheduleUpgrade) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgScheduleUpgrade) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ {
+ size, err := m.Plan.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintTx(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0x12
+ if len(m.Authority) > 0 {
+ i -= len(m.Authority)
+ copy(dAtA[i:], m.Authority)
+ i = encodeVarintTx(dAtA, i, uint64(len(m.Authority)))
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
+func (m *MsgScheduleUpgradeResponse) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *MsgScheduleUpgradeResponse) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *MsgScheduleUpgradeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ return len(dAtA) - i, nil
+}
+
func encodeVarintTx(dAtA []byte, offset int, v uint64) int {
offset -= sovTx(v)
base := offset
@@ -1029,6 +1224,30 @@ func (m *MsgReplaceAuthorityResponse) Size() (n int) {
return n
}
+func (m *MsgScheduleUpgrade) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ l = len(m.Authority)
+ if l > 0 {
+ n += 1 + l + sovTx(uint64(l))
+ }
+ l = m.Plan.Size()
+ n += 1 + l + sovTx(uint64(l))
+ return n
+}
+
+func (m *MsgScheduleUpgradeResponse) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ return n
+}
+
func sovTx(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
@@ -1757,6 +1976,171 @@ func (m *MsgReplaceAuthorityResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *MsgScheduleUpgrade) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgScheduleUpgrade: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgScheduleUpgrade: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType)
+ }
+ var stringLen uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ stringLen |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ intStringLen := int(stringLen)
+ if intStringLen < 0 {
+ return ErrInvalidLengthTx
+ }
+ postIndex := iNdEx + intStringLen
+ if postIndex < 0 {
+ return ErrInvalidLengthTx
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ m.Authority = string(dAtA[iNdEx:postIndex])
+ iNdEx = postIndex
+ case 2:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Plan", 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 := m.Plan.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
+func (m *MsgScheduleUpgradeResponse) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTx
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: MsgScheduleUpgradeResponse: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: MsgScheduleUpgradeResponse: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTx(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTx
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func skipTx(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0