Merge remote-tracking branch 'origin/develop' into rigel/fee-distribution
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
# Architecture Decision Records (ADR)
|
||||
|
||||
This is a location to record all high-level architecture decisions in the cosmos-sdk project.
|
||||
|
||||
You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t).
|
||||
|
||||
An ADR should provide:
|
||||
|
||||
- Context on the relevant goals and the current state
|
||||
- Proposed changes to achieve the goals
|
||||
- Summary of pros and cons
|
||||
- References
|
||||
- Changelog
|
||||
|
||||
Note the distinction between an ADR and a spec. The ADR provides the context, intuition, reasoning, and
|
||||
justification for a change in architecture, or for the architecture of something
|
||||
new. The spec is much more compressed and streamlined summary of everything as
|
||||
it stands today.
|
||||
|
||||
If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match.
|
||||
|
||||
Note the context/background should be written in the present tense.
|
||||
@@ -0,0 +1,54 @@
|
||||
# ADR 001: Global Message Counter
|
||||
|
||||
## Context
|
||||
|
||||
There is a desire for modules to have a concept of orderings between messages.
|
||||
|
||||
One such example is in staking, we currently use an "intra bond tx counter" and
|
||||
bond height.
|
||||
The purpose these two serve is to providing an ordering for validators with equal stake,
|
||||
for usage in the power-ranking of validators.
|
||||
We can't use address here, as that would create a bad incentive to grind
|
||||
addresses that optimized the sort function, which lowers the private key's
|
||||
security.
|
||||
Instead we order by whose transaction appeared first, as tracked by bondHeight
|
||||
and intra bond tx counter.
|
||||
|
||||
This logic however should not be unique to staking.
|
||||
It is very conceivable that many modules in the future will want to be able to
|
||||
know the ordering of messages / objects after they were initially created.
|
||||
|
||||
## Decision
|
||||
|
||||
Create a global message counter field of type int64.
|
||||
Note that with int64's, there is no fear of overflow under normal use,
|
||||
as it is only getting incremented by one,
|
||||
and thus has a space of 9 quintillion values to go through.
|
||||
|
||||
This counter must be persisted in state, but can just be read and written on
|
||||
begin/end block respectively.
|
||||
This field will get incremented upon every DeliverTx,
|
||||
regardless if the transaction succeeds or not.
|
||||
It must also be incremented within the check state for CheckTx.
|
||||
The global message ordering field should be set within the context
|
||||
so that modules can access it.
|
||||
|
||||
## Corollary - Intra block ordering
|
||||
In the event that there is desire to just have an intra block msg counter,
|
||||
this can easily be derived from the global message counter.
|
||||
Simply subtract current counter from first global message counter in the block.
|
||||
Thus the relevant module could easily implement this.
|
||||
|
||||
## Status
|
||||
Proposed
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
* Moves message ordering out of the set of things staking must keep track of
|
||||
* Abstracts the logic well so other modules can use it
|
||||
|
||||
### Negative
|
||||
* Another thing to implement prelaunch. (Though this should be easy to implement)
|
||||
|
||||
### Neutral
|
||||
@@ -0,0 +1,32 @@
|
||||
# ADR {ADR-NUMBER}: {TITLE}
|
||||
|
||||
## Changelog
|
||||
* {date}: {changelog}
|
||||
|
||||
## Context
|
||||
> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high level idea behind the solution.
|
||||
|
||||
## Decision
|
||||
> This section explains all of the details of the proposed solution, including implementation details.
|
||||
It should also describe affects / corollary items that may need to be changed as a part of this.
|
||||
If the proposed change will be large, please also indicate a way to do the change to maximize ease of review.
|
||||
(e.g. the optimal split of things to do between separate PR's)
|
||||
|
||||
## Status
|
||||
> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.
|
||||
|
||||
{Deprecated|Proposed|Accepted}
|
||||
|
||||
## Consequences
|
||||
> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones.
|
||||
|
||||
### Positive
|
||||
|
||||
### Negative
|
||||
|
||||
### Neutral
|
||||
|
||||
## References
|
||||
> Are there any relevant PR comments, issues that led up to this, or articles referrenced for why we made the given design choice? If so link them here!
|
||||
|
||||
* {reference link}
|
||||
+700
-413
File diff suppressed because it is too large
Load Diff
@@ -1003,7 +1003,7 @@ where the processes that caused the consensus to fail (ie. caused clients of
|
||||
the protocol to accept different values - a fork) can be identified and punished
|
||||
according to the rules of the protocol, or, possibly, the legal system. When
|
||||
the legal system is unreliable or excessively expensive to invoke, validators can be forced to make security
|
||||
deposits in order to participate, and those deposits can be revoked, or slashed,
|
||||
deposits in order to participate, and those deposits can be jailed, or slashed,
|
||||
when malicious behaviour is detected [\[10\]][10].
|
||||
|
||||
Note this is unlike Bitcoin, where forking is a regular occurence due to
|
||||
|
||||
@@ -139,8 +139,8 @@ Amino can also be used for persistent storage of interfaces.
|
||||
To use Amino, simply create a codec, and then register types:
|
||||
|
||||
```
|
||||
func NewCodec() *wire.Codec {
|
||||
cdc := wire.NewCodec()
|
||||
func NewCodec() *codec.Codec {
|
||||
cdc := codec.New()
|
||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
cdc.RegisterConcrete(MsgSend{}, "example/MsgSend", nil)
|
||||
cdc.RegisterConcrete(MsgIssue{}, "example/MsgIssue", nil)
|
||||
@@ -175,7 +175,7 @@ func (tx app2Tx) GetMsgs() []sdk.Msg {
|
||||
}
|
||||
|
||||
// Amino decode app2Tx. Capable of decoding both MsgSend and MsgIssue
|
||||
func tx2Decoder(cdc *wire.Codec) sdk.TxDecoder {
|
||||
func tx2Decoder(cdc *codec.Codec) sdk.TxDecoder {
|
||||
return func(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||
var tx app2Tx
|
||||
err := cdc.UnmarshalBinary(txBytes, &tx)
|
||||
|
||||
@@ -57,6 +57,7 @@ func NewMsgSend(from, to sdk.AccAddress, amt sdk.Coins) MsgSend {
|
||||
|
||||
// Implements Msg.
|
||||
func (msg MsgSend) Type() string { return "send" }
|
||||
func (msg MsgSend) Name() string { return "send" }
|
||||
|
||||
// Implements Msg. Ensure the addresses are good and the
|
||||
// amount is positive.
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
bapp "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -25,8 +25,8 @@ var (
|
||||
issuer = ed25519.GenPrivKey().PubKey().Address()
|
||||
)
|
||||
|
||||
func NewCodec() *wire.Codec {
|
||||
cdc := wire.NewCodec()
|
||||
func NewCodec() *codec.Codec {
|
||||
cdc := codec.New()
|
||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
cdc.RegisterConcrete(MsgSend{}, "example/MsgSend", nil)
|
||||
cdc.RegisterConcrete(MsgIssue{}, "example/MsgIssue", nil)
|
||||
@@ -77,6 +77,7 @@ type MsgIssue struct {
|
||||
|
||||
// Implements Msg.
|
||||
func (msg MsgIssue) Type() string { return "issue" }
|
||||
func (msg MsgIssue) Name() string { return "issue" }
|
||||
|
||||
// Implements Msg. Ensures addresses are valid and Coin is positive
|
||||
func (msg MsgIssue) ValidateBasic() sdk.Error {
|
||||
@@ -196,7 +197,7 @@ func (tx app2Tx) GetSignature() []byte {
|
||||
}
|
||||
|
||||
// Amino decode app2Tx. Capable of decoding both MsgSend and MsgIssue
|
||||
func tx2Decoder(cdc *wire.Codec) sdk.TxDecoder {
|
||||
func tx2Decoder(cdc *codec.Codec) sdk.TxDecoder {
|
||||
return func(txBytes []byte) (sdk.Tx, sdk.Error) {
|
||||
var tx app2Tx
|
||||
err := cdc.UnmarshalBinary(txBytes, &tx)
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
bapp "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
@@ -51,12 +51,12 @@ func NewApp3(logger log.Logger, db dbm.DB) *bapp.BaseApp {
|
||||
}
|
||||
|
||||
// Update codec from app2 to register imported modules
|
||||
func UpdatedCodec() *wire.Codec {
|
||||
cdc := wire.NewCodec()
|
||||
func UpdatedCodec() *codec.Codec {
|
||||
cdc := codec.New()
|
||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
cdc.RegisterConcrete(MsgSend{}, "example/MsgSend", nil)
|
||||
cdc.RegisterConcrete(MsgIssue{}, "example/MsgIssue", nil)
|
||||
auth.RegisterWire(cdc)
|
||||
auth.RegisterCodec(cdc)
|
||||
cryptoAmino.RegisterAmino(cdc)
|
||||
return cdc
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
bapp "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
)
|
||||
@@ -76,7 +76,7 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount, err error) {
|
||||
|
||||
// InitChainer will set initial balances for accounts as well as initial coin metadata
|
||||
// MsgIssue can no longer be used to create new coin
|
||||
func NewInitChainer(cdc *wire.Codec, accountMapper auth.AccountMapper) sdk.InitChainer {
|
||||
func NewInitChainer(cdc *codec.Codec, accountMapper auth.AccountMapper) sdk.InitChainer {
|
||||
return func(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
stateJSON := req.AppStateBytes
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
Finally, we need to define the `MakeCodec()` function and register the concrete types and interface from the various modules.
|
||||
|
||||
```go
|
||||
func MakeCodec() *wire.Codec {
|
||||
var cdc = wire.NewCodec()
|
||||
wire.RegisterCrypto(cdc) // Register crypto.
|
||||
sdk.RegisterWire(cdc) // Register Msgs
|
||||
bank.RegisterWire(cdc)
|
||||
simplestake.RegisterWire(cdc)
|
||||
simpleGov.RegisterWire(cdc)
|
||||
func MakeCodec() *codec.Codec {
|
||||
var cdc = codec.New()
|
||||
codec.RegisterCrypto(cdc) // Register crypto.
|
||||
sdk.RegisterCodec(cdc) // Register Msgs
|
||||
bank.RegisterCodec(cdc)
|
||||
simplestake.RegisterCodec(cdc)
|
||||
simpleGov.RegisterCodec(cdc)
|
||||
|
||||
// Register AppAccount
|
||||
cdc.RegisterInterface((*auth.Account)(nil), nil)
|
||||
|
||||
@@ -13,7 +13,7 @@ var SimpleGovAppInit = server.AppInit{
|
||||
}
|
||||
|
||||
// SimpleGovAppGenState sets up the app_state and appends the simpleGov app state
|
||||
func SimpleGovAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
|
||||
func SimpleGovAppGenState(cdc *codec.Codec, appGenTxs []json.RawMessage) (appState json.RawMessage, err error) {
|
||||
appState, err = server.SimpleAppGenState(cdc, appGenTxs)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
@@ -28,7 +28,7 @@ Then, let us define the structure of our application.
|
||||
// Extended ABCI application
|
||||
type SimpleGovApp struct {
|
||||
*bam.BaseApp
|
||||
cdc *wire.Codec
|
||||
cdc *codec.Codec
|
||||
|
||||
// keys to access the substores
|
||||
capKeyMainStore *sdk.KVStoreKey
|
||||
|
||||
@@ -28,7 +28,7 @@ Before getting in the bulk of the code, we will start by some introductory conte
|
||||
+ [Types](module-types.md)
|
||||
+ [Keeper](module-keeper.md)
|
||||
+ [Handler](module-handler.md)
|
||||
+ [Wire](module-wire.md)
|
||||
+ [Wire](module-codec.md)
|
||||
+ [Errors](module-errors.md)
|
||||
+ Command-Line Interface and Rest API
|
||||
* [Command-Line Interface](module-cli.md)
|
||||
|
||||
@@ -14,7 +14,7 @@ The CLI builds on top of [Cobra](https://github.com/spf13/cobra). Here is the sc
|
||||
)
|
||||
|
||||
// Main command function. One function for each command.
|
||||
func Command(codec *wire.Codec) *cobra.Command {
|
||||
func Command(codec *codec.Codec) *cobra.Command {
|
||||
// Create the command to return
|
||||
command := &cobra.Command{
|
||||
Use: "actual command",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
## Codec
|
||||
|
||||
**File: [`x/simple_governance/codec.go`](https://github.com/cosmos/cosmos-sdk/blob/fedekunze/module_tutorial/examples/simpleGov/x/simple_governance/codec.go)**
|
||||
|
||||
The `codec.go` file allows developers to register the concrete message types of their module into the codec. In our case, we have two messages to declare:
|
||||
|
||||
```go
|
||||
func RegisterCodec(cdc *codec.Codec) {
|
||||
cdc.RegisterConcrete(SubmitProposalMsg{}, "simple_governance/SubmitProposalMsg", nil)
|
||||
cdc.RegisterConcrete(VoteMsg{}, "simple_governance/VoteMsg", nil)
|
||||
}
|
||||
```
|
||||
Don't forget to call this function in `app.go` (see [Application - Bridging it all together](app-structure.md)) for more).
|
||||
@@ -7,7 +7,7 @@ cd x/
|
||||
mkdir simple_governance
|
||||
cd simple_governance
|
||||
mkdir -p client/cli client/rest
|
||||
touch client/cli/simple_governance.go client/rest/simple_governance.go errors.go handler.go handler_test.go keeper_keys.go keeper_test.go keeper.go test_common.go test_types.go types.go wire.go
|
||||
touch client/cli/simple_governance.go client/rest/simple_governance.go errors.go handler.go handler_test.go keeper_keys.go keeper_test.go keeper.go test_common.go test_types.go types.go codec.go
|
||||
```
|
||||
|
||||
Let us start by adding the files we will need. Your module's folder should look something like that:
|
||||
@@ -25,7 +25,7 @@ x
|
||||
├─── keeper_keys.go
|
||||
├─── keeper.go
|
||||
├─── types.go
|
||||
└─── wire.go
|
||||
└─── codec.go
|
||||
```
|
||||
|
||||
Let us go into the detail of each of these files.
|
||||
@@ -47,7 +47,7 @@ With all that in mind, we can define the structure of our `Keeper`:
|
||||
```go
|
||||
type Keeper struct {
|
||||
SimpleGov sdk.StoreKey // Key to our module's store
|
||||
cdc *wire.Codec // Codec to encore/decode structs
|
||||
cdc *codec.Codec // Codec to encore/decode structs
|
||||
ck bank.Keeper // Needed to handle deposits. This module onlyl requires read/writes to Atom balance
|
||||
sm stake.Keeper // Needed to compute voting power. This module only needs read access to the staking store.
|
||||
codespace sdk.CodespaceType // Reserves space for error codes
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
## Wire
|
||||
|
||||
**File: [`x/simple_governance/wire.go`](https://github.com/cosmos/cosmos-sdk/blob/fedekunze/module_tutorial/examples/simpleGov/x/simple_governance/wire.go)**
|
||||
|
||||
The `wire.go` file allows developers to register the concrete message types of their module into the codec. In our case, we have two messages to declare:
|
||||
|
||||
```go
|
||||
func RegisterWire(cdc *wire.Codec) {
|
||||
cdc.RegisterConcrete(SubmitProposalMsg{}, "simple_governance/SubmitProposalMsg", nil)
|
||||
cdc.RegisterConcrete(VoteMsg{}, "simple_governance/VoteMsg", nil)
|
||||
}
|
||||
```
|
||||
Don't forget to call this function in `app.go` (see [Application - Bridging it all together](app-structure.md)) for more).
|
||||
@@ -8,7 +8,7 @@ The specification has focused on semantics and functionality of the IBC protocol
|
||||
|
||||
In defining a standard binary encoding for all the "universal" components, we wish to make use of a standardized library, with efficient serialization and support in multiple languages. We considered two main formats: Ethereum's RLP[[6](./references.md#6)] and Google's Protobuf[[7](./references.md#7)]. We decided for protobuf, as it is more widely supported, is more expressive for different data types, and supports code generation for very efficient (de)serialization codecs. It does have a learning curve and more setup to generate the code from the type specifications, but the ibc data types should not change often and this code generation setup only needs to happen once per language (and can be exposed in a common repo), so this is not a strong counter-argument. Efficiency, expressiveness, and wider support rule in its favor. It is also widely used in gRPC and in many microservice architectures.
|
||||
|
||||
The tendermint-specific data structures are encoded with go-wire[[8](./references.md#8)], the native binary encoding used inside of tendermint. Most blockchains define their own formats, and until some universal format for headers and signatures among blockchains emerge, it seems very premature to enforce any encoding here. These are defined as arbitrary byte slices in the protocol, to be parsed in an consensus engine-dependent manner.
|
||||
The tendermint-specific data structures are encoded with go-amino[[8](./references.md#8)], the native binary encoding used inside of tendermint. Most blockchains define their own formats, and until some universal format for headers and signatures among blockchains emerge, it seems very premature to enforce any encoding here. These are defined as arbitrary byte slices in the protocol, to be parsed in an consensus engine-dependent manner.
|
||||
|
||||
For the following appendixes, the data structure specifications will be in proto3[[9](./references.md#9)] format.
|
||||
|
||||
@@ -61,7 +61,7 @@ The IBC protocol does not handle these kinds of errors. They must be handled ind
|
||||
|
||||
**TODO: clean this all up**
|
||||
|
||||
This is a mess now, we need to figure out what formats we use, define go-wire, etc. or just point to the source???? Will do more later, need help here from the tendermint core team.
|
||||
This is a mess now, we need to figure out what formats we use, define go-amino, etc. or just point to the source???? Will do more later, need help here from the tendermint core team.
|
||||
|
||||
In order to prove a merkle root, we must fully define the headers, signatures, and validator information returned from the Tendermint consensus engine, as well as the rules by which to verify a header. We also define here the messages used for creating and removing connections to other blockchains as well as how to handle forks.
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ Every transaction on the same chain already has a well-defined causality relatio
|
||||
|
||||
For example, an application may wish to allow a single tokenized asset to be transferred between and held on multiple blockchains while preserving fungibility and conservation of supply. The application can mint asset vouchers on chain `B` when a particular IBC packet is committed to chain `B`, and require outgoing sends of that packet on chain `A` to escrow an equal amount of the asset on chain `A` until the vouchers are later redeemed back to chain `A` with an IBC packet in the reverse direction. This ordering guarantee along with correct application logic can ensure that total supply is preserved across both chains and that any vouchers minted on chain `B` can later be redeemed back to chain `A`.
|
||||
|
||||
This section provides definitions for packets and channels, a high-level specification of the queue interface, and a list of the necessary proofs. To implement wire-compatible IBC, chain `A` and chain `B` must also use a common encoding format. An example binary encoding format can be found in [Appendix C](appendices.md#appendix-c-merkle-proof-formats).
|
||||
This section provides definitions for packets and channels, a high-level specification of the queue interface, and a list of the necessary proofs. To implement amino-compatible IBC, chain `A` and chain `B` must also use a common encoding format. An example binary encoding format can be found in [Appendix C](appendices.md#appendix-c-merkle-proof-formats).
|
||||
|
||||
### 3.2 Definitions
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ We have demonstrated a secure, performant, and flexible protocol for cross-block
|
||||
|
||||
This document defines solely a message queue protocol - not the application-level semantics which must sit on top of it to enable asset transfer between two chains. We will shortly release a separate paper on Cosmos IBC that defines the application logic used for direct value transfer as well as routing over the Cosmos hub. That paper builds upon the IBC protocol defined here and provides a first example of how to reason about application logic and global invariants in the context of IBC.
|
||||
|
||||
There is a reference implementation of the Cosmos IBC protocol as part of the Cosmos SDK, written in Golang and released under the Apache license. To facilitate implementations in other langauages which are wire-compatible with the Cosmos implementation, the following appendices define exact message and binary encoding formats.
|
||||
There is a reference implementation of the Cosmos IBC protocol as part of the Cosmos SDK, written in Golang and released under the Apache license. To facilitate implementations in other langauages which are amino-compatible with the Cosmos implementation, the following appendices define exact message and binary encoding formats.
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
[https://developers.google.com/protocol-buffers/](https://developers.google.com/protocol-buffers/)
|
||||
|
||||
##### 8:
|
||||
[https://github.com/tendermint/go-wire](https://github.com/tendermint/go-wire)
|
||||
[https://github.com/tendermint/go-amino](https://github.com/tendermint/go-amino)
|
||||
|
||||
##### 9:
|
||||
[https://developers.google.com/protocol-buffers/docs/proto3](https://developers.google.com/protocol-buffers/docs/proto3)
|
||||
|
||||
@@ -100,7 +100,7 @@ type TxDelegate struct {
|
||||
|
||||
delegate(tx TxDelegate):
|
||||
pool = getPool()
|
||||
if validator.Status == Revoked return
|
||||
if validator.Status == Jailed return
|
||||
|
||||
delegation = getDelegatorBond(DelegatorAddr, ValidatorAddr)
|
||||
if delegation == nil then delegation = NewDelegation(DelegatorAddr, ValidatorAddr)
|
||||
@@ -141,7 +141,7 @@ startUnbonding(tx TxStartUnbonding):
|
||||
revokeCandidacy = false
|
||||
if bond.Shares.IsZero() {
|
||||
|
||||
if bond.DelegatorAddr == validator.Operator && validator.Revoked == false
|
||||
if bond.DelegatorAddr == validator.Operator && validator.Jailed == false
|
||||
revokeCandidacy = true
|
||||
|
||||
removeDelegation( bond)
|
||||
@@ -157,7 +157,7 @@ startUnbonding(tx TxStartUnbonding):
|
||||
setUnbondingDelegation(unbondingDelegation)
|
||||
|
||||
if revokeCandidacy
|
||||
validator.Revoked = true
|
||||
validator.Jailed = true
|
||||
|
||||
validator = updateValidator(validator)
|
||||
|
||||
@@ -279,9 +279,9 @@ updateBondedValidators(newValidator Validator) (updatedVal Validator)
|
||||
else
|
||||
validator = getValidator(operatorAddr)
|
||||
|
||||
// if not previously a validator (and unrevoked),
|
||||
// if not previously a validator (and unjailed),
|
||||
// kick the cliff validator / bond this new validator
|
||||
if validator.Status() != Bonded && !validator.Revoked {
|
||||
if validator.Status() != Bonded && !validator.Jailed {
|
||||
kickCliffValidator = true
|
||||
|
||||
validator = bondValidator(ctx, store, validator)
|
||||
|
||||
Reference in New Issue
Block a user