From 459ee59e461fe201cdc3b66fa5423a3037f1c1c3 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 20 May 2018 16:15:58 -0400 Subject: [PATCH 1/5] Request/ResponseValidator, update Header --- types/types.proto | 51 ++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/types/types.proto b/types/types.proto index 00777dcfb..2fe8ea7b4 100644 --- a/types/types.proto +++ b/types/types.proto @@ -47,7 +47,7 @@ message RequestSetOption { } message RequestInitChain { - repeated Validator validators = 1 [(gogoproto.nullable)=false]; + repeated RequestValidator validators = 1 [(gogoproto.nullable)=false]; bytes genesis_bytes = 2; } @@ -61,8 +61,9 @@ message RequestQuery { message RequestBeginBlock { bytes hash = 1; Header header = 2 [(gogoproto.nullable)=false]; - repeated bytes absent_validators = 3; - repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; + repeated RequestValidator present_validators = 3; + repeated RequestValidator absent_validators = 4; + repeated Evidence byzantine_validators = 5 [(gogoproto.nullable)=false]; } message RequestCheckTx { @@ -128,7 +129,7 @@ message ResponseSetOption { } message ResponseInitChain { - repeated Validator validators = 1 [(gogoproto.nullable)=false]; + repeated ResponseValidator validators = 1 [(gogoproto.nullable)=false]; } message ResponseQuery { @@ -170,7 +171,7 @@ message ResponseDeliverTx { } message ResponseEndBlock { - repeated Validator validator_updates = 1 [(gogoproto.nullable)=false]; + repeated ResponseValidator validator_updates = 1 [(gogoproto.nullable)=false]; ConsensusParams consensus_param_updates = 2; repeated common.KVPair tags = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"]; } @@ -214,36 +215,44 @@ message BlockGossip { //---------------------------------------- // Blockchain Types +// just the minimum the app might need message Header { + // basics string chain_id = 1 [(gogoproto.customname)="ChainID"]; int64 height = 2; int64 time = 3; + + // txs int32 num_txs = 4; - BlockID last_block_id = 5 [(gogoproto.customname)="LastBlockID", (gogoproto.nullable)=false]; - bytes last_commit_hash = 6; - bytes data_hash = 7; - bytes validators_hash = 8; - bytes app_hash = 9; + int64 total_txs = 5; + + // hashes + bytes last_block_hash = 6; + bytes app_hash = 7; } -message BlockID { - bytes hash = 1; - PartSetHeader parts = 2 [(gogoproto.nullable)=false]; +// Validator for use in responses +message ResponseValidator { + PubKey pub_key = 1; + int64 power = 2; } -message PartSetHeader { - int32 total = 1; - bytes hash = 2; +// Validator for use in requests +message RequestValidator { + bytes address = 1; + int32 index = 2; + PubKey pub_key = 3; + int64 power = 4; } -message Validator { - bytes pub_key = 1; - int64 power = 2; +message PubKey { + string type = 1; + bytes data = 2; } message Evidence { - bytes type = 1; - bytes pub_key = 2; + string type = 1; + RequestValidator validator = 2; int64 height = 3; int64 time = 4; } From 31576150ad183e7e480bc61bf6c1e96b464b395e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 20 May 2018 16:24:21 -0400 Subject: [PATCH 2/5] add total_voting_power to evidence --- types/types.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/types/types.proto b/types/types.proto index 2fe8ea7b4..d1f27eae3 100644 --- a/types/types.proto +++ b/types/types.proto @@ -255,6 +255,7 @@ message Evidence { RequestValidator validator = 2; int64 height = 3; int64 time = 4; + int64 total_voting_power = 5; } //---------------------------------------- From efbc2efb425ba1dc8dd1b5b1da4a4246d515af3e Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sun, 20 May 2018 16:25:48 -0400 Subject: [PATCH 3/5] add proposer to header --- types/types.proto | 3 +++ 1 file changed, 3 insertions(+) diff --git a/types/types.proto b/types/types.proto index d1f27eae3..20101305b 100644 --- a/types/types.proto +++ b/types/types.proto @@ -229,6 +229,9 @@ message Header { // hashes bytes last_block_hash = 6; bytes app_hash = 7; + + // consensus + RequestValidator proposer = 8; } // Validator for use in responses From 8bb04d7ef7d03165e397fc89db7a8b9662e6b4a1 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 23 May 2018 22:20:24 -0400 Subject: [PATCH 4/5] Validator and SignedValidator --- types/types.proto | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/types/types.proto b/types/types.proto index 20101305b..2cea82d0d 100644 --- a/types/types.proto +++ b/types/types.proto @@ -47,7 +47,7 @@ message RequestSetOption { } message RequestInitChain { - repeated RequestValidator validators = 1 [(gogoproto.nullable)=false]; + repeated Validator validators = 1 [(gogoproto.nullable)=false]; bytes genesis_bytes = 2; } @@ -61,9 +61,8 @@ message RequestQuery { message RequestBeginBlock { bytes hash = 1; Header header = 2 [(gogoproto.nullable)=false]; - repeated RequestValidator present_validators = 3; - repeated RequestValidator absent_validators = 4; - repeated Evidence byzantine_validators = 5 [(gogoproto.nullable)=false]; + repeated SigningValidator validators = 3; + repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; } message RequestCheckTx { @@ -129,7 +128,7 @@ message ResponseSetOption { } message ResponseInitChain { - repeated ResponseValidator validators = 1 [(gogoproto.nullable)=false]; + repeated Validator validators = 1 [(gogoproto.nullable)=false]; } message ResponseQuery { @@ -171,7 +170,7 @@ message ResponseDeliverTx { } message ResponseEndBlock { - repeated ResponseValidator validator_updates = 1 [(gogoproto.nullable)=false]; + repeated Validator validator_updates = 1 [(gogoproto.nullable)=false]; ConsensusParams consensus_param_updates = 2; repeated common.KVPair tags = 3 [(gogoproto.nullable)=false, (gogoproto.jsontag)="tags,omitempty"]; } @@ -231,21 +230,20 @@ message Header { bytes app_hash = 7; // consensus - RequestValidator proposer = 8; + Validator proposer = 8; } -// Validator for use in responses -message ResponseValidator { - PubKey pub_key = 1; - int64 power = 2; +// Validator +message Validator { + bytes address = 1; + PubKey pub_key = 2 [(gogoproto.nullable)=false]; + int64 power = 3; } -// Validator for use in requests -message RequestValidator { - bytes address = 1; - int32 index = 2; - PubKey pub_key = 3; - int64 power = 4; +// Validator with an extra bool +message SigningValidator { + Validator validator = 1; + bool signed_last_block = 2; } message PubKey { @@ -255,7 +253,7 @@ message PubKey { message Evidence { string type = 1; - RequestValidator validator = 2; + Validator validator = 2; int64 height = 3; int64 time = 4; int64 total_voting_power = 5; From 3dbdc87edba1028d52e1624aba5e1497bedc7d72 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 23 May 2018 22:20:35 -0400 Subject: [PATCH 5/5] protoc and update everything --- Makefile | 3 - example/dummy/README.md | 4 - example/dummy/helpers.go | 36 --- example/dummy/kvstore.go | 126 -------- example/dummy/kvstore_test.go | 310 -------------------- example/dummy/persistent_kvstore.go | 205 ------------- example/kvstore/helpers.go | 7 +- example/kvstore/kvstore_test.go | 2 +- example/kvstore/persistent_kvstore.go | 19 +- tests/server/client.go | 2 +- types/pubkey.go | 16 + types/types.pb.go | 401 +++++++++++++------------- types/util.go | 15 +- 13 files changed, 249 insertions(+), 897 deletions(-) delete mode 100644 example/dummy/README.md delete mode 100644 example/dummy/helpers.go delete mode 100644 example/dummy/kvstore.go delete mode 100644 example/dummy/kvstore_test.go delete mode 100644 example/dummy/persistent_kvstore.go create mode 100644 types/pubkey.go diff --git a/Makefile b/Makefile index 13a9547ce..d5aa5365a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/example/dummy/README.md b/example/dummy/README.md deleted file mode 100644 index fe9d1c2db..000000000 --- a/example/dummy/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Dummy - -DEPRECATED. See KVStore - diff --git a/example/dummy/helpers.go b/example/dummy/helpers.go deleted file mode 100644 index 1dc1e235b..000000000 --- a/example/dummy/helpers.go +++ /dev/null @@ -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("[]"), - }) -} diff --git a/example/dummy/kvstore.go b/example/dummy/kvstore.go deleted file mode 100644 index 79aa43978..000000000 --- a/example/dummy/kvstore.go +++ /dev/null @@ -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 - } -} diff --git a/example/dummy/kvstore_test.go b/example/dummy/kvstore_test.go deleted file mode 100644 index 548fe7422..000000000 --- a/example/dummy/kvstore_test.go +++ /dev/null @@ -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)) -} diff --git a/example/dummy/persistent_kvstore.go b/example/dummy/persistent_kvstore.go deleted file mode 100644 index 30885bc1e..000000000 --- a/example/dummy/persistent_kvstore.go +++ /dev/null @@ -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} -} diff --git a/example/kvstore/helpers.go b/example/kvstore/helpers.go index cbb8b6c50..da826fe65 100644 --- a/example/kvstore/helpers.go +++ b/example/kvstore/helpers.go @@ -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 diff --git a/example/kvstore/kvstore_test.go b/example/kvstore/kvstore_test.go index b3d29ffb0..ff3e49208 100644 --- a/example/kvstore/kvstore_test.go +++ b/example/kvstore/kvstore_test.go @@ -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) } diff --git a/example/kvstore/persistent_kvstore.go b/example/kvstore/persistent_kvstore.go index 888258ff5..02f7ce74a 100644 --- a/example/kvstore/persistent_kvstore.go +++ b/example/kvstore/persistent_kvstore.go @@ -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) { diff --git a/tests/server/client.go b/tests/server/client.go index 2516b9fda..14b4007a1 100644 --- a/tests/server/client.go +++ b/tests/server/client.go @@ -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, diff --git a/types/pubkey.go b/types/pubkey.go new file mode 100644 index 000000000..e5cd5fbf3 --- /dev/null +++ b/types/pubkey.go @@ -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, + } +} diff --git a/types/types.pb.go b/types/types.pb.go index 23b425530..e04a4f4bf 100644 --- a/types/types.pb.go +++ b/types/types.pb.go @@ -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, } diff --git a/types/util.go b/types/util.go index da5bc7261..0924ab5ff 100644 --- a/types/util.go +++ b/types/util.go @@ -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"` }