Skip to content

Commit

Permalink
Merge PR cosmos#7251: Cleanup of evidence types
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-zaremba authored Sep 8, 2020
1 parent 325be6f commit 9856327
Show file tree
Hide file tree
Showing 19 changed files with 47 additions and 93 deletions.
11 changes: 6 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ older clients.

### API Breaking Changes

* (x/evidence) [\#7251](https://github.com/cosmos/cosmos-sdk/pull/7251) New evidence types and light client evidence handling. The module function names changed.
* (modules) [\#6564](https://github.com/cosmos/cosmos-sdk/pull/6564) Constant `DefaultParamspace` is removed from all modules, use ModuleName instead.
* (client) [\#6525](https://github.com/cosmos/cosmos-sdk/pull/6525) Removed support for `indent` in JSON responses. Clients should consider piping to an external tool such as `jq`.
* (x/staking) [\#6451](https://github.com/cosmos/cosmos-sdk/pull/6451) `DefaultParamspace` and `ParamKeyTable` in staking module are moved from keeper to types to enforce consistency.
Expand Down Expand Up @@ -129,11 +130,11 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
* (modules) [\#6311](https://github.com/cosmos/cosmos-sdk/issues/6311) Remove `alias.go` usage
* (x/auth) [\#6443](https://github.com/cosmos/cosmos-sdk/issues/6443) Move `FeeTx` and `TxWithMemo` interfaces from `x/auth/ante` to `types`.
* (modules) [\#6447](https://github.com/cosmos/cosmos-sdk/issues/6447) Rename `blacklistedAddrs` to `blockedAddrs`.

Migration guide:

```go
cliCtx := context.CLIContext{}
cliCtx := context.CLIContext{}
```

Now becomes:
Expand All @@ -144,7 +145,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
* (client/rpc) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `RegisterRoutes` of rpc is moved from package client to client/rpc and client/rpc.RegisterRPCRoutes is removed.
* (client/lcd) [\#6290](https://github.com/cosmos/cosmos-sdk/pull/6290) `CliCtx` of struct `RestServer` in package client/lcd has been renamed to `ClientCtx`.
* (types) [\#6327](https://github.com/cosmos/cosmos-sdk/pull/6327) `sdk.Msg` now inherits `proto.Message`, as a result all `sdk.Msg` types now use pointer semantics.
* (codec) [\#6330](https://github.com/cosmos/cosmos-sdk/pull/6330) `codec.RegisterCrypto` has been moved to the `crypto/codec` package and the global `codec.Cdc` Amino instance has been deprecated and moved to the `codec/legacy_global` package.
* (codec) [\#6330](https://github.com/cosmos/cosmos-sdk/pull/6330) `codec.RegisterCrypto` has been moved to the `crypto/codec` package and the global `codec.Cdc` Amino instance has been deprecated and moved to the `codec/legacy_global` package.
* (x/ibc) [\#6374](https://github.com/cosmos/cosmos-sdk/pull/6374) `VerifyMembership` and `VerifyNonMembership` now take a `specs []string` argument to specify the proof format used for verification. Most SDK chains can simply use `commitmenttypes.GetSDKSpecs()` for this argument.
* (crypto/types/multisig) [\#6373](https://github.com/cosmos/cosmos-sdk/pull/6373) `multisig.Multisignature` has been renamed to `AminoMultisignature`
* (x/auth) [\#6428](https://github.com/cosmos/cosmos-sdk/issues/6428):
Expand Down Expand Up @@ -193,7 +194,7 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa
* (types) [\#7038](https://github.com/cosmos/cosmos-sdk/issues/7038) Fix infinite looping of `ApproxRoot` by including a hard-coded maximum iterations limit of 100.
* (simulation) [\#7129](https://github.com/cosmos/cosmos-sdk/issues/7129) Fix support for custom `Account` and key types on auth's simulation.
* (types) [\#7084](https://github.com/cosmos/cosmos-sdk/pull/7084) Fix panic when calling `BigInt()` on an uninitialized `Int`.
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
* (x/bank) [\#6536](https://github.com/cosmos/cosmos-sdk/pull/6536) Fix bug in `WriteGeneratedTxResponse` function used by multiple
REST endpoints. Now it writes a Tx in StdTx format.
* (x/staking) [\#6529](https://github.com/cosmos/cosmos-sdk/pull/6529) Export validator addresses (previously was empty).
* (export) [\#6510](https://github.com/cosmos/cosmos-sdk/pull/6510/) Field TimeIotaMs now is included in genesis file while exporting.
Expand Down Expand Up @@ -324,7 +325,7 @@ pagination.
* (baseapp) [\#6053](https://github.com/cosmos/cosmos-sdk/pull/6053) Customizable panic recovery handling added for `app.runTx()` method (as proposed in the [ADR 22](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-022-custom-panic-handling.md)). Adds ability for developers to register custom panic handlers extending standard ones.
* (store) [\#6481](https://github.com/cosmos/cosmos-sdk/pull/6481) Move `SimpleProofsFromMap` from Tendermint into the SDK.
* (store) [\#6719](https://github.com/cosmos/cosmos-sdk/6754) Add validity checks to stores for nil and empty keys.
* (types) \#6897 Add KV type from tendermint to `types` directory.
* (types) \#6897 Add KV type from tendermint to `types` directory.

## [v0.39.0] - 2020-07-20

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ proto-check-breaking-docker:
@$(DOCKER_BUF) check breaking --against-input $(HTTPS_GIT)#branch=master
.PHONY: proto-check-breaking-ci

TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/v0.34.0-rc3/proto/tendermint
TM_URL = https://raw.githubusercontent.com/tendermint/tendermint/3359e0bf2f8414d9687f9eecda67b899d64a9cd1/proto/tendermint
GOGO_PROTO_URL = https://raw.githubusercontent.com/regen-network/protobuf/cosmos
COSMOS_PROTO_URL = https://raw.githubusercontent.com/regen-network/cosmos-proto/master
CONFIO_URL = https://raw.githubusercontent.com/confio/ics23/v0.6.2
Expand Down
4 changes: 0 additions & 4 deletions baseapp/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ func ValidateEvidenceParams(i interface{}) error {
return fmt.Errorf("evidence maximum number of evidence must be positive: %v", v.MaxAgeDuration)
}

if v.ProofTrialPeriod <= 0 {
return fmt.Errorf("proof of trial period must be greater than 0: %v", v.MaxAgeDuration)
}

return nil
}

Expand Down
5 changes: 2 additions & 3 deletions baseapp/params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ func TestValidateEvidenceParams(t *testing.T) {
{nil, true},
{&tmproto.EvidenceParams{}, true},
{tmproto.EvidenceParams{}, true},
{tmproto.EvidenceParams{MaxAgeNumBlocks: -1, MaxAgeDuration: 18004000, MaxNum: 50, ProofTrialPeriod: 10_000}, true},
{tmproto.EvidenceParams{MaxAgeNumBlocks: 360000, MaxAgeDuration: 18004000, MaxNum: 50, ProofTrialPeriod: -1}, true},
{tmproto.EvidenceParams{MaxAgeNumBlocks: 360000, MaxAgeDuration: 18004000, MaxNum: 50, ProofTrialPeriod: 50_0000}, false},
{tmproto.EvidenceParams{MaxAgeNumBlocks: -1, MaxAgeDuration: 18004000, MaxNum: 50}, true},
{tmproto.EvidenceParams{MaxAgeNumBlocks: 360000, MaxAgeDuration: 18004000, MaxNum: 50}, false},
}

for _, tc := range testCases {
Expand Down
4 changes: 0 additions & 4 deletions codec/amino.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ func NewLegacyAmino() *LegacyAmino {
func RegisterEvidences(cdc *LegacyAmino) {
cdc.Amino.RegisterInterface((*tmtypes.Evidence)(nil), nil)
cdc.Amino.RegisterConcrete(&tmtypes.DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence", nil)
cdc.Amino.RegisterConcrete(&tmtypes.ConflictingHeadersEvidence{}, "tendermint/ConflictingHeadersEvidence", nil)
cdc.Amino.RegisterConcrete(&tmtypes.LunaticValidatorEvidence{}, "tendermint/LunaticValidatorEvidence", nil)
cdc.Amino.RegisterConcrete(&tmtypes.PotentialAmnesiaEvidence{}, "tendermint/PotentialAmnesiaEvidence", nil)
cdc.Amino.RegisterConcrete(&tmtypes.AmnesiaEvidence{}, "tendermint/AmnesiaEvidence", nil)
}

// MarshalJSONIndent provides a utility for indented JSON encoding of an object
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ require (
github.com/tendermint/btcd v0.1.1
github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15
github.com/tendermint/go-amino v0.15.1
github.com/tendermint/tendermint v0.34.0-rc3
github.com/tendermint/tendermint v0.34.0-rc3.0.20200907055413-3359e0bf2f84
github.com/tendermint/tm-db v0.6.2
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ github.com/tendermint/go-amino v0.15.1 h1:D2uk35eT4iTsvJd9jWIetzthE5C0/k2QmMFkCN
github.com/tendermint/go-amino v0.15.1/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME=
github.com/tendermint/tendermint v0.34.0-rc3 h1:d7Fsd5rdbxq4GmJ0kRfx7l7LesQM7e70f0ytWLTQ/Go=
github.com/tendermint/tendermint v0.34.0-rc3/go.mod h1:BoHcEpjfpBHc1Be7RQz3AHaXFNObcDG7SNHCev6Or4g=
github.com/tendermint/tendermint v0.34.0-rc3.0.20200907055413-3359e0bf2f84 h1:BI/EhLLh6SAlOtMaHePo8BNFLsNRiFNCtJ8cMBX+OE8=
github.com/tendermint/tendermint v0.34.0-rc3.0.20200907055413-3359e0bf2f84/go.mod h1:ZgOz3PoriH5yHRJmUmhDTVX8ps4+hzFvhmDq6MDUHxU=
github.com/tendermint/tm-db v0.6.1 h1:w3X87itMPXopcRPlFiqspEKhw4FXihPk2rnFFkP0zGk=
github.com/tendermint/tm-db v0.6.1/go.mod h1:m3x9kRP4UFd7JODJL0yBAZqE7wTw+S37uAE90cTx7OA=
github.com/tendermint/tm-db v0.6.2 h1:DOn8jwCdjJblrCFJbtonEIPD1IuJWpbRUUdR8GWE4RM=
Expand Down
7 changes: 3 additions & 4 deletions server/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,9 @@ func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Com
TimeIotaMs: doc.ConsensusParams.Block.TimeIotaMs,
},
Evidence: tmproto.EvidenceParams{
MaxAgeNumBlocks: exported.ConsensusParams.Evidence.MaxAgeNumBlocks,
MaxAgeDuration: exported.ConsensusParams.Evidence.MaxAgeDuration,
MaxNum: exported.ConsensusParams.Evidence.MaxNum,
ProofTrialPeriod: exported.ConsensusParams.Evidence.ProofTrialPeriod,
MaxAgeNumBlocks: exported.ConsensusParams.Evidence.MaxAgeNumBlocks,
MaxAgeDuration: exported.ConsensusParams.Evidence.MaxAgeDuration,
MaxNum: exported.ConsensusParams.Evidence.MaxNum,
},
Validator: tmproto.ValidatorParams{
PubKeyTypes: exported.ConsensusParams.Validator.PubKeyTypes,
Expand Down
2 changes: 1 addition & 1 deletion server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func interceptConfigs(ctx *Context, rootViper *viper.Viper) (*tmcfg.Config, erro
return nil, fmt.Errorf("error in config file: %v", err)
}

conf.ProfListenAddress = "localhost:6060"
conf.RPC.PprofListenAddress = "localhost:6060"
conf.P2P.RecvRate = 5120000
conf.P2P.SendRate = 5120000
conf.Consensus.TimeoutCommit = 5 * time.Second
Expand Down
8 changes: 7 additions & 1 deletion third_party/proto/tendermint/abci/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,14 @@ message VoteInfo {
bool signed_last_block = 2;
}

enum EvidenceType {
UNKNOWN = 0;
DUPLICATE_VOTE = 1;
LIGHT_CLIENT_ATTACK = 2;
}

message Evidence {
string type = 1;
EvidenceType type = 1;
// The offending validator
Validator validator = 2 [(gogoproto.nullable) = false];
// The height when the offense occurred
Expand Down
8 changes: 0 additions & 8 deletions third_party/proto/tendermint/crypto/keys.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,3 @@ message PublicKey {
bytes ed25519 = 1;
}
}

// PrivateKey defines the keys available for use with Tendermint Validators
// WARNING PrivateKey is used for internal purposes only
message PrivateKey {
oneof sum {
bytes ed25519 = 1;
}
}
43 changes: 3 additions & 40 deletions third_party/proto/tendermint/types/evidence.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,46 +13,14 @@ import "tendermint/crypto/keys.proto";
message DuplicateVoteEvidence {
Vote vote_a = 1;
Vote vote_b = 2;

google.protobuf.Timestamp timestamp = 3
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

message PotentialAmnesiaEvidence {
Vote vote_a = 1;
Vote vote_b = 2;

int64 height_stamp = 3;
google.protobuf.Timestamp timestamp = 4
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

message AmnesiaEvidence {
PotentialAmnesiaEvidence potential_amnesia_evidence = 1;
ProofOfLockChange polc = 2;
}

message ConflictingHeadersEvidence {
SignedHeader h1 = 1;
SignedHeader h2 = 2;
}

message LunaticValidatorEvidence {
Header header = 1;
Vote vote = 2;
string invalid_header_field = 3;

google.protobuf.Timestamp timestamp = 4
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp timestamp = 3
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}

message Evidence {
oneof sum {
DuplicateVoteEvidence duplicate_vote_evidence = 1;
ConflictingHeadersEvidence conflicting_headers_evidence = 2;
LunaticValidatorEvidence lunatic_validator_evidence = 3;
PotentialAmnesiaEvidence potential_amnesia_evidence = 4;
AmnesiaEvidence amnesia_evidence = 5;
DuplicateVoteEvidence duplicate_vote_evidence = 1;
}
}

Expand All @@ -61,8 +29,3 @@ message EvidenceData {
repeated Evidence evidence = 1 [(gogoproto.nullable) = false];
bytes hash = 2;
}

message ProofOfLockChange {
repeated Vote votes = 1;
tendermint.crypto.PublicKey pub_key = 2;
}
5 changes: 0 additions & 5 deletions third_party/proto/tendermint/types/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ message EvidenceParams {
// each evidence (See MaxEvidenceBytes). The maximum number is MaxEvidencePerBlock.
// Default is 50
uint32 max_num = 3;

// Proof trial period dictates the time given for nodes accused of amnesia evidence, incorrectly
// voting twice in two different rounds to respond with their respective proofs.
// Default is half the max age in blocks: 50,000
int64 proof_trial_period = 4;
}

// ValidatorParams restrict the public key types validators can use.
Expand Down
6 changes: 6 additions & 0 deletions third_party/proto/tendermint/types/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import "google/protobuf/timestamp.proto";
import "tendermint/libs/bits/types.proto";
import "tendermint/crypto/proof.proto";
import "tendermint/version/types.proto";
import "tendermint/types/validator.proto";

// BlockIdFlag indicates which BlcokID the signature is for
enum BlockIDFlag {
Expand Down Expand Up @@ -141,6 +142,11 @@ message SignedHeader {
Commit commit = 2;
}

message LightBlock {
SignedHeader signed_header = 1;
tendermint.types.ValidatorSet validator_set = 2;
}

message BlockMeta {
BlockID block_id = 1 [(gogoproto.customname) = "BlockID", (gogoproto.nullable) = false];
int64 block_size = 2;
Expand Down
14 changes: 7 additions & 7 deletions x/evidence/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ import (
"fmt"
"time"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"

abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/evidence/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence/types"
)
Expand All @@ -21,9 +19,11 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)

for _, tmEvidence := range req.ByzantineValidators {
switch tmEvidence.Type {
case tmtypes.ABCIEvidenceTypeDuplicateVote:
evidence := types.ConvertDuplicateVoteEvidence(tmEvidence)
k.HandleDoubleSign(ctx, evidence.(*types.Equivocation))
// It's still ongoing discussion how should we treat and slash attacks with
// premeditation. So for now we agree to treat them in the same way.
case abci.EvidenceType_DUPLICATE_VOTE, abci.EvidenceType_LIGHT_CLIENT_ATTACK:
evidence := types.FromABCIEvidence(tmEvidence)
k.HandleEquivocationEvidence(ctx, evidence.(*types.Equivocation))

default:
k.Logger(ctx).Error(fmt.Sprintf("ignored unknown evidence type: %s", tmEvidence.Type))
Expand Down
4 changes: 2 additions & 2 deletions x/evidence/keeper/infraction.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/evidence/types"
)

// HandleDoubleSign implements an equivocation evidence handler. Assuming the
// HandleEquivocationEvidence implements an equivocation evidence handler. Assuming the
// evidence is valid, the validator committing the misbehavior will be slashed,
// jailed and tombstoned. Once tombstoned, the validator will not be able to
// recover. Note, the evidence contains the block time and height at the time of
Expand All @@ -22,7 +22,7 @@ import (
//
// TODO: Some of the invalid constraints listed above may need to be reconsidered
// in the case of a lunatic attack.
func (k Keeper) HandleDoubleSign(ctx sdk.Context, evidence *types.Equivocation) {
func (k Keeper) HandleEquivocationEvidence(ctx sdk.Context, evidence *types.Equivocation) {
logger := k.Logger(ctx)
consAddr := evidence.GetConsensusAddress()

Expand Down
6 changes: 3 additions & 3 deletions x/evidence/keeper/infraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign() {
Power: power,
ConsensusAddress: sdk.ConsAddress(val.Address()),
}
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)

// should be jailed and tombstoned
suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
Expand All @@ -63,7 +63,7 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign() {
suite.True(newTokens.LT(oldTokens))

// submit duplicate evidence
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)

// tokens should be the same (capped slash)
suite.True(suite.app.StakingKeeper.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))
Expand Down Expand Up @@ -119,7 +119,7 @@ func (suite *KeeperTestSuite) TestHandleDoubleSign_TooOld() {
ctx = ctx.WithConsensusParams(cp)
ctx = ctx.WithBlockTime(ctx.BlockTime().Add(cp.Evidence.MaxAgeDuration + 1))
ctx = ctx.WithBlockHeight(ctx.BlockHeight() + cp.Evidence.MaxAgeNumBlocks + 1)
suite.app.EvidenceKeeper.HandleDoubleSign(ctx, evidence)
suite.app.EvidenceKeeper.HandleEquivocationEvidence(ctx, evidence)

suite.False(suite.app.StakingKeeper.Validator(ctx, operatorAddr).IsJailed())
suite.False(suite.app.SlashingKeeper.IsTombstoned(ctx, sdk.ConsAddress(val.Address())))
Expand Down
4 changes: 2 additions & 2 deletions x/evidence/types/evidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ func (e Equivocation) GetValidatorPower() int64 {
// GetTotalPower is a no-op for the Equivocation type.
func (e Equivocation) GetTotalPower() int64 { return 0 }

// ConvertDuplicateVoteEvidence converts a Tendermint concrete Evidence type to
// FromABCIEvidence converts a Tendermint concrete Evidence type to
// SDK Evidence using Equivocation as the concrete type.
func ConvertDuplicateVoteEvidence(dupVote abci.Evidence) exported.Evidence {
func FromABCIEvidence(dupVote abci.Evidence) exported.Evidence {
return &Equivocation{
Height: dupVote.Height,
Power: dupVote.Validator.Power,
Expand Down
3 changes: 1 addition & 2 deletions x/simulation/mock_tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtypes "github.com/tendermint/tendermint/types"
)

type mockValidator struct {
Expand Down Expand Up @@ -201,7 +200,7 @@ func RandomRequestBeginBlock(r *rand.Rand, params Params,

evidence = append(evidence,
abci.Evidence{
Type: tmtypes.ABCIEvidenceTypeDuplicateVote,
Type: abci.EvidenceType_DUPLICATE_VOTE,
Validator: validator,
Height: height,
Time: time,
Expand Down

0 comments on commit 9856327

Please sign in to comment.