Release v0.34.2
* Merge PR #4163: Fix v0.33.x export script to port gov data correctly * Remove TOC * Add missing changelog entry for v0.34.1 * Merge PR #4182: Cherry pick #4083 into v0.34.2 * Merge PR #4181: Cherry pick 4135 v0.34.2 * Merge PR #4183: Cherry pick 4181 into v0.34.2 * Support pagination and status query params for /staking/validators * Rename BondStatusToString to String * Cherry pick 4181 * Remove pending log * Fix CODEOWNERS
This commit is contained in:
parent
bfb2b49b09
commit
13bd5b62cf
|
@ -1,9 +1,4 @@
|
|||
# CODEOWNERS: https://help.github.com/articles/about-codeowners/
|
||||
|
||||
# Primary repo maintainers
|
||||
* @ebuchman @rigelrozanski @cwgoes
|
||||
|
||||
# Precious documentation
|
||||
/docs/README.md @zramsay
|
||||
/docs/DOCS_README.md @zramsay
|
||||
/docs/.vuepress/ @zramsay
|
||||
* @alessio @alexanderbez @cwgoes @jackzampolin
|
||||
|
|
51
CHANGELOG.md
51
CHANGELOG.md
|
@ -1,30 +1,31 @@
|
|||
# Changelog
|
||||
|
||||
* [0.34.0](#0340)
|
||||
* [Breaking Changes](#breaking-changes)
|
||||
* [Gaia](#gaia)
|
||||
* [Gaia CLI](#gaia-cli)
|
||||
* [SDK](#sdk)
|
||||
* [Tendermint](#tendermint)
|
||||
* [New features](#new-features)
|
||||
* [SDK](#sdk-1)
|
||||
* [Gaia](#gaia-1)
|
||||
* [Gaia CLI](#gaia-cli-1)
|
||||
* [Gaia REST API](#gaia-rest-api)
|
||||
* [Improvements](#improvements)
|
||||
* [Gaia](#gaia-2)
|
||||
* [Gaia CLI](#gaia-cli-2)
|
||||
* [SDK](#sdk-2)
|
||||
* [Bug Fixes](#bug-fixes)
|
||||
* [Gaia](#gaia-3)
|
||||
* [Gaia CLI](#gaia-cli-3)
|
||||
* [SDK](#sdk-3)
|
||||
* [0.33.2](#0332)
|
||||
* [Improvements](#improvements-1)
|
||||
* [Tendermint](#tendermint-1)
|
||||
* [0.33.1](#0331)
|
||||
* [Bug Fixes](#bug-fixes-1)
|
||||
* [Gaia](#gaia-4)
|
||||
## 0.34.2
|
||||
|
||||
### Improvements
|
||||
|
||||
#### SDK
|
||||
|
||||
* [\#4135](https://github.com/cosmos/cosmos-sdk/pull/4135) Add further clarification
|
||||
to generate only usage.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
#### SDK
|
||||
|
||||
* [\#4135](https://github.com/cosmos/cosmos-sdk/pull/4135) Fix `NewResponseFormatBroadcastTxCommit`
|
||||
* [\#4053](https://github.com/cosmos/cosmos-sdk/issues/4053) Add `--inv-check-period`
|
||||
flag to gaiad to set period at which invariants checks will run.
|
||||
* [\#4099](https://github.com/cosmos/cosmos-sdk/issues/4099) Update the /staking/validators endpoint to support
|
||||
status and pagination query flags.
|
||||
|
||||
## 0.34.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
#### Gaia
|
||||
|
||||
* [#4163](https://github.com/cosmos/cosmos-sdk/pull/4163) Fix v0.33.x export script to port gov data correctly.
|
||||
|
||||
## 0.34.0
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/pelletier/go-toml"
|
||||
toml "github.com/pelletier/go-toml"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
|
|
@ -7,6 +7,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
@ -292,7 +294,7 @@ func GetFromFields(from string, genOnly bool) (sdk.AccAddress, string, error) {
|
|||
if genOnly {
|
||||
addr, err := sdk.AccAddressFromBech32(from)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return nil, "", errors.Wrap(err, "must provide a valid Bech32 address for generate-only")
|
||||
}
|
||||
|
||||
return addr, "", nil
|
||||
|
|
|
@ -93,7 +93,7 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command {
|
|||
c.Flags().Bool(FlagPrintResponse, true, "return tx response (only works with async = false)")
|
||||
c.Flags().Bool(FlagTrustNode, true, "Trust connected full node (don't verify proofs for responses)")
|
||||
c.Flags().Bool(FlagDryRun, false, "ignore the --gas flag and perform a simulation of a transaction, but don't broadcast it")
|
||||
c.Flags().Bool(FlagGenerateOnly, false, "build an unsigned transaction and write it to STDOUT")
|
||||
c.Flags().Bool(FlagGenerateOnly, false, "Build an unsigned transaction and write it to STDOUT (when enabled, the local Keybase is not accessible)")
|
||||
c.Flags().BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
|
||||
|
||||
// --gas can accept integers and "simulate"
|
||||
|
|
|
@ -763,7 +763,23 @@ paths:
|
|||
description: Internal Server Error
|
||||
/staking/validators:
|
||||
get:
|
||||
summary: Get all validator candidates
|
||||
summary: Get all validator candidates. By default it returns only the bonded validators.
|
||||
parameters:
|
||||
- in: query
|
||||
name: status
|
||||
type: string
|
||||
description: The validator bond status. Must be either 'bonded', 'unbonded', or 'unbonding'.
|
||||
x-example: bonded
|
||||
- in: query
|
||||
name: page
|
||||
description: The gage number.
|
||||
type: integer
|
||||
x-example: 1
|
||||
- in: query
|
||||
name: limit
|
||||
description: The maximum number of items per page.
|
||||
type: integer
|
||||
x-example: 1
|
||||
tags:
|
||||
- ICS21
|
||||
produces:
|
||||
|
|
|
@ -221,7 +221,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress
|
|||
privVal.Reset()
|
||||
|
||||
db := dbm.NewMemDB()
|
||||
app := gapp.NewGaiaApp(logger, db, nil, true, false)
|
||||
app := gapp.NewGaiaApp(logger, db, nil, true, 0)
|
||||
cdc = gapp.MakeCodec()
|
||||
|
||||
genesisFile := config.GenesisFile()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
|
||||
|
|
|
@ -162,7 +162,6 @@ func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec)
|
|||
}
|
||||
|
||||
tags, page, limit, err = rest.ParseHTTPArgs(r)
|
||||
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
|
|
|
@ -42,7 +42,7 @@ type GaiaApp struct {
|
|||
*bam.BaseApp
|
||||
cdc *codec.Codec
|
||||
|
||||
assertInvariantsBlockly bool
|
||||
invCheckPeriod uint
|
||||
|
||||
// keys to access the substores
|
||||
keyMain *sdk.KVStoreKey
|
||||
|
@ -72,7 +72,8 @@ type GaiaApp struct {
|
|||
}
|
||||
|
||||
// NewGaiaApp returns a reference to an initialized GaiaApp.
|
||||
func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest, assertInvariantsBlockly bool,
|
||||
func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool,
|
||||
invCheckPeriod uint,
|
||||
baseAppOptions ...func(*bam.BaseApp)) *GaiaApp {
|
||||
|
||||
cdc := MakeCodec()
|
||||
|
@ -83,6 +84,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest,
|
|||
var app = &GaiaApp{
|
||||
BaseApp: bApp,
|
||||
cdc: cdc,
|
||||
invCheckPeriod: invCheckPeriod,
|
||||
keyMain: sdk.NewKVStoreKey(bam.MainStoreKey),
|
||||
keyAccount: sdk.NewKVStoreKey(auth.StoreKey),
|
||||
keyStaking: sdk.NewKVStoreKey(staking.StoreKey),
|
||||
|
@ -244,7 +246,7 @@ func (app *GaiaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.R
|
|||
validatorUpdates, endBlockerTags := staking.EndBlocker(ctx, app.stakingKeeper)
|
||||
tags = append(tags, endBlockerTags...)
|
||||
|
||||
if app.assertInvariantsBlockly {
|
||||
if app.invCheckPeriod != 0 && ctx.BlockHeight()%int64(app.invCheckPeriod) == 0 {
|
||||
app.assertRuntimeInvariants()
|
||||
}
|
||||
|
||||
|
|
|
@ -55,11 +55,11 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error {
|
|||
|
||||
func TestGaiadExport(t *testing.T) {
|
||||
db := db.NewMemDB()
|
||||
gapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, false)
|
||||
gapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
|
||||
setGenesis(gapp)
|
||||
|
||||
// Making a new app object with the db, so that initchain hasn't been called
|
||||
newGapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, false)
|
||||
newGapp := NewGaiaApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, 0)
|
||||
_, _, err := newGapp.ExportAppStateAndValidators(false, []string{})
|
||||
require.NoError(t, err, "ExportAppStateAndValidators should not have an error")
|
||||
}
|
||||
|
|
|
@ -26,5 +26,6 @@ func (app *GaiaApp) assertRuntimeInvariantsOnContext(ctx sdk.Context) {
|
|||
}
|
||||
end := time.Now()
|
||||
diff := end.Sub(start)
|
||||
app.BaseApp.Logger().With("module", "invariants").Info("Asserted all invariants", "duration", diff)
|
||||
app.BaseApp.Logger().With("module", "invariants").Info(
|
||||
"Asserted all invariants", "duration", diff, "height", app.LastBlockHeight())
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ func BenchmarkFullGaiaSimulation(b *testing.B) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0)
|
||||
|
||||
// Run randomized simulation
|
||||
// TODO parameterize numbers, save for a later PR
|
||||
|
@ -354,7 +354,7 @@ func TestFullGaiaSimulation(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
|
@ -388,7 +388,7 @@ func TestGaiaImportExport(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
|
@ -415,7 +415,7 @@ func TestGaiaImportExport(t *testing.T) {
|
|||
newDB.Close()
|
||||
os.RemoveAll(newDir)
|
||||
}()
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, false, fauxMerkleModeOpt)
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", newApp.Name())
|
||||
var genesisState GenesisState
|
||||
err = app.cdc.UnmarshalJSON(appState, &genesisState)
|
||||
|
@ -478,7 +478,7 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
|
|||
db.Close()
|
||||
os.RemoveAll(dir)
|
||||
}()
|
||||
app := NewGaiaApp(logger, db, nil, true, false, fauxMerkleModeOpt)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", app.Name())
|
||||
|
||||
// Run randomized simulation
|
||||
|
@ -514,7 +514,7 @@ func TestGaiaSimulationAfterImport(t *testing.T) {
|
|||
newDB.Close()
|
||||
os.RemoveAll(newDir)
|
||||
}()
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, false, fauxMerkleModeOpt)
|
||||
newApp := NewGaiaApp(log.NewNopLogger(), newDB, nil, true, 0, fauxMerkleModeOpt)
|
||||
require.Equal(t, "GaiaApp", newApp.Name())
|
||||
newApp.InitChain(abci.RequestInitChain{
|
||||
AppStateBytes: appState,
|
||||
|
@ -542,7 +542,7 @@ func TestAppStateDeterminism(t *testing.T) {
|
|||
for j := 0; j < numTimesToRunPerSeed; j++ {
|
||||
logger := log.NewNopLogger()
|
||||
db := dbm.NewMemDB()
|
||||
app := NewGaiaApp(logger, db, nil, true, false)
|
||||
app := NewGaiaApp(logger, db, nil, true, 0)
|
||||
|
||||
// Run randomized simulation
|
||||
simulation.SimulateFromSeed(
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/go-amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
|
|
|
@ -23,9 +23,9 @@ import (
|
|||
)
|
||||
|
||||
// gaiad custom flags
|
||||
const flagAssertInvariantsBlockly = "assert-invariants-blockly"
|
||||
const flagInvCheckPeriod = "inv-check-period"
|
||||
|
||||
var assertInvariantsBlockly bool
|
||||
var invCheckPeriod uint
|
||||
|
||||
func main() {
|
||||
cdc := app.MakeCodec()
|
||||
|
@ -43,6 +43,7 @@ func main() {
|
|||
Short: "Gaia Daemon (server)",
|
||||
PersistentPreRunE: server.PersistentPreRunEFn(ctx),
|
||||
}
|
||||
|
||||
rootCmd.AddCommand(gaiaInit.InitCmd(ctx, cdc))
|
||||
rootCmd.AddCommand(gaiaInit.CollectGenTxsCmd(ctx, cdc))
|
||||
rootCmd.AddCommand(gaiaInit.TestnetFilesCmd(ctx, cdc))
|
||||
|
@ -55,8 +56,8 @@ func main() {
|
|||
|
||||
// prepare and add flags
|
||||
executor := cli.PrepareBaseCmd(rootCmd, "GA", app.DefaultNodeHome)
|
||||
rootCmd.PersistentFlags().BoolVar(&assertInvariantsBlockly, flagAssertInvariantsBlockly,
|
||||
false, "Assert registered invariants on a blockly basis")
|
||||
rootCmd.PersistentFlags().UintVar(&invCheckPeriod, flagInvCheckPeriod,
|
||||
1, "Assert registered invariants every N blocks")
|
||||
err := executor.Execute()
|
||||
if err != nil {
|
||||
// handle with #870
|
||||
|
@ -66,7 +67,7 @@ func main() {
|
|||
|
||||
func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer) abci.Application {
|
||||
return app.NewGaiaApp(
|
||||
logger, db, traceStore, true, assertInvariantsBlockly,
|
||||
logger, db, traceStore, true, invCheckPeriod,
|
||||
baseapp.SetPruning(store.NewPruningOptionsFromString(viper.GetString("pruning"))),
|
||||
baseapp.SetMinGasPrices(viper.GetString(server.FlagMinGasPrices)),
|
||||
)
|
||||
|
@ -77,13 +78,13 @@ func exportAppStateAndTMValidators(
|
|||
) (json.RawMessage, []tmtypes.GenesisValidator, error) {
|
||||
|
||||
if height != -1 {
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, false, false)
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, false, uint(1))
|
||||
err := gApp.LoadHeight(height)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
|
||||
}
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, true, false)
|
||||
gApp := app.NewGaiaApp(logger, db, traceStore, true, uint(1))
|
||||
return gApp.ExportAppStateAndValidators(forZeroHeight, jailWhiteList)
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ func run(rootDir string) {
|
|||
// Application
|
||||
fmt.Println("Creating application")
|
||||
myapp := app.NewGaiaApp(
|
||||
ctx.Logger, appDB, traceStoreWriter, true, true,
|
||||
ctx.Logger, appDB, traceStoreWriter, true, uint(1),
|
||||
baseapp.SetPruning(store.PruneEverything), // nothing
|
||||
)
|
||||
|
||||
|
|
|
@ -15,7 +15,10 @@ def process_raw_genesis(genesis, parsed_args):
|
|||
},
|
||||
}
|
||||
|
||||
# default tm value
|
||||
# migrate governance state as the internal structure of proposals has changed
|
||||
migrate_gov_data(genesis['app_state']['gov'])
|
||||
|
||||
# default Tendermint block time (ms)
|
||||
genesis['consensus_params']['block']['time_iota_ms'] = '1000'
|
||||
|
||||
# proposal #1 updates
|
||||
|
@ -36,6 +39,36 @@ def process_raw_genesis(genesis, parsed_args):
|
|||
return genesis
|
||||
|
||||
|
||||
def migrate_gov_data(gov_data):
|
||||
for p in gov_data['proposals']:
|
||||
# get Amino type and value
|
||||
t = p['type']
|
||||
v = p['value']
|
||||
|
||||
del p['type']
|
||||
del p['value']
|
||||
|
||||
assert t == 'gov/TextProposal', 'invalid proposal type: {t}'
|
||||
assert p == {}, 'expected proposal to be empty after deleting contents'
|
||||
|
||||
p['proposal_content'] = {
|
||||
'type': t,
|
||||
'value': {
|
||||
'title': v['title'],
|
||||
'description': v['description']
|
||||
}
|
||||
}
|
||||
|
||||
p['proposal_id'] = v['proposal_id']
|
||||
p['proposal_status'] = v['proposal_status']
|
||||
p['final_tally_result'] = v['final_tally_result']
|
||||
p['submit_time'] = v['submit_time']
|
||||
p['deposit_end_time'] = v['deposit_end_time']
|
||||
p['total_deposit'] = v['total_deposit']
|
||||
p['voting_start_time'] = v['voting_start_time']
|
||||
p['voting_end_time'] = v['voting_end_time']
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = lib.init_default_argument_parser(
|
||||
prog_desc='Convert genesis.json from v0.33.x to v0.34.0',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-amino"
|
||||
"github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
amino "github.com/tendermint/go-amino"
|
||||
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
|
||||
)
|
||||
|
||||
var cdc = amino.NewCodec()
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/secp256k1"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/go-bip39"
|
||||
bip39 "github.com/cosmos/go-bip39"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
|
|
@ -256,6 +256,10 @@ gaiacli tx sign \
|
|||
unsignedSendTx.json > signedSendTx.json
|
||||
```
|
||||
|
||||
::: tip Note
|
||||
The `--generate-only` flag prevents `gaiacli` from accessing the local keybase.
|
||||
:::
|
||||
|
||||
You can validate the transaction's signatures by typing the following:
|
||||
|
||||
```bash
|
||||
|
|
|
@ -107,6 +107,10 @@ func NewResponseResultTx(res *ctypes.ResultTx, tx Tx, timestamp string) TxRespon
|
|||
// NewResponseFormatBroadcastTxCommit returns a TxResponse given a
|
||||
// ResultBroadcastTxCommit from tendermint.
|
||||
func NewResponseFormatBroadcastTxCommit(res *ctypes.ResultBroadcastTxCommit) TxResponse {
|
||||
if res == nil {
|
||||
return TxResponse{}
|
||||
}
|
||||
|
||||
if !res.CheckTx.IsOK() {
|
||||
return newTxResponseCheckTx(res)
|
||||
}
|
||||
|
|
|
@ -25,19 +25,23 @@ const (
|
|||
// Constant as this should not change without a hard fork.
|
||||
// TODO: Link to some Tendermint docs, this is very unobvious.
|
||||
ValidatorUpdateDelay int64 = 1
|
||||
|
||||
BondStatusUnbonded = "Unbonded"
|
||||
BondStatusUnbonding = "Unbonding"
|
||||
BondStatusBonded = "Bonded"
|
||||
)
|
||||
|
||||
//BondStatusToString for pretty prints of Bond Status
|
||||
func BondStatusToString(b BondStatus) string {
|
||||
// String implements the Stringer interface for BondStatus.
|
||||
func (b BondStatus) String() string {
|
||||
switch b {
|
||||
case 0x00:
|
||||
return "Unbonded"
|
||||
return BondStatusUnbonded
|
||||
case 0x01:
|
||||
return "Unbonding"
|
||||
return BondStatusUnbonding
|
||||
case 0x02:
|
||||
return "Bonded"
|
||||
return BondStatusBonded
|
||||
default:
|
||||
panic("improper use of BondStatusToString")
|
||||
panic("invalid bond status")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -248,6 +248,10 @@ func (bldr TxBuilder) BuildTxForSim(msgs []sdk.Msg) ([]byte, error) {
|
|||
// SignStdTx appends a signature to a StdTx and returns a copy of it. If append
|
||||
// is false, it replaces the signatures already attached with the new signature.
|
||||
func (bldr TxBuilder) SignStdTx(name, passphrase string, stdTx auth.StdTx, appendSig bool) (signedStdTx auth.StdTx, err error) {
|
||||
if bldr.chainID == "" {
|
||||
return auth.StdTx{}, fmt.Errorf("chain ID required but not specified")
|
||||
}
|
||||
|
||||
stdSignature, err := MakeSignature(bldr.keybase, name, passphrase, StdSignMsg{
|
||||
ChainID: bldr.chainID,
|
||||
AccountNumber: bldr.accountNumber,
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint/client/cli"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tendermint/go-amino"
|
||||
)
|
||||
|
|
|
@ -36,6 +36,7 @@ type (
|
|||
QueryValidatorParams = querier.QueryValidatorParams
|
||||
QueryBondsParams = querier.QueryBondsParams
|
||||
QueryRedelegationParams = querier.QueryRedelegationParams
|
||||
QueryValidatorsParams = querier.QueryValidatorsParams
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -97,10 +98,11 @@ var (
|
|||
NewMsgUndelegate = types.NewMsgUndelegate
|
||||
NewMsgBeginRedelegate = types.NewMsgBeginRedelegate
|
||||
|
||||
NewQuerier = querier.NewQuerier
|
||||
NewQueryDelegatorParams = querier.NewQueryDelegatorParams
|
||||
NewQueryValidatorParams = querier.NewQueryValidatorParams
|
||||
NewQueryBondsParams = querier.NewQueryBondsParams
|
||||
NewQuerier = querier.NewQuerier
|
||||
NewQueryDelegatorParams = querier.NewQueryDelegatorParams
|
||||
NewQueryValidatorParams = querier.NewQueryValidatorParams
|
||||
NewQueryBondsParams = querier.NewQueryBondsParams
|
||||
NewQueryValidatorsParams = querier.NewQueryValidatorsParams
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package rest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -15,7 +16,6 @@ import (
|
|||
)
|
||||
|
||||
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec) {
|
||||
|
||||
// Get all delegations from a delegator
|
||||
r.HandleFunc(
|
||||
"/staking/delegators/{delegatorAddr}/delegations",
|
||||
|
@ -249,7 +249,31 @@ func delegatorValidatorHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) ht
|
|||
// HTTP request handler to query list of validators
|
||||
func validatorsHandlerFn(cliCtx context.CLIContext, cdc *codec.Codec) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
res, err := cliCtx.QueryWithData("custom/staking/validators", nil)
|
||||
_, page, limit, err := rest.ParseHTTPArgs(r)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// override default limit if it wasn't provided
|
||||
if l := r.FormValue("limit"); l == "" {
|
||||
limit = 0
|
||||
}
|
||||
|
||||
status := r.FormValue("status")
|
||||
if status == "" {
|
||||
status = sdk.BondStatusBonded
|
||||
}
|
||||
|
||||
params := staking.NewQueryValidatorsParams(page, limit, status)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", staking.QuerierRoute, staking.QueryValidators)
|
||||
res, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
|
|
@ -162,9 +162,8 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) {
|
|||
|
||||
assert.Equal(
|
||||
t, status, val.GetStatus(),
|
||||
fmt.Sprintf("expected validator at index %v to have status: %s",
|
||||
valIdx,
|
||||
sdk.BondStatusToString(status)))
|
||||
fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package querier
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
|
@ -35,7 +36,7 @@ func NewQuerier(k keep.Keeper, cdc *codec.Codec) sdk.Querier {
|
|||
return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
|
||||
switch path[0] {
|
||||
case QueryValidators:
|
||||
return queryValidators(ctx, cdc, k)
|
||||
return queryValidators(ctx, cdc, req, k)
|
||||
case QueryValidator:
|
||||
return queryValidator(ctx, cdc, req, k)
|
||||
case QueryValidatorDelegations:
|
||||
|
@ -128,14 +129,47 @@ func NewQueryRedelegationParams(delegatorAddr sdk.AccAddress, srcValidatorAddr s
|
|||
}
|
||||
}
|
||||
|
||||
func queryValidators(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []byte, err sdk.Error) {
|
||||
stakingParams := k.GetParams(ctx)
|
||||
validators := k.GetValidators(ctx, stakingParams.MaxValidators)
|
||||
func queryValidators(ctx sdk.Context, cdc *codec.Codec, req abci.RequestQuery, k keep.Keeper) ([]byte, sdk.Error) {
|
||||
var params QueryValidatorsParams
|
||||
|
||||
res, errRes := codec.MarshalJSONIndent(cdc, validators)
|
||||
err := cdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("could not marshal result to JSON", errRes.Error()))
|
||||
return nil, sdk.ErrInternal(fmt.Sprintf("failed to parse params: %s", err))
|
||||
}
|
||||
|
||||
stakingParams := k.GetParams(ctx)
|
||||
if params.Limit == 0 {
|
||||
params.Limit = int(stakingParams.MaxValidators)
|
||||
}
|
||||
|
||||
validators := k.GetAllValidators(ctx)
|
||||
filteredVals := make([]types.Validator, 0, len(validators))
|
||||
|
||||
for _, val := range validators {
|
||||
if strings.ToLower(val.GetStatus().String()) == strings.ToLower(params.Status) {
|
||||
filteredVals = append(filteredVals, val)
|
||||
}
|
||||
}
|
||||
|
||||
// get pagination bounds
|
||||
start := (params.Page - 1) * params.Limit
|
||||
end := params.Limit + start
|
||||
if end >= len(filteredVals) {
|
||||
end = len(filteredVals)
|
||||
}
|
||||
|
||||
if start >= len(filteredVals) {
|
||||
// page is out of bounds
|
||||
filteredVals = []types.Validator{}
|
||||
} else {
|
||||
filteredVals = filteredVals[start:end]
|
||||
}
|
||||
|
||||
res, err := codec.MarshalJSONIndent(cdc, filteredVals)
|
||||
if err != nil {
|
||||
return nil, sdk.ErrInternal(sdk.AppendMsgToErr("failed to JSON marshal result: %s", err.Error()))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
@ -354,3 +388,14 @@ func queryParameters(ctx sdk.Context, cdc *codec.Codec, k keep.Keeper) (res []by
|
|||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// QueryValidatorsParams defines the params for the following queries:
|
||||
// - 'custom/staking/validators'
|
||||
type QueryValidatorsParams struct {
|
||||
Page, Limit int
|
||||
Status string
|
||||
}
|
||||
|
||||
func NewQueryValidatorsParams(page, limit int, status string) QueryValidatorsParams {
|
||||
return QueryValidatorsParams{page, limit, status}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package querier
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -44,9 +45,6 @@ func TestNewQuerier(t *testing.T) {
|
|||
require.NotNil(t, err)
|
||||
require.Nil(t, bz)
|
||||
|
||||
_, err = querier(ctx, []string{"validators"}, query)
|
||||
require.Nil(t, err)
|
||||
|
||||
_, err = querier(ctx, []string{"pool"}, query)
|
||||
require.Nil(t, err)
|
||||
|
||||
|
@ -121,28 +119,44 @@ func TestQueryValidators(t *testing.T) {
|
|||
params := keeper.GetParams(ctx)
|
||||
|
||||
// Create Validators
|
||||
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)}
|
||||
var validators [2]types.Validator
|
||||
amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)}
|
||||
status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding}
|
||||
var validators [3]types.Validator
|
||||
for i, amt := range amts {
|
||||
validators[i] = types.NewValidator(sdk.ValAddress(keep.Addrs[i]), keep.PKs[i], types.Description{})
|
||||
validators[i], pool, _ = validators[i].AddTokensFromDel(pool, amt)
|
||||
validators[i], pool = validators[i].UpdateStatus(pool, status[i])
|
||||
}
|
||||
|
||||
keeper.SetPool(ctx, pool)
|
||||
keeper.SetValidator(ctx, validators[0])
|
||||
keeper.SetValidator(ctx, validators[1])
|
||||
keeper.SetValidator(ctx, validators[2])
|
||||
|
||||
// Query Validators
|
||||
queriedValidators := keeper.GetValidators(ctx, params.MaxValidators)
|
||||
|
||||
res, err := queryValidators(ctx, cdc, keeper)
|
||||
require.Nil(t, err)
|
||||
for i, s := range status {
|
||||
queryValsParams := NewQueryValidatorsParams(1, int(params.MaxValidators), s.String())
|
||||
bz, errRes := cdc.MarshalJSON(queryValsParams)
|
||||
require.Nil(t, errRes)
|
||||
|
||||
var validatorsResp []types.Validator
|
||||
errRes := cdc.UnmarshalJSON(res, &validatorsResp)
|
||||
require.Nil(t, errRes)
|
||||
req := abci.RequestQuery{
|
||||
Path: fmt.Sprintf("/custom/%s/%s", types.QuerierRoute, QueryValidators),
|
||||
Data: bz,
|
||||
}
|
||||
|
||||
require.Equal(t, len(queriedValidators), len(validatorsResp))
|
||||
require.ElementsMatch(t, queriedValidators, validatorsResp)
|
||||
res, err := queryValidators(ctx, cdc, req, keeper)
|
||||
require.Nil(t, err)
|
||||
|
||||
var validatorsResp []types.Validator
|
||||
errRes = cdc.UnmarshalJSON(res, &validatorsResp)
|
||||
require.Nil(t, errRes)
|
||||
|
||||
require.Equal(t, 1, len(validatorsResp))
|
||||
require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress)
|
||||
|
||||
}
|
||||
|
||||
// Query each validator
|
||||
queryParams := NewQueryValidatorParams(addrVal1)
|
||||
|
@ -153,7 +167,7 @@ func TestQueryValidators(t *testing.T) {
|
|||
Path: "/custom/staking/validator",
|
||||
Data: bz,
|
||||
}
|
||||
res, err = queryValidator(ctx, cdc, query, keeper)
|
||||
res, err := queryValidator(ctx, cdc, query, keeper)
|
||||
require.Nil(t, err)
|
||||
|
||||
var validator types.Validator
|
||||
|
|
|
@ -117,7 +117,7 @@ func (v Validator) String() string {
|
|||
Unbonding Completion Time: %v
|
||||
Minimum Self Delegation: %v
|
||||
Commission: %s`, v.OperatorAddress, bechConsPubKey,
|
||||
v.Jailed, sdk.BondStatusToString(v.Status), v.Tokens,
|
||||
v.Jailed, v.Status, v.Tokens,
|
||||
v.DelegatorShares, v.Description,
|
||||
v.UnbondingHeight, v.UnbondingCompletionTime, v.MinSelfDelegation, v.Commission)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue