Merge remote-tracking branch 'origin/develop' into rigel/clearer-staking-logic
This commit is contained in:
commit
c21e6a0642
|
@ -18,7 +18,7 @@ BREAKING CHANGES
|
|||
* The keys sub-module is now in the SDK
|
||||
* Various other fixes
|
||||
* [auth] Signers of a transaction now only sign over their own account and sequence number
|
||||
* [auth] Removed MsgChangePubKey
|
||||
* [auth] Removed MsgChangePubKey
|
||||
* [auth] Removed SetPubKey from account mapper
|
||||
* [auth] AltBytes renamed to Memo, now a string, max 100 characters, costs a bit of gas
|
||||
* [types] `GetMsg()` -> `GetMsgs()` as txs wrap many messages
|
||||
|
@ -104,6 +104,7 @@ IMPROVEMENTS
|
|||
* [keys] improve error message when deleting non-existent key
|
||||
* [gaiacli] improve error messages on `send` and `account` commands
|
||||
* added contributing guidelines
|
||||
* [docs] Added commands for governance CLI on testnet README
|
||||
|
||||
BUG FIXES
|
||||
* [x/slashing] \#1510 Unrevoked validators cannot un-revoke themselves
|
||||
|
@ -129,8 +130,11 @@ BUG FIXES
|
|||
* \#1461 - CLI tests now no longer reset your local environment data
|
||||
* \#1505 - `gaiacli stake validator` no longer panics if validator doesn't exist
|
||||
* \#1565 - fix cliff validator persisting when validator set shrinks from max
|
||||
* \#1287 - prevent zero power validators at genesis
|
||||
* [x/stake] fix bug when unbonding/redelegating using `--shares-percent`
|
||||
* \#1010 - two validators can't bond with the same pubkey anymore
|
||||
|
||||
|
||||
## 0.19.0
|
||||
|
||||
*June 13, 2018*
|
||||
|
|
|
@ -554,7 +554,6 @@ func getState(app *BaseApp, mode runTxMode) *state {
|
|||
|
||||
// txBytes may be nil in some cases, eg. in tests.
|
||||
// Also, in the future we may support "internal" transactions.
|
||||
// nolint: gocyclo
|
||||
func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk.Result) {
|
||||
//NOTE: GasWanted should be returned by the AnteHandler.
|
||||
// GasUsed is determined by the GasMeter.
|
||||
|
|
|
@ -164,7 +164,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
}
|
||||
|
||||
// load the initial stake information
|
||||
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||
if err != nil {
|
||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
|
||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState())
|
||||
|
||||
|
|
|
@ -228,8 +228,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
var genesisState gaia.GenesisState
|
||||
err := app.cdc.UnmarshalJSON(stateJSON, &genesisState)
|
||||
if err != nil {
|
||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
|
||||
// return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
// load the accounts
|
||||
|
@ -239,7 +238,10 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
|||
}
|
||||
|
||||
// load the initial stake information
|
||||
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||
return abci.ResponseInitChain{}
|
||||
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
|
||||
if err != nil {
|
||||
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
|
|
|
@ -310,11 +310,11 @@ WantedBy=multi-user.target
|
|||
|
||||
## Delegating to a Validator
|
||||
|
||||
On the upcoming mainnet, you can delegate `atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf).
|
||||
On the upcoming mainnet, you can delegate `Atom` to a validator. These [delegators](https://cosmos.network/resources/delegators) can receive part of the validator's fee revenue. Read more about the [Cosmos Token Model](https://github.com/cosmos/cosmos/raw/master/Cosmos_Token_Model.pdf).
|
||||
|
||||
### Bond Tokens
|
||||
|
||||
On the testnet, we delegate `steak` instead of `atom`. Here's how you can bond tokens to a testnet validator:
|
||||
On the testnet, we delegate `steak` instead of `Atom`. Here's how you can bond tokens to a testnet validator:
|
||||
|
||||
```bash
|
||||
gaiacli stake delegate \
|
||||
|
@ -353,6 +353,90 @@ gaiacli stake delegation \
|
|||
--chain-id=gaia-6002
|
||||
```
|
||||
|
||||
## Governance
|
||||
|
||||
Governance is the process from which users in the Cosmos Hub can come to consensus on software upgrades, parameters of the mainnet or on custom text proposals. This is done through voting on proposals, which will be submitted by `Atom` holders on the mainnet.
|
||||
|
||||
Some considerations about the voting process:
|
||||
|
||||
- Voting is done by bonded `Atom` holders on a 1 bonded `Atom` 1 vote basis
|
||||
- Delegators inherit the vote of their validator if they don't vote
|
||||
- **Validators MUST vote on every proposal**. If a validator does not vote on a proposal, they will be **partially slashed**
|
||||
- Votes are tallied at the end of the voting period (2 weeks on mainnet). Each address can vote multiple times to update its `Option` value (paying the transaction fee each time), only the last casted vote will count as valid
|
||||
- Voters can choose between options `Yes`, `No`, `NoWithVeto` and `Abstain`
|
||||
At the end of the voting period, a proposal is accepted if `(YesVotes/(YesVotes+NoVotes+NoWithVetoVotes))>1/2` and `(NoWithVetoVotes/(YesVotes+NoVotes+NoWithVetoVotes))<1/3`. It is rejected otherwise
|
||||
|
||||
For more information about the governance process and how it works, please check out the Governance module [specification](https://github.com/cosmos/cosmos-sdk/tree/develop/docs/spec/governance).
|
||||
|
||||
### Create a Governance proposal
|
||||
|
||||
In order to create a governance proposal, you must submit an initial deposit along with the proposal details:
|
||||
|
||||
- `title`: Title of the proposal
|
||||
- `description`: Description of the proposal
|
||||
- `type`: Type of proposal. Must be of value _Text_ (types _SoftwareUpgrade_ and _ParameterChange_ not supported yet).
|
||||
|
||||
```bash
|
||||
gaiacli gov submit-proposal \
|
||||
--title=<title> \
|
||||
--description=<description> \
|
||||
--type=<Text/ParameterChange/SoftwareUpgrade> \
|
||||
--proposer=<account_cosmosaccaddr> \
|
||||
--deposit=<40steak> \
|
||||
--from=<name> \
|
||||
--chain-id=gaia-7000
|
||||
```
|
||||
|
||||
|
||||
### Increase deposit
|
||||
|
||||
In order for a proposal to be broadcasted to the network, the amount deposited must be above a `minDeposit` value (default: `10 steak`). If the proposal you previously created didn't meet this requirement, you can still increase the total amount deposited to activate it. Once the minimum deposit is reached, the proposal enters voting period:
|
||||
|
||||
```bash
|
||||
gaiacli gov deposit \
|
||||
--proposalID=<proposal_id> \
|
||||
--depositer=<account_cosmosaccaddr> \
|
||||
--deposit=<200steak> \
|
||||
--from=<name> \
|
||||
--chain-id=gaia-7000
|
||||
```
|
||||
|
||||
> _NOTE_: Proposals that don't meet this requirement will be deleted after `MaxDepositPeriod` is reached.
|
||||
|
||||
#### Query proposal
|
||||
|
||||
Once created, you can now query information of the proposal:
|
||||
|
||||
```bash
|
||||
gaiacli gov query-proposal \
|
||||
--proposalID=<proposal_id> \
|
||||
--chain-id=gaia-7000
|
||||
```
|
||||
|
||||
### Vote on a proposal
|
||||
|
||||
After a proposal's deposit reaches the `MinDeposit` value, the voting period opens. Bonded `Atom` holders can then cast vote on it:
|
||||
|
||||
```bash
|
||||
gaiacli gov vote \
|
||||
--proposalID=<proposal_id> \
|
||||
--voter=<account_cosmosaccaddr> \
|
||||
--option=<Yes/No/NoWithVeto/Abstain> \
|
||||
--from=<name> \
|
||||
--chain-id=gaia-7000
|
||||
```
|
||||
|
||||
#### Query vote
|
||||
|
||||
Check the vote with the option you just submitted:
|
||||
|
||||
```bash
|
||||
gaiacli gov query-vote \
|
||||
--proposalID=<proposal_id> \
|
||||
--voter=<account_cosmosaccaddr> \
|
||||
--chain-id=gaia-7000
|
||||
```
|
||||
|
||||
## Other Operations
|
||||
|
||||
### Send Tokens
|
||||
|
@ -365,7 +449,7 @@ gaiacli send \
|
|||
--to=<destination_cosmosaccaddr>
|
||||
```
|
||||
|
||||
> _*Note:*_ The `--amount` flag accepts the format `--amount=<value|coin_name>`.
|
||||
> _*NOTE:*_ The `--amount` flag accepts the format `--amount=<value|coin_name>`.
|
||||
|
||||
Now, view the updated balances of the origin and destination accounts:
|
||||
|
||||
|
|
|
@ -61,7 +61,10 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk
|
|||
stakeGenesis := stake.DefaultGenesisState()
|
||||
stakeGenesis.Pool.LooseTokens = 100000
|
||||
|
||||
stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
|
||||
err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
InitGenesis(ctx, keeper, DefaultGenesisState())
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ func (tx testMsg) Type() string { return msgType }
|
|||
func (tx testMsg) GetMsg() sdk.Msg { return tx }
|
||||
func (tx testMsg) GetMemo() string { return "" }
|
||||
func (tx testMsg) GetSignBytes() []byte { return nil }
|
||||
func (tx testMsg) GetSigners() []sdk.AccAddress { return tx.signers }
|
||||
func (tx testMsg) GetSigners() []sdk.AccAddress { return tx.signers }
|
||||
func (tx testMsg) GetSignatures() []auth.StdSignature { return nil }
|
||||
func (tx testMsg) ValidateBasic() sdk.Error {
|
||||
if tx.positiveNum >= 0 {
|
||||
|
|
|
@ -55,7 +55,10 @@ func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer {
|
|||
mapp.InitChainer(ctx, req)
|
||||
stakeGenesis := stake.DefaultGenesisState()
|
||||
stakeGenesis.Pool.LooseTokens = 100000
|
||||
stake.InitGenesis(ctx, keeper, stakeGenesis)
|
||||
err := stake.InitGenesis(ctx, keeper, stakeGenesis)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,9 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, Keep
|
|||
sk := stake.NewKeeper(cdc, keyStake, ck, stake.DefaultCodespace)
|
||||
genesis := stake.DefaultGenesisState()
|
||||
genesis.Pool.LooseTokens = initCoins.MulRaw(int64(len(addrs))).Int64()
|
||||
stake.InitGenesis(ctx, sk, genesis)
|
||||
err = stake.InitGenesis(ctx, sk, genesis)
|
||||
require.Nil(t, err)
|
||||
|
||||
for _, addr := range addrs {
|
||||
_, _, err = ck.AddCoins(ctx, addr, sdk.Coins{
|
||||
{sk.GetParams(ctx).BondDenom, initCoins},
|
||||
|
|
|
@ -65,7 +65,10 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer {
|
|||
stakeGenesis := DefaultGenesisState()
|
||||
stakeGenesis.Pool.LooseTokens = 100000
|
||||
|
||||
InitGenesis(ctx, keeper, stakeGenesis)
|
||||
err := InitGenesis(ctx, keeper, stakeGenesis)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return abci.ResponseInitChain{}
|
||||
}
|
||||
|
@ -83,7 +86,6 @@ func checkValidator(t *testing.T, mapp *mock.App, keeper Keeper,
|
|||
return validator
|
||||
}
|
||||
|
||||
|
||||
func checkDelegation(
|
||||
t *testing.T, mapp *mock.App, keeper Keeper, delegatorAddr,
|
||||
validatorAddr sdk.AccAddress, expFound bool, expShares sdk.Rat,
|
||||
|
|
|
@ -240,15 +240,10 @@ func getShares(storeName string, cdc *wire.Codec, sharesAmountStr, sharesPercent
|
|||
key := stake.GetDelegationKey(delegatorAddr, validatorAddr)
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
resQuery, err := ctx.QueryStore(key, storeName)
|
||||
if err != nil {
|
||||
return sharesAmount, err
|
||||
}
|
||||
var delegation stake.Delegation
|
||||
err = cdc.UnmarshalBinary(resQuery, &delegation)
|
||||
if err != nil {
|
||||
return sharesAmount, errors.Errorf("cannot find delegation to determine percent Error: %v", err)
|
||||
}
|
||||
|
||||
delegation := types.MustUnmarshalDelegation(cdc, key, resQuery)
|
||||
sharesAmount = sharesPercent.Mul(delegation.Shares)
|
||||
}
|
||||
return
|
||||
|
|
|
@ -3,6 +3,7 @@ package stake
|
|||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
"github.com/pkg/errors"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
|
@ -11,7 +12,7 @@ import (
|
|||
// validator in the keeper along with manually setting the indexes. In
|
||||
// addition, it also sets any delegations found in data. Finally, it updates
|
||||
// the bonded validators.
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
||||
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error {
|
||||
keeper.SetPool(ctx, data.Pool)
|
||||
keeper.SetNewParams(ctx, data.Params)
|
||||
keeper.InitIntraTxCounter(ctx)
|
||||
|
@ -19,6 +20,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
|||
for _, validator := range data.Validators {
|
||||
keeper.SetValidator(ctx, validator)
|
||||
|
||||
if validator.PoolShares.Amount.IsZero() {
|
||||
return errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator)
|
||||
}
|
||||
if validator.DelegatorShares.IsZero() {
|
||||
return errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator)
|
||||
}
|
||||
|
||||
// Manually set indexes for the first time
|
||||
keeper.SetValidatorByPubKeyIndex(ctx, validator)
|
||||
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
|
||||
|
@ -33,6 +41,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
|
|||
}
|
||||
|
||||
keeper.UpdateBondedValidatorsFull(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteGenesis returns a GenesisState for a given context and keeper. The
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package stake
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
keep "github.com/cosmos/cosmos-sdk/x/stake/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake/types"
|
||||
)
|
||||
|
||||
func TestInitGenesis(t *testing.T) {
|
||||
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
|
||||
|
||||
pool := keeper.GetPool(ctx)
|
||||
pool.UnbondedTokens = 1
|
||||
pool.UnbondedShares = sdk.OneRat()
|
||||
|
||||
params := keeper.GetParams(ctx)
|
||||
var delegations []Delegation
|
||||
|
||||
validators := []Validator{
|
||||
NewValidator(keep.Addrs[0], keep.PKs[0], Description{Moniker: "hoop"}),
|
||||
}
|
||||
|
||||
genesisState := types.NewGenesisState(pool, params, validators, delegations)
|
||||
err := InitGenesis(ctx, keeper, genesisState)
|
||||
require.Error(t, err)
|
||||
|
||||
validators[0].PoolShares.Amount = sdk.OneRat()
|
||||
validators[0].DelegatorShares = sdk.OneRat()
|
||||
|
||||
genesisState = types.NewGenesisState(pool, params, validators, delegations)
|
||||
err = InitGenesis(ctx, keeper, genesisState)
|
||||
require.NoError(t, err)
|
||||
}
|
|
@ -156,7 +156,7 @@ func GetUBDsByValIndexKey(validatorAddr sdk.AccAddress) []byte {
|
|||
|
||||
// get the key for a redelegation
|
||||
// VALUE: stake/types.RedelegationKey
|
||||
func GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) []byte {
|
||||
func GetREDKey(delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) []byte {
|
||||
return append(append(
|
||||
GetREDsKey(delegatorAddr.Bytes()),
|
||||
validatorSrcAddr.Bytes()...),
|
||||
|
|
Loading…
Reference in New Issue