Browse Source

protoc and update everything

pull/1780/head
Ethan Buchman 6 years ago
parent
commit
3dbdc87edb
13 changed files with 249 additions and 897 deletions
  1. +0
    -3
      Makefile
  2. +0
    -4
      example/dummy/README.md
  3. +0
    -36
      example/dummy/helpers.go
  4. +0
    -126
      example/dummy/kvstore.go
  5. +0
    -310
      example/dummy/kvstore_test.go
  6. +0
    -205
      example/dummy/persistent_kvstore.go
  7. +5
    -2
      example/kvstore/helpers.go
  8. +1
    -1
      example/kvstore/kvstore_test.go
  9. +7
    -12
      example/kvstore/persistent_kvstore.go
  10. +1
    -1
      tests/server/client.go
  11. +16
    -0
      types/pubkey.go
  12. +208
    -193
      types/types.pb.go
  13. +11
    -4
      types/util.go

+ 0
- 3
Makefile View File

@ -94,9 +94,6 @@ test_cli:
# test the cli against the examples in the tutorial at tendermint.com
@ bash tests/test_cli/test.sh
fmt:
@ go fmt ./...
########################################
### Formatting, linting, and vetting


+ 0
- 4
example/dummy/README.md View File

@ -1,4 +0,0 @@
# Dummy
DEPRECATED. See KVStore

+ 0
- 36
example/dummy/helpers.go View File

@ -1,36 +0,0 @@
package dummy
import (
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
)
// RandVal creates one random validator, with a key derived
// from the input value
func RandVal(i int) types.Validator {
pubkey := cmn.RandBytes(33)
power := cmn.RandUint16() + 1
return types.Validator{pubkey, int64(power)}
}
// RandVals returns a list of cnt validators for initializing
// the application. Note that the keys are deterministically
// derived from the index in the array, while the power is
// random (Change this if not desired)
func RandVals(cnt int) []types.Validator {
res := make([]types.Validator, cnt)
for i := 0; i < cnt; i++ {
res[i] = RandVal(i)
}
return res
}
// InitDummy initializes the dummy app with some data,
// which allows tests to pass and is fine as long as you
// don't make any tx that modify the validator state
func InitDummy(app *PersistentDummyApplication) {
app.InitChain(types.RequestInitChain{
Validators: RandVals(1),
GenesisBytes: []byte("[]"),
})
}

+ 0
- 126
example/dummy/kvstore.go View File

@ -1,126 +0,0 @@
package dummy
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
)
var (
stateKey = []byte("stateKey")
kvPairPrefixKey = []byte("kvPairKey:")
)
type State struct {
db dbm.DB
Size int64 `json:"size"`
Height int64 `json:"height"`
AppHash []byte `json:"app_hash"`
}
func loadState(db dbm.DB) State {
stateBytes := db.Get(stateKey)
var state State
if len(stateBytes) != 0 {
err := json.Unmarshal(stateBytes, &state)
if err != nil {
panic(err)
}
}
state.db = db
return state
}
func saveState(state State) {
stateBytes, err := json.Marshal(state)
if err != nil {
panic(err)
}
state.db.Set(stateKey, stateBytes)
}
func prefixKey(key []byte) []byte {
return append(kvPairPrefixKey, key...)
}
//---------------------------------------------------
var _ types.Application = (*DummyApplication)(nil)
type DummyApplication struct {
types.BaseApplication
state State
}
func NewDummyApplication() *DummyApplication {
state := loadState(dbm.NewMemDB())
return &DummyApplication{state: state}
}
func (app *DummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
return types.ResponseInfo{Data: fmt.Sprintf("{\"size\":%v}", app.state.Size)}
}
// tx is either "key=value" or just arbitrary bytes
func (app *DummyApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
var key, value []byte
parts := bytes.Split(tx, []byte("="))
if len(parts) == 2 {
key, value = parts[0], parts[1]
} else {
key, value = tx, tx
}
app.state.db.Set(prefixKey(key), value)
app.state.Size += 1
tags := []cmn.KVPair{
{[]byte("app.creator"), []byte("jae")},
{[]byte("app.key"), key},
}
return types.ResponseDeliverTx{Code: code.CodeTypeOK, Tags: tags}
}
func (app *DummyApplication) CheckTx(tx []byte) types.ResponseCheckTx {
return types.ResponseCheckTx{Code: code.CodeTypeOK}
}
func (app *DummyApplication) Commit() types.ResponseCommit {
// Using a memdb - just return the big endian size of the db
appHash := make([]byte, 8)
binary.PutVarint(appHash, app.state.Size)
app.state.AppHash = appHash
app.state.Height += 1
saveState(app.state)
return types.ResponseCommit{Data: appHash}
}
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
if reqQuery.Prove {
value := app.state.db.Get(prefixKey(reqQuery.Data))
resQuery.Index = -1 // TODO make Proof return index
resQuery.Key = reqQuery.Data
resQuery.Value = value
if value != nil {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
} else {
value := app.state.db.Get(prefixKey(reqQuery.Data))
resQuery.Value = value
if value != nil {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
}
}

+ 0
- 310
example/dummy/kvstore_test.go View File

@ -1,310 +0,0 @@
package dummy
import (
"bytes"
"io/ioutil"
"sort"
"testing"
"github.com/stretchr/testify/require"
cmn "github.com/tendermint/tmlibs/common"
"github.com/tendermint/tmlibs/log"
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/example/code"
abciserver "github.com/tendermint/abci/server"
"github.com/tendermint/abci/types"
)
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
ar := app.DeliverTx(tx)
require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error
ar = app.DeliverTx(tx)
require.False(t, ar.IsErr(), ar)
// make sure query is fine
resQuery := app.Query(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
// make sure proof is fine
resQuery = app.Query(types.RequestQuery{
Path: "/store",
Data: []byte(key),
Prove: true,
})
require.EqualValues(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
}
func TestDummyKV(t *testing.T) {
dummy := NewDummyApplication()
key := "abc"
value := key
tx := []byte(key)
testDummy(t, dummy, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testDummy(t, dummy, tx, key, value)
}
func TestPersistentDummyKV(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
if err != nil {
t.Fatal(err)
}
dummy := NewPersistentDummyApplication(dir)
key := "abc"
value := key
tx := []byte(key)
testDummy(t, dummy, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testDummy(t, dummy, tx, key, value)
}
func TestPersistentDummyInfo(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
if err != nil {
t.Fatal(err)
}
dummy := NewPersistentDummyApplication(dir)
InitDummy(dummy)
height := int64(0)
resInfo := dummy.Info(types.RequestInfo{})
if resInfo.LastBlockHeight != height {
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
}
// make and apply block
height = int64(1)
hash := []byte("foo")
header := types.Header{
Height: int64(height),
}
dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
dummy.EndBlock(types.RequestEndBlock{header.Height})
dummy.Commit()
resInfo = dummy.Info(types.RequestInfo{})
if resInfo.LastBlockHeight != height {
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
}
}
// add a validator, remove a validator, update a validator
func TestValUpdates(t *testing.T) {
dir, err := ioutil.TempDir("/tmp", "abci-dummy-test") // TODO
if err != nil {
t.Fatal(err)
}
dummy := NewPersistentDummyApplication(dir)
// init with some validators
total := 10
nInit := 5
vals := RandVals(total)
// iniitalize with the first nInit
dummy.InitChain(types.RequestInitChain{
Validators: vals[:nInit],
})
vals1, vals2 := vals[:nInit], dummy.Validators()
valsEqual(t, vals1, vals2)
var v1, v2, v3 types.Validator
// add some validators
v1, v2 = vals[nInit], vals[nInit+1]
diff := []types.Validator{v1, v2}
tx1 := MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 := MakeValSetChangeTx(v2.PubKey, v2.Power)
makeApplyBlock(t, dummy, 1, diff, tx1, tx2)
vals1, vals2 = vals[:nInit+2], dummy.Validators()
valsEqual(t, vals1, vals2)
// remove some validators
v1, v2, v3 = vals[nInit-2], vals[nInit-1], vals[nInit]
v1.Power = 0
v2.Power = 0
v3.Power = 0
diff = []types.Validator{v1, v2, v3}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
tx2 = MakeValSetChangeTx(v2.PubKey, v2.Power)
tx3 := MakeValSetChangeTx(v3.PubKey, v3.Power)
makeApplyBlock(t, dummy, 2, diff, tx1, tx2, tx3)
vals1 = append(vals[:nInit-2], vals[nInit+1])
vals2 = dummy.Validators()
valsEqual(t, vals1, vals2)
// update some validators
v1 = vals[0]
if v1.Power == 5 {
v1.Power = 6
} else {
v1.Power = 5
}
diff = []types.Validator{v1}
tx1 = MakeValSetChangeTx(v1.PubKey, v1.Power)
makeApplyBlock(t, dummy, 3, diff, tx1)
vals1 = append([]types.Validator{v1}, vals1[1:]...)
vals2 = dummy.Validators()
valsEqual(t, vals1, vals2)
}
func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff []types.Validator, txs ...[]byte) {
// make and apply block
height := int64(heightInt)
hash := []byte("foo")
header := types.Header{
Height: height,
}
dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil})
for _, tx := range txs {
if r := dummy.DeliverTx(tx); r.IsErr() {
t.Fatal(r)
}
}
resEndBlock := dummy.EndBlock(types.RequestEndBlock{header.Height})
dummy.Commit()
valsEqual(t, diff, resEndBlock.ValidatorUpdates)
}
// order doesn't matter
func valsEqual(t *testing.T, vals1, vals2 []types.Validator) {
if len(vals1) != len(vals2) {
t.Fatalf("vals dont match in len. got %d, expected %d", len(vals2), len(vals1))
}
sort.Sort(types.Validators(vals1))
sort.Sort(types.Validators(vals2))
for i, v1 := range vals1 {
v2 := vals2[i]
if !bytes.Equal(v1.PubKey, v2.PubKey) ||
v1.Power != v2.Power {
t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
}
}
}
func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
logger := log.TestingLogger()
server := abciserver.NewSocketServer(socket, app)
server.SetLogger(logger.With("module", "abci-server"))
if err := server.Start(); err != nil {
return nil, nil, err
}
// Connect to the socket
client := abcicli.NewSocketClient(socket, false)
client.SetLogger(logger.With("module", "abci-client"))
if err := client.Start(); err != nil {
server.Stop()
return nil, nil, err
}
return client, server, nil
}
func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
logger := log.TestingLogger()
gapp := types.NewGRPCApplication(app)
server := abciserver.NewGRPCServer(socket, gapp)
server.SetLogger(logger.With("module", "abci-server"))
if err := server.Start(); err != nil {
return nil, nil, err
}
client := abcicli.NewGRPCClient(socket, true)
client.SetLogger(logger.With("module", "abci-client"))
if err := client.Start(); err != nil {
server.Stop()
return nil, nil, err
}
return client, server, nil
}
func TestClientServer(t *testing.T) {
// set up socket app
dummy := NewDummyApplication()
client, server, err := makeSocketClientServer(dummy, "dummy-socket")
require.Nil(t, err)
defer server.Stop()
defer client.Stop()
runClientTests(t, client)
// set up grpc app
dummy = NewDummyApplication()
gclient, gserver, err := makeGRPCClientServer(dummy, "dummy-grpc")
require.Nil(t, err)
defer gserver.Stop()
defer gclient.Stop()
runClientTests(t, gclient)
}
func runClientTests(t *testing.T, client abcicli.Client) {
// run some tests....
key := "abc"
value := key
tx := []byte(key)
testClient(t, client, tx, key, value)
value = "def"
tx = []byte(key + "=" + value)
testClient(t, client, tx, key, value)
}
func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
ar, err := app.DeliverTxSync(tx)
require.NoError(t, err)
require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error
ar, err = app.DeliverTxSync(tx)
require.NoError(t, err)
require.False(t, ar.IsErr(), ar)
// make sure query is fine
resQuery, err := app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Nil(t, err)
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
// make sure proof is fine
resQuery, err = app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
Prove: true,
})
require.Nil(t, err)
require.Equal(t, code.CodeTypeOK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
}

+ 0
- 205
example/dummy/persistent_kvstore.go View File

@ -1,205 +0,0 @@
package dummy
import (
"bytes"
"encoding/hex"
"fmt"
"strconv"
"strings"
"github.com/tendermint/abci/example/code"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/tmlibs/log"
)
const (
ValidatorSetChangePrefix string = "val:"
)
//-----------------------------------------
var _ types.Application = (*PersistentDummyApplication)(nil)
type PersistentDummyApplication struct {
app *DummyApplication
// validator set
ValUpdates []types.Validator
logger log.Logger
}
func NewPersistentDummyApplication(dbDir string) *PersistentDummyApplication {
name := "dummy"
db, err := dbm.NewGoLevelDB(name, dbDir)
if err != nil {
panic(err)
}
state := loadState(db)
return &PersistentDummyApplication{
app: &DummyApplication{state: state},
logger: log.NewNopLogger(),
}
}
func (app *PersistentDummyApplication) SetLogger(l log.Logger) {
app.logger = l
}
func (app *PersistentDummyApplication) Info(req types.RequestInfo) types.ResponseInfo {
res := app.app.Info(req)
res.LastBlockHeight = app.app.state.Height
res.LastBlockAppHash = app.app.state.AppHash
return res
}
func (app *PersistentDummyApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption {
return app.app.SetOption(req)
}
// tx is either "val:pubkey/power" or "key=value" or just arbitrary bytes
func (app *PersistentDummyApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
// if it starts with "val:", update the validator set
// format is "val:pubkey/power"
if isValidatorTx(tx) {
// update validators in the merkle tree
// and in app.ValUpdates
return app.execValidatorTx(tx)
}
// otherwise, update the key-value store
return app.app.DeliverTx(tx)
}
func (app *PersistentDummyApplication) CheckTx(tx []byte) types.ResponseCheckTx {
return app.app.CheckTx(tx)
}
// Commit will panic if InitChain was not called
func (app *PersistentDummyApplication) Commit() types.ResponseCommit {
return app.app.Commit()
}
func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
return app.app.Query(reqQuery)
}
// Save the validators in the merkle tree
func (app *PersistentDummyApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain {
for _, v := range req.Validators {
r := app.updateValidator(v)
if r.IsErr() {
app.logger.Error("Error updating validators", "r", r)
}
}
return types.ResponseInitChain{}
}
// Track the block hash and header information
func (app *PersistentDummyApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
// reset valset changes
app.ValUpdates = make([]types.Validator, 0)
return types.ResponseBeginBlock{}
}
// Update the validator set
func (app *PersistentDummyApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock {
return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates}
}
//---------------------------------------------
// update validators
func (app *PersistentDummyApplication) Validators() (validators []types.Validator) {
itr := app.app.state.db.Iterator(nil, nil)
for ; itr.Valid(); itr.Next() {
if isValidatorTx(itr.Key()) {
validator := new(types.Validator)
err := types.ReadMessage(bytes.NewBuffer(itr.Value()), validator)
if err != nil {
panic(err)
}
validators = append(validators, *validator)
}
}
return
}
func MakeValSetChangeTx(pubkey []byte, power int64) []byte {
return []byte(cmn.Fmt("val:%X/%d", pubkey, power))
}
func isValidatorTx(tx []byte) bool {
return strings.HasPrefix(string(tx), ValidatorSetChangePrefix)
}
// format is "val:pubkey1/power1,addr2/power2,addr3/power3"tx
func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx {
tx = tx[len(ValidatorSetChangePrefix):]
//get the pubkey and power
pubKeyAndPower := strings.Split(string(tx), "/")
if len(pubKeyAndPower) != 2 {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Expected 'pubkey/power'. Got %v", pubKeyAndPower)}
}
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
// decode the pubkey, ensuring its go-crypto encoded
pubkey, err := hex.DecodeString(pubkeyS)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS)}
}
/*_, err = crypto.PubKeyFromBytes(pubkey)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%X) is invalid go-crypto encoded", pubkey)}
}*/
// decode the power
power, err := strconv.ParseInt(powerS, 10, 64)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Power (%s) is not an int", powerS)}
}
// update
return app.updateValidator(types.Validator{pubkey, power})
}
// add, update, or remove a validator
func (app *PersistentDummyApplication) updateValidator(v types.Validator) types.ResponseDeliverTx {
key := []byte("val:" + string(v.PubKey))
if v.Power == 0 {
// remove validator
if !app.app.state.db.Has(key) {
return types.ResponseDeliverTx{
Code: code.CodeTypeUnauthorized,
Log: fmt.Sprintf("Cannot remove non-existent validator %X", key)}
}
app.app.state.db.Delete(key)
} else {
// add or update validator
value := bytes.NewBuffer(make([]byte, 0))
if err := types.WriteMessage(&v, value); err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Error encoding validator: %v", err)}
}
app.app.state.db.Set(key, value.Bytes())
}
// we only update the changes array if we successfully updated the tree
app.ValUpdates = append(app.ValUpdates, v)
return types.ResponseDeliverTx{Code: code.CodeTypeOK}
}

+ 5
- 2
example/kvstore/helpers.go View File

@ -8,9 +8,12 @@ import (
// RandVal creates one random validator, with a key derived
// from the input value
func RandVal(i int) types.Validator {
pubkey := cmn.RandBytes(33)
addr := cmn.RandBytes(20)
pubkey := cmn.RandBytes(32)
power := cmn.RandUint16() + 1
return types.Validator{pubkey, int64(power)}
v := types.Ed25519Validator(pubkey, int64(power))
v.Address = addr
return v
}
// RandVals returns a list of cnt validators for initializing


+ 1
- 1
example/kvstore/kvstore_test.go View File

@ -198,7 +198,7 @@ func valsEqual(t *testing.T, vals1, vals2 []types.Validator) {
sort.Sort(types.Validators(vals2))
for i, v1 := range vals1 {
v2 := vals2[i]
if !bytes.Equal(v1.PubKey, v2.PubKey) ||
if !bytes.Equal(v1.PubKey.Data, v2.PubKey.Data) ||
v1.Power != v2.Power {
t.Fatalf("vals dont match at index %d. got %X/%d , expected %X/%d", i, v2.PubKey, v2.Power, v1.PubKey, v1.Power)
}


+ 7
- 12
example/kvstore/persistent_kvstore.go View File

@ -129,15 +129,16 @@ func (app *PersistentKVStoreApplication) Validators() (validators []types.Valida
return
}
func MakeValSetChangeTx(pubkey []byte, power int64) []byte {
return []byte(cmn.Fmt("val:%X/%d", pubkey, power))
func MakeValSetChangeTx(pubkey types.PubKey, power int64) []byte {
return []byte(cmn.Fmt("val:%X/%d", pubkey.Data, power))
}
func isValidatorTx(tx []byte) bool {
return strings.HasPrefix(string(tx), ValidatorSetChangePrefix)
}
// format is "val:pubkey1/power1,addr2/power2,addr3/power3"tx
// format is "val:pubkey/power"
// pubkey is raw 32-byte ed25519 key
func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx {
tx = tx[len(ValidatorSetChangePrefix):]
@ -150,19 +151,13 @@ func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.Respon
}
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
// decode the pubkey, ensuring its go-crypto encoded
// decode the pubkey
pubkey, err := hex.DecodeString(pubkeyS)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS)}
}
/*_, err = crypto.PubKeyFromBytes(pubkey)
if err != nil {
return types.ResponseDeliverTx{
Code: code.CodeTypeEncodingError,
Log: fmt.Sprintf("Pubkey (%X) is invalid go-crypto encoded", pubkey)}
}*/
// decode the power
power, err := strconv.ParseInt(powerS, 10, 64)
@ -173,12 +168,12 @@ func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.Respon
}
// update
return app.updateValidator(types.Validator{pubkey, power})
return app.updateValidator(types.Ed25519Validator(pubkey, int64(power)))
}
// add, update, or remove a validator
func (app *PersistentKVStoreApplication) updateValidator(v types.Validator) types.ResponseDeliverTx {
key := []byte("val:" + string(v.PubKey))
key := []byte("val:" + string(v.PubKey.Data))
if v.Power == 0 {
// remove validator
if !app.app.state.db.Has(key) {


+ 1
- 1
tests/server/client.go View File

@ -16,7 +16,7 @@ func InitChain(client abcicli.Client) error {
for i := 0; i < total; i++ {
pubkey := cmn.RandBytes(33)
power := cmn.RandInt()
vals[i] = types.Validator{pubkey, int64(power)}
vals[i] = types.Ed25519Validator(pubkey, int64(power))
}
_, err := client.InitChainSync(types.RequestInitChain{
Validators: vals,


+ 16
- 0
types/pubkey.go View File

@ -0,0 +1,16 @@
package types
const (
PubKeyEd25519 = "ed25519"
)
func Ed25519Validator(pubkey []byte, power int64) Validator {
return Validator{
// Address:
PubKey: PubKey{
Type: PubKeyEd25519,
Data: pubkey,
},
Power: power,
}
}

+ 208
- 193
types/types.pb.go View File

@ -38,9 +38,9 @@ It has these top-level messages:
TxSize
BlockGossip
Header
BlockID
PartSetHeader
Validator
SigningValidator
PubKey
Evidence
*/
//nolint: gas
@ -596,10 +596,10 @@ func (m *RequestQuery) GetProve() bool {
}
type RequestBeginBlock struct {
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Header Header `protobuf:"bytes,2,opt,name=header" json:"header"`
AbsentValidators [][]byte `protobuf:"bytes,3,rep,name=absent_validators,json=absentValidators" json:"absent_validators,omitempty"`
ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"`
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Header Header `protobuf:"bytes,2,opt,name=header" json:"header"`
Validators []*SigningValidator `protobuf:"bytes,3,rep,name=validators" json:"validators,omitempty"`
ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"`
}
func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} }
@ -621,9 +621,9 @@ func (m *RequestBeginBlock) GetHeader() Header {
return Header{}
}
func (m *RequestBeginBlock) GetAbsentValidators() [][]byte {
func (m *RequestBeginBlock) GetValidators() []*SigningValidator {
if m != nil {
return m.AbsentValidators
return m.Validators
}
return nil
}
@ -1646,16 +1646,20 @@ func (m *BlockGossip) GetBlockPartSizeBytes() int32 {
return 0
}
// just the minimum the app might need
type Header struct {
ChainID string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
NumTxs int32 `protobuf:"varint,4,opt,name=num_txs,json=numTxs,proto3" json:"num_txs,omitempty"`
LastBlockID BlockID `protobuf:"bytes,5,opt,name=last_block_id,json=lastBlockId" json:"last_block_id"`
LastCommitHash []byte `protobuf:"bytes,6,opt,name=last_commit_hash,json=lastCommitHash,proto3" json:"last_commit_hash,omitempty"`
DataHash []byte `protobuf:"bytes,7,opt,name=data_hash,json=dataHash,proto3" json:"data_hash,omitempty"`
ValidatorsHash []byte `protobuf:"bytes,8,opt,name=validators_hash,json=validatorsHash,proto3" json:"validators_hash,omitempty"`
AppHash []byte `protobuf:"bytes,9,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
// basics
ChainID string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"`
Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"`
// txs
NumTxs int32 `protobuf:"varint,4,opt,name=num_txs,json=numTxs,proto3" json:"num_txs,omitempty"`
TotalTxs int64 `protobuf:"varint,5,opt,name=total_txs,json=totalTxs,proto3" json:"total_txs,omitempty"`
// hashes
LastBlockHash []byte `protobuf:"bytes,6,opt,name=last_block_hash,json=lastBlockHash,proto3" json:"last_block_hash,omitempty"`
AppHash []byte `protobuf:"bytes,7,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
// consensus
Proposer *Validator `protobuf:"bytes,8,opt,name=proposer" json:"proposer,omitempty"`
}
func (m *Header) Reset() { *m = Header{} }
@ -1691,118 +1695,122 @@ func (m *Header) GetNumTxs() int32 {
return 0
}
func (m *Header) GetLastBlockID() BlockID {
func (m *Header) GetTotalTxs() int64 {
if m != nil {
return m.LastBlockID
return m.TotalTxs
}
return BlockID{}
return 0
}
func (m *Header) GetLastCommitHash() []byte {
func (m *Header) GetLastBlockHash() []byte {
if m != nil {
return m.LastCommitHash
return m.LastBlockHash
}
return nil
}
func (m *Header) GetDataHash() []byte {
func (m *Header) GetAppHash() []byte {
if m != nil {
return m.DataHash
return m.AppHash
}
return nil
}
func (m *Header) GetValidatorsHash() []byte {
func (m *Header) GetProposer() *Validator {
if m != nil {
return m.ValidatorsHash
return m.Proposer
}
return nil
}
func (m *Header) GetAppHash() []byte {
// Validator
type Validator struct {
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
PubKey PubKey `protobuf:"bytes,2,opt,name=pub_key,json=pubKey" json:"pub_key"`
Power int64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"`
}
func (m *Validator) Reset() { *m = Validator{} }
func (m *Validator) String() string { return proto.CompactTextString(m) }
func (*Validator) ProtoMessage() {}
func (*Validator) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} }
func (m *Validator) GetAddress() []byte {
if m != nil {
return m.AppHash
return m.Address
}
return nil
}
type BlockID struct {
Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
Parts PartSetHeader `protobuf:"bytes,2,opt,name=parts" json:"parts"`
}
func (m *BlockID) Reset() { *m = BlockID{} }
func (m *BlockID) String() string { return proto.CompactTextString(m) }
func (*BlockID) ProtoMessage() {}
func (*BlockID) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} }
func (m *BlockID) GetHash() []byte {
func (m *Validator) GetPubKey() PubKey {
if m != nil {
return m.Hash
return m.PubKey
}
return nil
return PubKey{}
}
func (m *BlockID) GetParts() PartSetHeader {
func (m *Validator) GetPower() int64 {
if m != nil {
return m.Parts
return m.Power
}
return PartSetHeader{}
return 0
}
type PartSetHeader struct {
Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"`
// Validator with an extra bool
type SigningValidator struct {
Validator *Validator `protobuf:"bytes,1,opt,name=validator" json:"validator,omitempty"`
SignedLastBlock bool `protobuf:"varint,2,opt,name=signed_last_block,json=signedLastBlock,proto3" json:"signed_last_block,omitempty"`
}
func (m *PartSetHeader) Reset() { *m = PartSetHeader{} }
func (m *PartSetHeader) String() string { return proto.CompactTextString(m) }
func (*PartSetHeader) ProtoMessage() {}
func (*PartSetHeader) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} }
func (m *SigningValidator) Reset() { *m = SigningValidator{} }
func (m *SigningValidator) String() string { return proto.CompactTextString(m) }
func (*SigningValidator) ProtoMessage() {}
func (*SigningValidator) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{31} }
func (m *PartSetHeader) GetTotal() int32 {
func (m *SigningValidator) GetValidator() *Validator {
if m != nil {
return m.Total
return m.Validator
}
return 0
return nil
}
func (m *PartSetHeader) GetHash() []byte {
func (m *SigningValidator) GetSignedLastBlock() bool {
if m != nil {
return m.Hash
return m.SignedLastBlock
}
return nil
return false
}
type Validator struct {
PubKey []byte `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"`
Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"`
type PubKey struct {
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *Validator) Reset() { *m = Validator{} }
func (m *Validator) String() string { return proto.CompactTextString(m) }
func (*Validator) ProtoMessage() {}
func (*Validator) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} }
func (m *PubKey) Reset() { *m = PubKey{} }
func (m *PubKey) String() string { return proto.CompactTextString(m) }
func (*PubKey) ProtoMessage() {}
func (*PubKey) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{32} }
func (m *Validator) GetPubKey() []byte {
func (m *PubKey) GetType() string {
if m != nil {
return m.PubKey
return m.Type
}
return nil
return ""
}
func (m *Validator) GetPower() int64 {
func (m *PubKey) GetData() []byte {
if m != nil {
return m.Power
return m.Data
}
return 0
return nil
}
type Evidence struct {
Type []byte `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
PubKey []byte `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"`
Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
Time int64 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Validator *Validator `protobuf:"bytes,2,opt,name=validator" json:"validator,omitempty"`
Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
Time int64 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"`
TotalVotingPower int64 `protobuf:"varint,5,opt,name=total_voting_power,json=totalVotingPower,proto3" json:"total_voting_power,omitempty"`
}
func (m *Evidence) Reset() { *m = Evidence{} }
@ -1810,16 +1818,16 @@ func (m *Evidence) String() string { return proto.CompactTextString(m
func (*Evidence) ProtoMessage() {}
func (*Evidence) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{33} }
func (m *Evidence) GetType() []byte {
func (m *Evidence) GetType() string {
if m != nil {
return m.Type
}
return nil
return ""
}
func (m *Evidence) GetPubKey() []byte {
func (m *Evidence) GetValidator() *Validator {
if m != nil {
return m.PubKey
return m.Validator
}
return nil
}
@ -1838,6 +1846,13 @@ func (m *Evidence) GetTime() int64 {
return 0
}
func (m *Evidence) GetTotalVotingPower() int64 {
if m != nil {
return m.TotalVotingPower
}
return 0
}
func init() {
proto.RegisterType((*Request)(nil), "types.Request")
proto.RegisterType((*RequestEcho)(nil), "types.RequestEcho")
@ -1869,9 +1884,9 @@ func init() {
proto.RegisterType((*TxSize)(nil), "types.TxSize")
proto.RegisterType((*BlockGossip)(nil), "types.BlockGossip")
proto.RegisterType((*Header)(nil), "types.Header")
proto.RegisterType((*BlockID)(nil), "types.BlockID")
proto.RegisterType((*PartSetHeader)(nil), "types.PartSetHeader")
proto.RegisterType((*Validator)(nil), "types.Validator")
proto.RegisterType((*SigningValidator)(nil), "types.SigningValidator")
proto.RegisterType((*PubKey)(nil), "types.PubKey")
proto.RegisterType((*Evidence)(nil), "types.Evidence")
}
@ -2280,117 +2295,117 @@ var _ABCIApplication_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("types/types.proto", fileDescriptorTypes) }
var fileDescriptorTypes = []byte{
// 1784 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcd, 0x72, 0x1b, 0xc7,
0x11, 0x26, 0xfe, 0xb1, 0x0d, 0x10, 0x24, 0x87, 0xfa, 0x81, 0xe0, 0x4a, 0x89, 0xb5, 0x49, 0xd9,
0x60, 0x24, 0x13, 0x09, 0x1d, 0xa9, 0x44, 0x39, 0xe5, 0x0a, 0x41, 0x2a, 0x02, 0x4a, 0x49, 0xcc,
0xac, 0x65, 0xa5, 0x2a, 0x17, 0xd4, 0x60, 0x77, 0x08, 0x6c, 0x09, 0xfb, 0x63, 0xcc, 0x80, 0x06,
0x75, 0xcb, 0xdd, 0xf7, 0x9c, 0xf3, 0x10, 0x79, 0x85, 0x54, 0x52, 0x79, 0x07, 0x1e, 0x9c, 0x5b,
0x5e, 0x22, 0xa9, 0x9e, 0x99, 0xfd, 0xe5, 0xc2, 0xe5, 0x28, 0x47, 0x5f, 0x80, 0x99, 0xed, 0xaf,
0x67, 0xa6, 0x7b, 0x7a, 0xbe, 0xee, 0x19, 0xd8, 0x13, 0xd7, 0x21, 0xe3, 0x03, 0xf9, 0x7b, 0x14,
0x2e, 0x03, 0x11, 0x90, 0x9a, 0xec, 0xf4, 0x3e, 0x9e, 0xb9, 0x62, 0xbe, 0x9a, 0x1e, 0xd9, 0x81,
0x37, 0x98, 0x05, 0xb3, 0x60, 0x20, 0xa5, 0xd3, 0xd5, 0xa5, 0xec, 0xc9, 0x8e, 0x6c, 0x29, 0xad,
0xde, 0x20, 0x05, 0x17, 0xcc, 0x77, 0xd8, 0xd2, 0x73, 0x7d, 0x31, 0x10, 0xde, 0xc2, 0x9d, 0xf2,
0x81, 0x1d, 0x78, 0x5e, 0xe0, 0xa7, 0xa7, 0x31, 0xff, 0x56, 0x85, 0x86, 0xc5, 0xbe, 0x5a, 0x31,
0x2e, 0x48, 0x1f, 0xaa, 0xcc, 0x9e, 0x07, 0xdd, 0xf2, 0x41, 0xa9, 0xdf, 0x3a, 0x26, 0x47, 0x0a,
0xa7, 0xa5, 0x2f, 0xec, 0x79, 0x30, 0xda, 0xb2, 0x24, 0x82, 0x3c, 0x82, 0xda, 0xe5, 0x62, 0xc5,
0xe7, 0xdd, 0x8a, 0x84, 0xee, 0x67, 0xa1, 0xbf, 0x46, 0xd1, 0x68, 0xcb, 0x52, 0x18, 0x1c, 0xd6,
0xf5, 0x2f, 0x83, 0x6e, 0xb5, 0x68, 0xd8, 0xb1, 0x7f, 0x29, 0x87, 0x45, 0x04, 0x79, 0x06, 0xc0,
0x99, 0x98, 0x04, 0xa1, 0x70, 0x03, 0xbf, 0x5b, 0x93, 0xf8, 0xfb, 0x59, 0xfc, 0x17, 0x4c, 0x7c,
0x2e, 0xc5, 0xa3, 0x2d, 0xcb, 0xe0, 0x51, 0x07, 0x35, 0x5d, 0xdf, 0x15, 0x13, 0x7b, 0x4e, 0x5d,
0xbf, 0x5b, 0x2f, 0xd2, 0x1c, 0xfb, 0xae, 0x38, 0x43, 0x31, 0x6a, 0xba, 0x51, 0x07, 0x4d, 0xf9,
0x6a, 0xc5, 0x96, 0xd7, 0xdd, 0x46, 0x91, 0x29, 0xbf, 0x47, 0x11, 0x9a, 0x22, 0x31, 0xe4, 0x53,
0x68, 0x4d, 0xd9, 0xcc, 0xf5, 0x27, 0xd3, 0x45, 0x60, 0xbf, 0xed, 0x36, 0xa5, 0x4a, 0x37, 0xab,
0x32, 0x44, 0xc0, 0x10, 0xe5, 0xa3, 0x2d, 0x0b, 0xa6, 0x71, 0x8f, 0x1c, 0x43, 0xd3, 0x9e, 0x33,
0xfb, 0xed, 0x44, 0xac, 0xbb, 0x86, 0xd4, 0xbc, 0x9b, 0xd5, 0x3c, 0x43, 0xe9, 0xeb, 0xf5, 0x68,
0xcb, 0x6a, 0xd8, 0xaa, 0x89, 0x76, 0x39, 0x6c, 0xe1, 0x5e, 0xb1, 0x25, 0x6a, 0xed, 0x17, 0xd9,
0x75, 0xae, 0xe4, 0x52, 0xcf, 0x70, 0xa2, 0x0e, 0x79, 0x02, 0x06, 0xf3, 0x1d, 0xbd, 0xd0, 0x96,
0x54, 0xbc, 0x97, 0xdb, 0x51, 0xdf, 0x89, 0x96, 0xd9, 0x64, 0xba, 0x4d, 0x8e, 0xa0, 0x8e, 0x51,
0xe2, 0x8a, 0x6e, 0x5b, 0xea, 0xdc, 0xc9, 0x2d, 0x51, 0xca, 0x46, 0x5b, 0x96, 0x46, 0x0d, 0x1b,
0x50, 0xbb, 0xa2, 0x8b, 0x15, 0x33, 0x3f, 0x82, 0x56, 0x2a, 0x52, 0x48, 0x17, 0x1a, 0x1e, 0xe3,
0x9c, 0xce, 0x58, 0xb7, 0x74, 0x50, 0xea, 0x1b, 0x56, 0xd4, 0x35, 0x3b, 0xd0, 0x4e, 0xc7, 0x49,
0x4a, 0x11, 0x63, 0x01, 0x15, 0xaf, 0xd8, 0x92, 0x63, 0x00, 0x68, 0x45, 0xdd, 0x35, 0x9f, 0xc3,
0x6e, 0x3e, 0x08, 0xc8, 0x2e, 0x54, 0xde, 0xb2, 0x6b, 0x8d, 0xc4, 0x26, 0xb9, 0xa3, 0x17, 0x24,
0xa3, 0xd8, 0xb0, 0xf4, 0xea, 0x82, 0x58, 0x37, 0x0e, 0x03, 0xf2, 0x14, 0xe0, 0x8a, 0x2e, 0x5c,
0x87, 0x8a, 0x60, 0xc9, 0xbb, 0xa5, 0x83, 0x4a, 0xbf, 0x75, 0xbc, 0xab, 0xcd, 0x7d, 0x13, 0x09,
0x86, 0xd5, 0xbf, 0xdf, 0x3c, 0xdc, 0xb2, 0x52, 0x48, 0xf2, 0x63, 0xd8, 0x9e, 0x31, 0x9f, 0x71,
0x97, 0x4f, 0xa6, 0xd7, 0x82, 0x71, 0x39, 0x53, 0xdb, 0x6a, 0xeb, 0x8f, 0x43, 0xfc, 0x66, 0x3a,
0xb1, 0x95, 0x32, 0x84, 0x08, 0x81, 0xaa, 0x43, 0x05, 0x95, 0x2b, 0x6d, 0x5b, 0xb2, 0x8d, 0xdf,
0x42, 0x2a, 0xe6, 0x7a, 0xa5, 0xb2, 0x4d, 0xee, 0x41, 0x7d, 0xce, 0xdc, 0xd9, 0x5c, 0xc8, 0xa3,
0x55, 0xb1, 0x74, 0x0f, 0xcd, 0x0a, 0x97, 0xc1, 0x15, 0x93, 0xa7, 0xa8, 0x69, 0xa9, 0x8e, 0xf9,
0xcf, 0x12, 0xec, 0xdd, 0x0a, 0x3b, 0x1c, 0x77, 0x4e, 0xf9, 0x3c, 0x9a, 0x0b, 0xdb, 0xe4, 0x11,
0x8e, 0x4b, 0x1d, 0xb6, 0xd4, 0xa7, 0x7b, 0x5b, 0x1b, 0x3a, 0x92, 0x1f, 0xb5, 0x95, 0x1a, 0x42,
0x1e, 0xc1, 0x1e, 0x9d, 0x72, 0xe6, 0x8b, 0x49, 0xca, 0x41, 0x95, 0x83, 0x4a, 0xbf, 0x6d, 0xed,
0x2a, 0xc1, 0x9b, 0xc4, 0x1d, 0x23, 0xb8, 0x33, 0xbd, 0x7e, 0x47, 0x7d, 0xe1, 0xfa, 0x2c, 0x8d,
0xaf, 0x4a, 0x87, 0xee, 0xe8, 0x79, 0x5e, 0x5c, 0xb9, 0x0e, 0xf3, 0x6d, 0xa6, 0x67, 0xda, 0x8f,
0x55, 0x92, 0x91, 0xcc, 0x03, 0xe8, 0x64, 0x4f, 0x02, 0xe9, 0x40, 0x59, 0xac, 0xb5, 0x1d, 0x65,
0xb1, 0x36, 0xcd, 0x78, 0x1b, 0xe3, 0xa8, 0xbf, 0x85, 0x39, 0x84, 0x9d, 0x5c, 0x80, 0xa7, 0x9c,
0x5a, 0x4a, 0x3b, 0xd5, 0xdc, 0x81, 0xed, 0x4c, 0x5c, 0x9b, 0xdf, 0xd4, 0xa0, 0x69, 0x31, 0x1e,
0x06, 0x3e, 0x67, 0xe4, 0x19, 0x18, 0x6c, 0x6d, 0x33, 0x45, 0x46, 0xa5, 0xdc, 0x51, 0x57, 0x98,
0x17, 0x91, 0x1c, 0xcf, 0x5e, 0x0c, 0x26, 0x87, 0x19, 0x22, 0xdd, 0xcf, 0x2b, 0xa5, 0x99, 0xf4,
0x71, 0x96, 0x49, 0xef, 0xe4, 0xb0, 0x39, 0x2a, 0x3d, 0xcc, 0x50, 0x69, 0x7e, 0xe0, 0x0c, 0x97,
0x9e, 0x14, 0x70, 0x69, 0x7e, 0xf9, 0x1b, 0xc8, 0xf4, 0xa4, 0x80, 0x4c, 0xbb, 0xb7, 0xe6, 0x2a,
0x64, 0xd3, 0xc7, 0x59, 0x36, 0xcd, 0x9b, 0x93, 0xa3, 0xd3, 0x5f, 0x16, 0xd1, 0xe9, 0x83, 0x9c,
0xce, 0x46, 0x3e, 0xfd, 0xe4, 0x16, 0x9f, 0xde, 0xcb, 0xa9, 0x16, 0x10, 0xea, 0x49, 0x86, 0x50,
0xa1, 0xd0, 0xb6, 0x0d, 0x8c, 0xfa, 0xf4, 0x36, 0xa3, 0xde, 0xcf, 0x6f, 0x6d, 0x11, 0xa5, 0x0e,
0x72, 0x94, 0x7a, 0x37, 0xbf, 0xca, 0x8d, 0x9c, 0x7a, 0x88, 0xa7, 0x3b, 0x17, 0x69, 0xc8, 0x04,
0x6c, 0xb9, 0x0c, 0x96, 0x9a, 0xf4, 0x54, 0xc7, 0xec, 0x23, 0xdf, 0x24, 0xf1, 0xf5, 0x1d, 0xfc,
0x2b, 0x83, 0x3e, 0x15, 0x5d, 0xe6, 0x9f, 0x4b, 0x89, 0xae, 0xa4, 0xe0, 0x34, 0x57, 0x19, 0x9a,
0xab, 0x52, 0xb4, 0x5c, 0xce, 0xd0, 0x32, 0xf9, 0x29, 0xec, 0x2d, 0x28, 0x17, 0xca, 0x2f, 0x93,
0x0c, 0x79, 0xed, 0xa0, 0x40, 0x39, 0x44, 0xb1, 0xd8, 0xc7, 0xb0, 0x9f, 0xc2, 0xd2, 0x30, 0x9c,
0x48, 0xa2, 0xaa, 0xca, 0xc3, 0xbb, 0x1b, 0xa3, 0x4f, 0xc3, 0x70, 0x44, 0xf9, 0xdc, 0xfc, 0x6d,
0x62, 0x7f, 0x42, 0xf9, 0x04, 0xaa, 0x76, 0xe0, 0x28, 0xb3, 0xb6, 0x2d, 0xd9, 0xc6, 0x34, 0xb0,
0x08, 0x66, 0x72, 0x56, 0xc3, 0xc2, 0x26, 0xa2, 0xe2, 0x93, 0x62, 0xa8, 0x23, 0x61, 0xbe, 0x4a,
0x86, 0xfb, 0xbf, 0xb3, 0x80, 0xf9, 0xd7, 0x52, 0xe2, 0xc7, 0x98, 0xe2, 0xdf, 0x6f, 0x61, 0xb8,
0xa5, 0xae, 0xef, 0xb0, 0xb5, 0x3c, 0xa6, 0x15, 0x4b, 0x75, 0xa2, 0xdc, 0x56, 0x97, 0xce, 0xc9,
0xe6, 0xb6, 0x86, 0xfc, 0xa6, 0x3a, 0x3a, 0x35, 0x04, 0x97, 0xf2, 0xfc, 0xb4, 0x2d, 0xd5, 0x49,
0x71, 0x9e, 0x91, 0xe1, 0xbc, 0x0b, 0x20, 0xb7, 0x4f, 0x16, 0x79, 0x0e, 0x55, 0x41, 0x67, 0x91,
0xfd, 0x9d, 0x23, 0x55, 0x29, 0x1e, 0xbd, 0x7a, 0x73, 0x41, 0xdd, 0xe5, 0xf0, 0x1e, 0x5a, 0xff,
0xef, 0x9b, 0x87, 0x1d, 0xc4, 0x3c, 0x0e, 0x3c, 0x57, 0x30, 0x2f, 0x14, 0xd7, 0x96, 0xd4, 0x31,
0xff, 0x53, 0x42, 0xc6, 0xcd, 0x9c, 0xb8, 0x42, 0x5f, 0x44, 0x61, 0x55, 0x4e, 0xa5, 0xc0, 0xef,
0xe7, 0x9f, 0x1f, 0x01, 0xcc, 0x28, 0x9f, 0x7c, 0x4d, 0x7d, 0xc1, 0x1c, 0xed, 0x24, 0x63, 0x46,
0xf9, 0x1f, 0xe4, 0x07, 0xf2, 0x00, 0x9a, 0x28, 0x5e, 0x71, 0xe6, 0x48, 0x6f, 0x55, 0xac, 0xc6,
0x8c, 0xf2, 0x2f, 0x39, 0x73, 0x62, 0xbb, 0x1a, 0xff, 0xbb, 0x5d, 0xa4, 0x0f, 0x95, 0x4b, 0xc6,
0x34, 0x2b, 0xed, 0xc6, 0xaa, 0xe3, 0xa7, 0xbf, 0x90, 0xca, 0x2a, 0x24, 0x10, 0x62, 0xfe, 0xa9,
0x9c, 0x44, 0x56, 0x92, 0x98, 0x7e, 0x58, 0x3e, 0xf8, 0x57, 0x09, 0x73, 0x73, 0x96, 0x06, 0xc9,
0x19, 0xec, 0xc5, 0x47, 0x66, 0xb2, 0x0a, 0x1d, 0x8a, 0xe5, 0xd2, 0x77, 0x9f, 0xb1, 0xdd, 0x58,
0xe1, 0x4b, 0x85, 0x27, 0xbf, 0x83, 0xfb, 0x36, 0x8e, 0xea, 0xf3, 0x15, 0x9f, 0x84, 0x74, 0x49,
0xbd, 0x78, 0xa8, 0x72, 0x86, 0xf6, 0xcf, 0x22, 0xd4, 0x05, 0x82, 0xb8, 0x75, 0xd7, 0xce, 0x7c,
0x88, 0xc6, 0x8b, 0xfc, 0x51, 0x79, 0x8f, 0x58, 0xff, 0x09, 0x96, 0x28, 0x69, 0xda, 0x2e, 0xda,
0x51, 0xf3, 0x2f, 0x25, 0xd8, 0xc9, 0x2d, 0x86, 0x0c, 0x00, 0x14, 0xeb, 0x71, 0xf7, 0x1d, 0xd3,
0xe5, 0x44, 0xe4, 0x03, 0xe9, 0xac, 0x2f, 0xdc, 0x77, 0xcc, 0x32, 0xa6, 0x51, 0x93, 0x7c, 0x08,
0x0d, 0xb1, 0x56, 0xe8, 0x6c, 0xc9, 0xf6, 0x7a, 0x2d, 0xa1, 0x75, 0x21, 0xff, 0xc9, 0x13, 0x68,
0xab, 0x81, 0x67, 0x01, 0xe7, 0x6e, 0xa8, 0x0b, 0x09, 0x92, 0x1e, 0xfa, 0xa5, 0x94, 0x58, 0xad,
0x69, 0xd2, 0x31, 0xff, 0x08, 0x46, 0x3c, 0x2d, 0xf9, 0x00, 0x0c, 0x8f, 0xae, 0x75, 0x39, 0x8b,
0x6b, 0xab, 0x59, 0x4d, 0x8f, 0xae, 0x65, 0x29, 0x4b, 0xee, 0x43, 0x03, 0x85, 0x62, 0xad, 0xfc,
0x5d, 0xb3, 0xea, 0x1e, 0x5d, 0xbf, 0x5e, 0xc7, 0x82, 0x19, 0xe5, 0x51, 0xb1, 0xea, 0xd1, 0xf5,
0x4b, 0xca, 0xcd, 0xcf, 0xa0, 0xae, 0x16, 0xf9, 0xbd, 0x06, 0x46, 0xfd, 0x72, 0x46, 0xff, 0x57,
0xd0, 0x4a, 0xad, 0x9b, 0xfc, 0x1c, 0xee, 0x2a, 0x0b, 0x43, 0xba, 0x14, 0xd2, 0x23, 0x99, 0x01,
0x89, 0x14, 0x5e, 0xd0, 0xa5, 0xc0, 0x29, 0x55, 0xf9, 0xfd, 0x8f, 0x32, 0xd4, 0x55, 0x69, 0x4b,
0x3e, 0xc4, 0x32, 0x81, 0xba, 0xfe, 0xc4, 0x75, 0x54, 0x46, 0x1b, 0xb6, 0xbe, 0xbd, 0x79, 0xd8,
0x90, 0xec, 0x3f, 0x3e, 0xc7, 0xca, 0x00, 0x1b, 0x4e, 0x8a, 0x30, 0xcb, 0x99, 0xca, 0x9b, 0x40,
0x55, 0xb8, 0x1e, 0xd3, 0x26, 0xca, 0x36, 0xae, 0xdc, 0x5f, 0x79, 0xd2, 0x25, 0x55, 0xe5, 0x12,
0x7f, 0xe5, 0xa1, 0x4b, 0x5e, 0xc2, 0x76, 0x2a, 0xc1, 0xb9, 0x8e, 0x2e, 0xbc, 0x3a, 0xe9, 0xdd,
0x18, 0x9f, 0x0f, 0xf7, 0x31, 0xc8, 0xbe, 0xbd, 0x79, 0xd8, 0xfa, 0x4d, 0x94, 0xf2, 0xc6, 0xe7,
0x56, 0x2b, 0xce, 0x7f, 0x63, 0x87, 0xf4, 0x41, 0xa6, 0xc3, 0x89, 0x2a, 0x09, 0x54, 0x9a, 0x54,
0x99, 0xa0, 0x83, 0xdf, 0x75, 0xcd, 0x80, 0x95, 0xfd, 0x07, 0x60, 0x60, 0xd0, 0x29, 0x88, 0x4a,
0x0c, 0x4d, 0xfc, 0x20, 0x85, 0x1f, 0xc1, 0x4e, 0x92, 0xb3, 0x14, 0x44, 0x65, 0x89, 0x4e, 0xf2,
0x59, 0x02, 0x1f, 0x40, 0x33, 0x4e, 0xc7, 0x86, 0x44, 0x34, 0xa8, 0xce, 0xc2, 0x9f, 0x43, 0x43,
0x2f, 0xb1, 0xf0, 0x66, 0xf1, 0x33, 0xa8, 0xe1, 0xbe, 0x44, 0x87, 0x31, 0x2a, 0xf9, 0xe4, 0x7e,
0x30, 0x91, 0xb9, 0x5f, 0x28, 0xa0, 0x79, 0x02, 0xdb, 0x19, 0x29, 0x66, 0x30, 0x11, 0x08, 0xba,
0xd0, 0x1b, 0xaa, 0x3a, 0xf1, 0x64, 0xe5, 0x64, 0x32, 0xf3, 0x39, 0x18, 0x31, 0x61, 0xe0, 0x2e,
0x84, 0xab, 0xe9, 0x24, 0xba, 0x00, 0xb6, 0xad, 0x7a, 0xb8, 0x9a, 0xbe, 0x52, 0x79, 0x32, 0x0c,
0xbe, 0xd6, 0x77, 0x9d, 0x8a, 0xa5, 0x3a, 0xa6, 0x0d, 0xcd, 0xe8, 0x16, 0x22, 0x37, 0xf5, 0x3a,
0x64, 0x91, 0x21, 0xd8, 0x4e, 0x0f, 0x57, 0xce, 0x0c, 0xb7, 0xe9, 0x4e, 0x16, 0x45, 0x46, 0x35,
0x89, 0x8c, 0xe3, 0x6f, 0x6a, 0xb0, 0x73, 0x3a, 0x3c, 0x1b, 0x9f, 0x86, 0xe1, 0xc2, 0xb5, 0xa9,
0xac, 0x58, 0x06, 0x50, 0x95, 0x35, 0x59, 0xc1, 0x8b, 0x4a, 0xaf, 0xe8, 0x72, 0x40, 0x8e, 0xa1,
0x26, 0x4b, 0x33, 0x52, 0xf4, 0xb0, 0xd2, 0x2b, 0xbc, 0x23, 0xe0, 0x24, 0xaa, 0x78, 0xbb, 0xfd,
0xbe, 0xd2, 0x2b, 0xba, 0x28, 0x90, 0xcf, 0xc0, 0x48, 0x8a, 0xaa, 0x4d, 0xaf, 0x2c, 0xbd, 0x8d,
0x57, 0x06, 0xd4, 0x4f, 0x72, 0xdd, 0xa6, 0x37, 0x89, 0xde, 0xc6, 0xda, 0x9a, 0x3c, 0x83, 0x46,
0x54, 0x2d, 0x14, 0xbf, 0x83, 0xf4, 0x36, 0x94, 0xf3, 0xe8, 0x1e, 0x55, 0x71, 0x15, 0x3d, 0xd6,
0xf4, 0x0a, 0xef, 0x1c, 0xe4, 0x09, 0xd4, 0x35, 0x61, 0x17, 0xbe, 0x68, 0xf4, 0x8a, 0x8b, 0x72,
0x34, 0x32, 0x29, 0x15, 0x37, 0x3d, 0x28, 0xf5, 0x36, 0x5e, 0x8e, 0xc8, 0x29, 0x40, 0xaa, 0xca,
0xda, 0xf8, 0x52, 0xd4, 0xdb, 0x7c, 0xe9, 0x21, 0x9f, 0x42, 0x33, 0xb9, 0xc8, 0x16, 0xbf, 0xe0,
0xf4, 0x36, 0xdd, 0x43, 0xa6, 0x75, 0xf9, 0xca, 0xf7, 0xc9, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
0x0e, 0x79, 0xb0, 0x4d, 0x61, 0x14, 0x00, 0x00,
// 1789 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4b, 0x73, 0x1c, 0x49,
0x11, 0xd6, 0xbc, 0xa7, 0x53, 0x4f, 0x97, 0xfc, 0x18, 0xcf, 0x06, 0x61, 0x47, 0x43, 0x18, 0x99,
0xd5, 0x6a, 0x40, 0x8b, 0x8d, 0xbd, 0x4b, 0x6c, 0x20, 0x69, 0xcd, 0x8e, 0xc2, 0x3c, 0x44, 0xdb,
0x6b, 0x22, 0xb8, 0x4c, 0xd4, 0x4c, 0x97, 0x7a, 0x2a, 0x3c, 0xd3, 0xdd, 0xdb, 0x55, 0xa3, 0x9d,
0xf1, 0x8d, 0xe0, 0xba, 0x77, 0xce, 0xdc, 0xf8, 0x03, 0xfc, 0x05, 0x82, 0x7f, 0xc0, 0xcd, 0x07,
0xb8, 0xf1, 0x27, 0x20, 0x32, 0xab, 0xdf, 0xea, 0x59, 0x16, 0x73, 0xdc, 0x8b, 0x54, 0x59, 0x99,
0x59, 0x9d, 0x99, 0x93, 0xf9, 0x65, 0x56, 0xc1, 0x0d, 0xbd, 0x0a, 0x85, 0x1a, 0xd0, 0xdf, 0xa3,
0x30, 0x0a, 0x74, 0xc0, 0x5a, 0x44, 0xf4, 0x3f, 0xf0, 0xa4, 0x9e, 0x2e, 0xc6, 0x47, 0x93, 0x60,
0x3e, 0xf0, 0x02, 0x2f, 0x18, 0x10, 0x77, 0xbc, 0xb8, 0x24, 0x8a, 0x08, 0x5a, 0x19, 0xad, 0xfe,
0x20, 0x27, 0xae, 0x85, 0xef, 0x8a, 0x68, 0x2e, 0x7d, 0x3d, 0xd0, 0xf3, 0x99, 0x1c, 0xab, 0xc1,
0x24, 0x98, 0xcf, 0x03, 0x3f, 0xff, 0x19, 0xfb, 0xaf, 0x4d, 0xe8, 0x38, 0xe2, 0x8b, 0x85, 0x50,
0x9a, 0x1d, 0x40, 0x53, 0x4c, 0xa6, 0x41, 0xaf, 0x7e, 0xbf, 0x76, 0xb0, 0x79, 0xcc, 0x8e, 0x8c,
0x5c, 0xcc, 0x7d, 0x36, 0x99, 0x06, 0xc3, 0x0d, 0x87, 0x24, 0xd8, 0xfb, 0xd0, 0xba, 0x9c, 0x2d,
0xd4, 0xb4, 0xd7, 0x20, 0xd1, 0xfd, 0xa2, 0xe8, 0xcf, 0x91, 0x35, 0xdc, 0x70, 0x8c, 0x0c, 0x1e,
0x2b, 0xfd, 0xcb, 0xa0, 0xd7, 0xac, 0x3a, 0xf6, 0xdc, 0xbf, 0xa4, 0x63, 0x51, 0x82, 0x3d, 0x01,
0x50, 0x42, 0x8f, 0x82, 0x50, 0xcb, 0xc0, 0xef, 0xb5, 0x48, 0xfe, 0x4e, 0x51, 0xfe, 0x85, 0xd0,
0xbf, 0x26, 0xf6, 0x70, 0xc3, 0xb1, 0x54, 0x42, 0xa0, 0xa6, 0xf4, 0xa5, 0x1e, 0x4d, 0xa6, 0x5c,
0xfa, 0xbd, 0x76, 0x95, 0xe6, 0xb9, 0x2f, 0xf5, 0x19, 0xb2, 0x51, 0x53, 0x26, 0x04, 0xba, 0xf2,
0xc5, 0x42, 0x44, 0xab, 0x5e, 0xa7, 0xca, 0x95, 0xdf, 0x20, 0x0b, 0x5d, 0x21, 0x19, 0xf6, 0x31,
0x6c, 0x8e, 0x85, 0x27, 0xfd, 0xd1, 0x78, 0x16, 0x4c, 0x5e, 0xf7, 0xba, 0xa4, 0xd2, 0x2b, 0xaa,
0x9c, 0xa2, 0xc0, 0x29, 0xf2, 0x87, 0x1b, 0x0e, 0x8c, 0x53, 0x8a, 0x1d, 0x43, 0x77, 0x32, 0x15,
0x93, 0xd7, 0x23, 0xbd, 0xec, 0x59, 0xa4, 0x79, 0xab, 0xa8, 0x79, 0x86, 0xdc, 0x97, 0xcb, 0xe1,
0x86, 0xd3, 0x99, 0x98, 0x25, 0xfa, 0xe5, 0x8a, 0x99, 0xbc, 0x12, 0x11, 0x6a, 0xed, 0x57, 0xf9,
0xf5, 0xa9, 0xe1, 0x93, 0x9e, 0xe5, 0x26, 0x04, 0x7b, 0x04, 0x96, 0xf0, 0xdd, 0xd8, 0xd0, 0x4d,
0x52, 0xbc, 0x5d, 0xfa, 0x45, 0x7d, 0x37, 0x31, 0xb3, 0x2b, 0xe2, 0x35, 0x3b, 0x82, 0x36, 0x66,
0x89, 0xd4, 0xbd, 0x2d, 0xd2, 0xb9, 0x59, 0x32, 0x91, 0x78, 0xc3, 0x0d, 0x27, 0x96, 0x3a, 0xed,
0x40, 0xeb, 0x8a, 0xcf, 0x16, 0xc2, 0xfe, 0x3e, 0x6c, 0xe6, 0x32, 0x85, 0xf5, 0xa0, 0x33, 0x17,
0x4a, 0x71, 0x4f, 0xf4, 0x6a, 0xf7, 0x6b, 0x07, 0x96, 0x93, 0x90, 0xf6, 0x0e, 0x6c, 0xe5, 0xf3,
0x24, 0xa7, 0x88, 0xb9, 0x80, 0x8a, 0x57, 0x22, 0x52, 0x98, 0x00, 0xb1, 0x62, 0x4c, 0xda, 0x1f,
0xc1, 0x5e, 0x39, 0x09, 0xd8, 0x1e, 0x34, 0x5e, 0x8b, 0x55, 0x2c, 0x89, 0x4b, 0x76, 0x33, 0x36,
0x88, 0xb2, 0xd8, 0x72, 0x62, 0xeb, 0x82, 0x54, 0x37, 0x4d, 0x03, 0xf6, 0x18, 0xe0, 0x8a, 0xcf,
0xa4, 0xcb, 0x75, 0x10, 0xa9, 0x5e, 0xed, 0x7e, 0xe3, 0x60, 0xf3, 0x78, 0x2f, 0x76, 0xf7, 0x55,
0xc2, 0x38, 0x6d, 0xfe, 0xed, 0xed, 0xbd, 0x0d, 0x27, 0x27, 0xc9, 0xbe, 0x0b, 0xdb, 0x9e, 0xf0,
0x85, 0x92, 0x6a, 0x34, 0x5e, 0x69, 0xa1, 0xe8, 0x4b, 0x5b, 0xce, 0x56, 0xbc, 0x79, 0x8a, 0x7b,
0xb6, 0x9b, 0x7a, 0x49, 0x29, 0xc4, 0x18, 0x34, 0x5d, 0xae, 0x39, 0x59, 0xba, 0xe5, 0xd0, 0x1a,
0xf7, 0x42, 0xae, 0xa7, 0xb1, 0xa5, 0xb4, 0x66, 0xb7, 0xa1, 0x3d, 0x15, 0xd2, 0x9b, 0x6a, 0x2a,
0xad, 0x86, 0x13, 0x53, 0xe8, 0x56, 0x18, 0x05, 0x57, 0x82, 0xaa, 0xa8, 0xeb, 0x18, 0xc2, 0xfe,
0x7b, 0x0d, 0x6e, 0x5c, 0x4b, 0x3b, 0x3c, 0x77, 0xca, 0xd5, 0x34, 0xf9, 0x16, 0xae, 0xd9, 0xfb,
0x78, 0x2e, 0x77, 0x45, 0x14, 0x57, 0xf7, 0x76, 0xec, 0xe8, 0x90, 0x36, 0x63, 0x2f, 0x63, 0x11,
0xf6, 0x93, 0x42, 0x64, 0x1a, 0x14, 0x99, 0x24, 0xeb, 0x5e, 0x48, 0xcf, 0x97, 0xbe, 0x97, 0x06,
0xa8, 0x10, 0x9a, 0x21, 0xdc, 0x1c, 0xaf, 0xde, 0x70, 0x5f, 0x4b, 0x5f, 0x8c, 0x72, 0x47, 0x34,
0xe9, 0x88, 0xdd, 0xf8, 0x88, 0x67, 0x57, 0xd2, 0x15, 0xfe, 0x44, 0xc4, 0x5f, 0xdd, 0x4f, 0x55,
0xd2, 0x43, 0x95, 0x7d, 0x1f, 0x76, 0x8a, 0x55, 0xc1, 0x76, 0xa0, 0xae, 0x97, 0xb1, 0x4f, 0x75,
0xbd, 0xb4, 0xed, 0xf4, 0x27, 0x4d, 0x2b, 0xe0, 0x9a, 0xcc, 0x43, 0xd8, 0x2d, 0x25, 0x7b, 0x2e,
0xc0, 0xb5, 0x7c, 0x80, 0xed, 0x5d, 0xd8, 0x2e, 0xe4, 0xb8, 0xfd, 0x55, 0x0b, 0xba, 0x8e, 0x50,
0x61, 0xe0, 0x2b, 0xc1, 0x9e, 0x80, 0x25, 0x96, 0x13, 0x61, 0x80, 0xa9, 0x56, 0x2a, 0x7b, 0x23,
0xf3, 0x2c, 0xe1, 0x63, 0x1d, 0xa6, 0xc2, 0xec, 0x61, 0x01, 0x54, 0xf7, 0xcb, 0x4a, 0x79, 0x54,
0x3d, 0x2c, 0xa2, 0xea, 0xcd, 0x92, 0x6c, 0x09, 0x56, 0x1f, 0x16, 0x60, 0xb5, 0x7c, 0x70, 0x01,
0x57, 0x9f, 0x56, 0xe0, 0x6a, 0xd9, 0xfc, 0x35, 0xc0, 0xfa, 0xb4, 0x02, 0x58, 0x7b, 0xd7, 0xbe,
0x55, 0x89, 0xac, 0x87, 0x45, 0x64, 0x2d, 0xbb, 0x53, 0x82, 0xd6, 0x9f, 0x56, 0x41, 0xeb, 0xdd,
0x92, 0xce, 0x5a, 0x6c, 0xfd, 0xf0, 0x1a, 0xb6, 0xde, 0x2e, 0xa9, 0x56, 0x80, 0xeb, 0xd3, 0x02,
0xb8, 0x42, 0xa5, 0x6f, 0x6b, 0xd0, 0xf5, 0xf1, 0x75, 0x74, 0xbd, 0x53, 0xfe, 0x69, 0xab, 0xe0,
0x75, 0x50, 0x82, 0xd7, 0x5b, 0x65, 0x2b, 0xd7, 0xe2, 0xeb, 0x43, 0xac, 0xf4, 0x52, 0xa6, 0x21,
0x2a, 0x88, 0x28, 0x0a, 0xa2, 0x18, 0x00, 0x0d, 0x61, 0x1f, 0x20, 0xf6, 0x64, 0xf9, 0xf5, 0x35,
0x58, 0x4c, 0x49, 0x9f, 0xcb, 0x2e, 0xfb, 0x8f, 0xb5, 0x4c, 0x97, 0xe0, 0x38, 0x8f, 0x5b, 0x56,
0x8c, 0x5b, 0x39, 0x88, 0xae, 0x17, 0x20, 0x9a, 0xfd, 0x00, 0x6e, 0xcc, 0xb8, 0xd2, 0x26, 0x2e,
0xa3, 0x02, 0x90, 0xed, 0x22, 0xc3, 0x04, 0xc4, 0x20, 0xda, 0x07, 0xb0, 0x9f, 0x93, 0xe5, 0x61,
0x38, 0x22, 0xd0, 0x6a, 0x52, 0xf1, 0xee, 0xa5, 0xd2, 0x27, 0x61, 0x38, 0xe4, 0x6a, 0x6a, 0xff,
0x32, 0xf3, 0x3f, 0x83, 0x7f, 0x06, 0xcd, 0x49, 0xe0, 0x1a, 0xb7, 0xb6, 0x1d, 0x5a, 0x63, 0x4b,
0x98, 0x05, 0x1e, 0x7d, 0xd5, 0x72, 0x70, 0x89, 0x52, 0x69, 0xa5, 0x58, 0xa6, 0x24, 0xec, 0xe7,
0xd9, 0x71, 0xff, 0x77, 0x47, 0xb0, 0xff, 0x52, 0xcb, 0xe2, 0x98, 0xc2, 0xfd, 0xbb, 0x19, 0x86,
0x3f, 0xa9, 0xf4, 0x5d, 0xb1, 0xa4, 0x32, 0x6d, 0x38, 0x86, 0x48, 0xfa, 0x5c, 0x9b, 0x82, 0x53,
0xec, 0x73, 0x1d, 0xda, 0x33, 0x44, 0xdc, 0x26, 0x82, 0x4b, 0xaa, 0x9f, 0x2d, 0xc7, 0x10, 0x39,
0xcc, 0xb3, 0x0a, 0x98, 0x77, 0x01, 0xec, 0x7a, 0x65, 0xb1, 0x8f, 0xa0, 0xa9, 0xb9, 0x97, 0xf8,
0xbf, 0x73, 0x64, 0xa6, 0xc6, 0xa3, 0xe7, 0xaf, 0x2e, 0xb8, 0x8c, 0x4e, 0x6f, 0xa3, 0xf7, 0xff,
0x7a, 0x7b, 0x6f, 0x07, 0x65, 0x0e, 0x83, 0xb9, 0xd4, 0x62, 0x1e, 0xea, 0x95, 0x43, 0x3a, 0xf6,
0xbf, 0x6b, 0x88, 0xb8, 0x85, 0x8a, 0xab, 0x8c, 0x45, 0x92, 0x56, 0xf5, 0x5c, 0x3b, 0xfc, 0x66,
0xf1, 0xf9, 0x0e, 0x80, 0xc7, 0xd5, 0xe8, 0x4b, 0xee, 0x6b, 0xe1, 0xc6, 0x41, 0xb2, 0x3c, 0xae,
0x7e, 0x4b, 0x1b, 0xec, 0x2e, 0x74, 0x91, 0xbd, 0x50, 0xc2, 0xa5, 0x68, 0x35, 0x9c, 0x8e, 0xc7,
0xd5, 0xe7, 0x4a, 0xb8, 0xa9, 0x5f, 0x9d, 0xff, 0xdd, 0x2f, 0x76, 0x00, 0x8d, 0x4b, 0x21, 0x62,
0x54, 0xda, 0x4b, 0x55, 0xcf, 0x1f, 0xff, 0x98, 0x94, 0x4d, 0x4a, 0xa0, 0x88, 0xfd, 0xfb, 0x7a,
0x96, 0x59, 0x59, 0x63, 0xfa, 0x76, 0xc5, 0xe0, 0x9f, 0x35, 0xec, 0xcd, 0x45, 0x18, 0x64, 0x67,
0x70, 0x23, 0x2d, 0x99, 0xd1, 0x22, 0x74, 0x39, 0x8e, 0x4e, 0x5f, 0x5f, 0x63, 0x7b, 0xa9, 0xc2,
0xe7, 0x46, 0x9e, 0xfd, 0x0a, 0xee, 0x4c, 0xf0, 0x54, 0x5f, 0x2d, 0xd4, 0x28, 0xe4, 0x11, 0x9f,
0xa7, 0x47, 0xd5, 0x0b, 0xb0, 0x7f, 0x96, 0x48, 0x5d, 0xa0, 0x90, 0x72, 0x6e, 0x4d, 0x0a, 0x1b,
0xc9, 0x79, 0x49, 0x3c, 0x1a, 0xef, 0x90, 0xeb, 0xdf, 0xc3, 0x11, 0x25, 0x0f, 0xdb, 0x55, 0xbf,
0xa8, 0xfd, 0xa7, 0x1a, 0xec, 0x96, 0x8c, 0x61, 0x03, 0x00, 0x83, 0x7a, 0x4a, 0xbe, 0x11, 0xf1,
0x38, 0x91, 0xc4, 0x80, 0x82, 0xf5, 0x42, 0xbe, 0x11, 0x8e, 0x35, 0x4e, 0x96, 0xec, 0x01, 0x74,
0xf4, 0xd2, 0x48, 0x17, 0xc7, 0xb7, 0x97, 0x4b, 0x12, 0x6d, 0x6b, 0xfa, 0xcf, 0x1e, 0xc1, 0x96,
0x39, 0xd8, 0x0b, 0x94, 0x92, 0x61, 0x3c, 0x48, 0xb0, 0xfc, 0xd1, 0x9f, 0x11, 0xc7, 0xd9, 0x1c,
0x67, 0x84, 0xfd, 0x3b, 0xb0, 0xd2, 0xcf, 0xb2, 0xf7, 0xc0, 0x9a, 0xf3, 0x65, 0x3c, 0xda, 0xa2,
0x6d, 0x2d, 0xa7, 0x3b, 0xe7, 0x4b, 0x1a, 0x6b, 0xd9, 0x1d, 0xe8, 0x20, 0x53, 0x2f, 0x4d, 0xbc,
0x5b, 0x4e, 0x7b, 0xce, 0x97, 0x2f, 0x97, 0x29, 0xc3, 0xe3, 0x2a, 0x19, 0x5c, 0xe7, 0x7c, 0xf9,
0x19, 0x57, 0xf6, 0x27, 0xd0, 0x36, 0x46, 0x7e, 0xa3, 0x83, 0x51, 0xbf, 0x5e, 0xd0, 0xff, 0x19,
0x6c, 0xe6, 0xec, 0x66, 0x3f, 0x82, 0x5b, 0xc6, 0xc3, 0x90, 0x47, 0x9a, 0x22, 0x52, 0x38, 0x90,
0x11, 0xf3, 0x82, 0x47, 0x1a, 0x3f, 0x69, 0x46, 0xf1, 0x3f, 0xd4, 0xa1, 0x6d, 0xc6, 0x5c, 0xf6,
0x00, 0xc7, 0x04, 0x2e, 0xfd, 0x91, 0x74, 0x4d, 0x47, 0x3b, 0xdd, 0xfc, 0xc7, 0xdb, 0x7b, 0x1d,
0x42, 0xff, 0xf3, 0x4f, 0x71, 0x32, 0xc0, 0x85, 0x9b, 0x03, 0xcc, 0x7a, 0x61, 0x0a, 0x67, 0xd0,
0xd4, 0x72, 0x2e, 0x62, 0x17, 0x69, 0x8d, 0x96, 0xfb, 0x8b, 0x39, 0x85, 0xa4, 0x69, 0x42, 0xe2,
0x2f, 0xe6, 0x18, 0x92, 0xf7, 0xc0, 0xd2, 0x81, 0xe6, 0x33, 0x62, 0x99, 0x22, 0xed, 0xd2, 0x06,
0x32, 0x1f, 0xc0, 0x6e, 0xbe, 0x53, 0x62, 0xe7, 0x33, 0xe0, 0xbe, 0x9d, 0xf5, 0x49, 0x9c, 0xdb,
0xef, 0x42, 0x37, 0x6d, 0x8d, 0x06, 0xe9, 0x3b, 0xdc, 0x74, 0x44, 0x76, 0x08, 0xdd, 0x30, 0x0a,
0xc2, 0x40, 0x89, 0x28, 0x2d, 0xca, 0x52, 0x1d, 0x39, 0xa9, 0x84, 0x2d, 0xc1, 0x4a, 0xb7, 0xb1,
0x83, 0x73, 0xd7, 0x8d, 0x84, 0x52, 0xf1, 0xb0, 0x9c, 0x90, 0xec, 0x10, 0x3a, 0xe1, 0x62, 0x3c,
0xc2, 0x66, 0x53, 0xcc, 0xb4, 0x8b, 0xc5, 0xf8, 0xb9, 0x58, 0x25, 0x17, 0x85, 0x90, 0x28, 0x6a,
0x37, 0xc1, 0x97, 0x22, 0x8a, 0x03, 0x62, 0x08, 0xdb, 0x87, 0xbd, 0xf2, 0x2d, 0x81, 0x1d, 0x81,
0x95, 0x16, 0x73, 0x29, 0xe3, 0x33, 0x6b, 0x33, 0x11, 0x9c, 0x24, 0x94, 0xf4, 0x7c, 0xe1, 0x8e,
0xb2, 0x30, 0x91, 0x45, 0x5d, 0x67, 0xd7, 0x30, 0x7e, 0x91, 0xc4, 0xc9, 0xfe, 0x21, 0xb4, 0x8d,
0x75, 0xf4, 0xfb, 0xac, 0xc2, 0x64, 0xcc, 0xa1, 0x75, 0x65, 0x51, 0xfe, 0xb9, 0x06, 0xdd, 0xe4,
0x16, 0x52, 0xa9, 0x54, 0x30, 0xb7, 0xfe, 0xdf, 0xcd, 0x5d, 0x77, 0x6d, 0x4b, 0x12, 0xa6, 0x99,
0x4b, 0x98, 0x43, 0x60, 0x26, 0x2f, 0xae, 0x02, 0x2d, 0x7d, 0x6f, 0x64, 0x22, 0x68, 0x12, 0x64,
0x8f, 0x38, 0xaf, 0x88, 0x71, 0x81, 0xfb, 0xc7, 0x5f, 0xb5, 0x60, 0xf7, 0xe4, 0xf4, 0xec, 0xfc,
0x24, 0x0c, 0x67, 0x72, 0xc2, 0x69, 0xec, 0x19, 0x40, 0x93, 0x06, 0xbb, 0x8a, 0x27, 0x9a, 0x7e,
0xd5, 0x0d, 0x83, 0x1d, 0x43, 0x8b, 0xe6, 0x3b, 0x56, 0xf5, 0x52, 0xd3, 0xaf, 0xbc, 0x68, 0xe0,
0x47, 0xcc, 0x04, 0x78, 0xfd, 0xc1, 0xa6, 0x5f, 0x75, 0xdb, 0x60, 0x9f, 0x80, 0x95, 0x4d, 0x66,
0xeb, 0x9e, 0x6d, 0xfa, 0x6b, 0xef, 0x1d, 0xa8, 0x9f, 0x35, 0xcc, 0x75, 0x8f, 0x1c, 0xfd, 0xb5,
0x03, 0x3a, 0x7b, 0x02, 0x9d, 0x64, 0xe4, 0xa8, 0x7e, 0x58, 0xe9, 0xaf, 0xb9, 0x13, 0x60, 0x78,
0xcc, 0xd8, 0x56, 0xf5, 0xfa, 0xd3, 0xaf, 0xbc, 0xb8, 0xb0, 0x47, 0xd0, 0x8e, 0x51, 0xbf, 0xf2,
0x89, 0xa4, 0x5f, 0x3d, 0xd9, 0xa3, 0x93, 0xd9, 0xbc, 0xb9, 0xee, 0x85, 0xaa, 0xbf, 0xf6, 0x86,
0xc5, 0x4e, 0x00, 0x72, 0xa3, 0xda, 0xda, 0xa7, 0xa7, 0xfe, 0xfa, 0x9b, 0x13, 0xfb, 0x18, 0xba,
0xd9, 0x6d, 0xb8, 0xfa, 0x49, 0xa8, 0xbf, 0xee, 0x32, 0x33, 0x6e, 0xd3, 0xb3, 0xe1, 0x87, 0xff,
0x09, 0x00, 0x00, 0xff, 0xff, 0x39, 0xa6, 0xae, 0x4d, 0xb2, 0x14, 0x00, 0x00,
}

+ 11
- 4
types/util.go View File

@ -4,6 +4,8 @@ import (
"bytes"
"encoding/json"
"sort"
cmn "github.com/tendermint/tmlibs/common"
)
//------------------------------------------------------------------------------
@ -25,7 +27,7 @@ func (v Validators) Len() int {
// XXX: doesn't distinguish same validator with different power
func (v Validators) Less(i, j int) bool {
return bytes.Compare(v[i].PubKey, v[j].PubKey) <= 0
return bytes.Compare(v[i].PubKey.Data, v[j].PubKey.Data) <= 0
}
func (v Validators) Swap(i, j int) {
@ -37,7 +39,11 @@ func (v Validators) Swap(i, j int) {
func ValidatorsString(vs Validators) string {
s := make([]validatorPretty, len(vs))
for i, v := range vs {
s[i] = validatorPretty(v)
s[i] = validatorPretty{
Address: v.Address,
PubKey: v.PubKey.Data,
Power: v.Power,
}
}
b, err := json.Marshal(s)
if err != nil {
@ -47,6 +53,7 @@ func ValidatorsString(vs Validators) string {
}
type validatorPretty struct {
PubKey []byte `json:"pub_key"`
Power int64 `json:"power"`
Address cmn.HexBytes `json:"address"`
PubKey []byte `json:"pub_key"`
Power int64 `json:"power"`
}

Loading…
Cancel
Save