mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-29 06:01:21 +00:00
commit
f4e97a5db1
@ -2,7 +2,6 @@ package counter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/tmsp/types"
|
"github.com/tendermint/tmsp/types"
|
||||||
@ -35,11 +34,7 @@ func (app *CounterApplication) AppendTx(tx []byte) types.Result {
|
|||||||
copy(tx8[len(tx8)-len(tx):], tx)
|
copy(tx8[len(tx8)-len(tx):], tx)
|
||||||
txValue := binary.BigEndian.Uint64(tx8)
|
txValue := binary.BigEndian.Uint64(tx8)
|
||||||
if txValue != uint64(app.txCount) {
|
if txValue != uint64(app.txCount) {
|
||||||
return types.Result{
|
return types.ErrBadNonce.SetLog(Fmt("Invalid nonce. Expected %v, got %v", app.txCount, txValue))
|
||||||
Code: types.CodeType_BadNonce,
|
|
||||||
Data: nil,
|
|
||||||
Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.txCount += 1
|
app.txCount += 1
|
||||||
@ -52,11 +47,7 @@ func (app *CounterApplication) CheckTx(tx []byte) types.Result {
|
|||||||
copy(tx8[len(tx8)-len(tx):], tx)
|
copy(tx8[len(tx8)-len(tx):], tx)
|
||||||
txValue := binary.BigEndian.Uint64(tx8)
|
txValue := binary.BigEndian.Uint64(tx8)
|
||||||
if txValue < uint64(app.txCount) {
|
if txValue < uint64(app.txCount) {
|
||||||
return types.Result{
|
return types.ErrBadNonce.SetLog(Fmt("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue))
|
||||||
Code: types.CodeType_BadNonce,
|
|
||||||
Data: nil,
|
|
||||||
Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return types.OK
|
return types.OK
|
||||||
@ -75,5 +66,5 @@ func (app *CounterApplication) Commit() types.Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *CounterApplication) Query(query []byte) types.Result {
|
func (app *CounterApplication) Query(query []byte) types.Result {
|
||||||
return types.NewResultOK(nil, fmt.Sprintf("Query is not supported"))
|
return types.NewResultOK(nil, Fmt("Query is not supported"))
|
||||||
}
|
}
|
||||||
|
31
example/dummy/README.md
Normal file
31
example/dummy/README.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# Dummy
|
||||||
|
|
||||||
|
There are two app's here: the DummyApplication and the PersistentDummyApplication.
|
||||||
|
|
||||||
|
## DummyApplication
|
||||||
|
|
||||||
|
The DummyApplication is a simple merkle key-value store.
|
||||||
|
Transactions of the form `key=value` are stored as key-value pairs in the tree.
|
||||||
|
Transactions without an `=` sign set the value to the key.
|
||||||
|
The app has no replay protection (other than what the mempool provides).
|
||||||
|
|
||||||
|
## PersistentDummyApplication
|
||||||
|
|
||||||
|
The PersistentDummyApplication wraps the DummyApplication
|
||||||
|
and provides two additional features:
|
||||||
|
|
||||||
|
1) persistence of state across app restarts (using Tendermint's TMSP-Handshake mechanism)
|
||||||
|
2) validator set changes
|
||||||
|
|
||||||
|
The state is persisted in leveldb along with the last block committed,
|
||||||
|
and the Handshake allows any necessary blocks to be replayed.
|
||||||
|
Validator set changes are effected using the following transaction format:
|
||||||
|
|
||||||
|
```
|
||||||
|
val:pubkey1/power1,addr2/power2,addr3/power3"
|
||||||
|
```
|
||||||
|
|
||||||
|
where `power1` is the new voting power for the validator with `pubkey1` (possibly a new one).
|
||||||
|
There is no sybil protection against new validators joining.
|
||||||
|
Validators can be removed by setting their power to `0`.
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/go-merkle"
|
"github.com/tendermint/go-merkle"
|
||||||
|
"github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/tmsp/types"
|
"github.com/tendermint/tmsp/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,10 +14,7 @@ type DummyApplication struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewDummyApplication() *DummyApplication {
|
func NewDummyApplication() *DummyApplication {
|
||||||
state := merkle.NewIAVLTree(
|
state := merkle.NewIAVLTree(0, ".", nil)
|
||||||
0,
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
return &DummyApplication{state: state}
|
return &DummyApplication{state: state}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +49,12 @@ func (app *DummyApplication) Commit() types.Result {
|
|||||||
func (app *DummyApplication) Query(query []byte) types.Result {
|
func (app *DummyApplication) Query(query []byte) types.Result {
|
||||||
index, value, exists := app.state.Get(query)
|
index, value, exists := app.state.Get(query)
|
||||||
|
|
||||||
resStr := Fmt("Index=%v value=%v exists=%v", index, string(value), exists)
|
queryResult := QueryResult{index, string(value), exists}
|
||||||
return types.NewResultOK([]byte(resStr), "")
|
return types.NewResultOK(wire.JSONBytes(queryResult), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryResult struct {
|
||||||
|
Index int `json:"index"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
Exists bool `json:"exists"`
|
||||||
}
|
}
|
||||||
|
203
example/dummy/dummy_test.go
Normal file
203
example/dummy/dummy_test.go
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
package dummy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
. "github.com/tendermint/go-common"
|
||||||
|
"github.com/tendermint/go-crypto"
|
||||||
|
"github.com/tendermint/go-wire"
|
||||||
|
"github.com/tendermint/tmsp/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testDummy(t *testing.T, dummy types.Application, tx []byte, key, value string) {
|
||||||
|
if r := dummy.AppendTx(tx); r.IsErr() {
|
||||||
|
t.Fatal(r)
|
||||||
|
}
|
||||||
|
if r := dummy.AppendTx(tx); r.IsErr() {
|
||||||
|
t.Fatal(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := dummy.Query([]byte(key))
|
||||||
|
if r.IsErr() {
|
||||||
|
t.Fatal(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
q := new(QueryResult)
|
||||||
|
if err := wire.ReadJSONBytes(r.Data, q); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if q.Value != value {
|
||||||
|
t.Fatalf("Got %s, expected %s", q.Value, 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", "tmsp-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", "tmsp-dummy-test") // TODO
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
dummy := NewPersistentDummyApplication(dir)
|
||||||
|
height := uint64(0)
|
||||||
|
|
||||||
|
_, _, lastBlockInfo, _ := dummy.Info()
|
||||||
|
if lastBlockInfo.BlockHeight != height {
|
||||||
|
t.Fatalf("expected height of %d, got %d", height, lastBlockInfo.BlockHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make and apply block
|
||||||
|
height = uint64(1)
|
||||||
|
hash := []byte("foo")
|
||||||
|
header := &types.Header{
|
||||||
|
Height: uint64(height),
|
||||||
|
}
|
||||||
|
dummy.BeginBlock(hash, header)
|
||||||
|
dummy.EndBlock(height)
|
||||||
|
dummy.Commit()
|
||||||
|
|
||||||
|
_, _, lastBlockInfo, _ = dummy.Info()
|
||||||
|
if lastBlockInfo.BlockHeight != height {
|
||||||
|
t.Fatalf("expected height of %d, got %d", height, lastBlockInfo.BlockHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a validator, remove a validator, update a validator
|
||||||
|
func TestValSetChanges(t *testing.T) {
|
||||||
|
dir, err := ioutil.TempDir("/tmp", "tmsp-dummy-test") // TODO
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
dummy := NewPersistentDummyApplication(dir)
|
||||||
|
|
||||||
|
// init with some validators
|
||||||
|
total := 10
|
||||||
|
nInit := 5
|
||||||
|
vals := make([]*types.Validator, total)
|
||||||
|
for i := 0; i < total; i++ {
|
||||||
|
pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(Fmt("test%d", i))).PubKey().Bytes()
|
||||||
|
power := RandInt()
|
||||||
|
vals[i] = &types.Validator{pubkey, uint64(power)}
|
||||||
|
}
|
||||||
|
// iniitalize with the first nInit
|
||||||
|
dummy.InitChain(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:len(vals1)]...)
|
||||||
|
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 := uint64(heightInt)
|
||||||
|
hash := []byte("foo")
|
||||||
|
header := &types.Header{
|
||||||
|
Height: height,
|
||||||
|
}
|
||||||
|
|
||||||
|
dummyChain := dummy.(types.BlockchainAware) // hmm...
|
||||||
|
dummyChain.BeginBlock(hash, header)
|
||||||
|
for _, tx := range txs {
|
||||||
|
if r := dummy.AppendTx(tx); r.IsErr() {
|
||||||
|
t.Fatal(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff2 := dummyChain.EndBlock(height)
|
||||||
|
dummy.Commit()
|
||||||
|
|
||||||
|
valsEqual(t, diff, diff2)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,9 @@ package dummy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/tendermint/go-common"
|
. "github.com/tendermint/go-common"
|
||||||
dbm "github.com/tendermint/go-db"
|
dbm "github.com/tendermint/go-db"
|
||||||
@ -10,6 +13,10 @@ import (
|
|||||||
"github.com/tendermint/tmsp/types"
|
"github.com/tendermint/tmsp/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ValidatorSetChangePrefix string = "val:"
|
||||||
|
)
|
||||||
|
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
|
|
||||||
type PersistentDummyApplication struct {
|
type PersistentDummyApplication struct {
|
||||||
@ -17,18 +24,19 @@ type PersistentDummyApplication struct {
|
|||||||
db dbm.DB
|
db dbm.DB
|
||||||
|
|
||||||
// latest received
|
// latest received
|
||||||
|
// TODO: move to merkle tree?
|
||||||
blockHash []byte
|
blockHash []byte
|
||||||
blockHeader *types.Header
|
blockHeader *types.Header
|
||||||
|
|
||||||
|
// validator set
|
||||||
|
changes []*types.Validator
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPersistentDummyApplication(dbDir string) *PersistentDummyApplication {
|
func NewPersistentDummyApplication(dbDir string) *PersistentDummyApplication {
|
||||||
db := dbm.NewDB("dummy", "leveldb", dbDir)
|
db := dbm.NewDB("dummy", "leveldb", dbDir)
|
||||||
lastBlock := LoadLastBlock(db)
|
lastBlock := LoadLastBlock(db)
|
||||||
|
|
||||||
stateTree := merkle.NewIAVLTree(
|
stateTree := merkle.NewIAVLTree(0, ".", db)
|
||||||
0,
|
|
||||||
db,
|
|
||||||
)
|
|
||||||
stateTree.Load(lastBlock.AppHash)
|
stateTree.Load(lastBlock.AppHash)
|
||||||
|
|
||||||
log.Notice("Loaded state", "block", lastBlock.BlockHeight, "root", stateTree.Hash())
|
log.Notice("Loaded state", "block", lastBlock.BlockHeight, "root", stateTree.Hash())
|
||||||
@ -51,6 +59,15 @@ func (app *PersistentDummyApplication) SetOption(key string, value string) (log
|
|||||||
|
|
||||||
// tx is either "key=value" or just arbitrary bytes
|
// tx is either "key=value" or just arbitrary bytes
|
||||||
func (app *PersistentDummyApplication) AppendTx(tx []byte) types.Result {
|
func (app *PersistentDummyApplication) AppendTx(tx []byte) types.Result {
|
||||||
|
// 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.changes
|
||||||
|
return app.execValidatorTx(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, update the key-value store
|
||||||
return app.app.AppendTx(tx)
|
return app.app.AppendTx(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,17 +93,29 @@ func (app *PersistentDummyApplication) Query(query []byte) types.Result {
|
|||||||
return app.app.Query(query)
|
return app.app.Query(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the validators in the merkle tree
|
||||||
func (app *PersistentDummyApplication) InitChain(validators []*types.Validator) {
|
func (app *PersistentDummyApplication) InitChain(validators []*types.Validator) {
|
||||||
return
|
for _, v := range validators {
|
||||||
|
r := app.updateValidator(v)
|
||||||
|
if r.IsErr() {
|
||||||
|
log.Error("Error updating validators", "r", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Track the block hash and header information
|
||||||
func (app *PersistentDummyApplication) BeginBlock(hash []byte, header *types.Header) {
|
func (app *PersistentDummyApplication) BeginBlock(hash []byte, header *types.Header) {
|
||||||
|
// update latest block info
|
||||||
app.blockHash = hash
|
app.blockHash = hash
|
||||||
app.blockHeader = header
|
app.blockHeader = header
|
||||||
|
|
||||||
|
// reset valset changes
|
||||||
|
app.changes = make([]*types.Validator, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the validator set
|
||||||
func (app *PersistentDummyApplication) EndBlock(height uint64) (diffs []*types.Validator) {
|
func (app *PersistentDummyApplication) EndBlock(height uint64) (diffs []*types.Validator) {
|
||||||
return nil
|
return app.changes
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------
|
//-----------------------------------------
|
||||||
@ -120,3 +149,77 @@ func SaveLastBlock(db dbm.DB, lastBlock types.LastBlockInfo) {
|
|||||||
}
|
}
|
||||||
db.Set(lastBlockKey, buf.Bytes())
|
db.Set(lastBlockKey, buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
// update validators
|
||||||
|
|
||||||
|
func (app *PersistentDummyApplication) Validators() (validators []*types.Validator) {
|
||||||
|
app.app.state.Iterate(func(key, value []byte) bool {
|
||||||
|
if isValidatorTx(key) {
|
||||||
|
validator := new(types.Validator)
|
||||||
|
err := types.ReadMessage(bytes.NewBuffer(value), validator)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
validators = append(validators, validator)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeValSetChangeTx(pubkey []byte, power uint64) []byte {
|
||||||
|
return []byte(Fmt("val:%X/%d", pubkey, power))
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidatorTx(tx []byte) bool {
|
||||||
|
if strings.HasPrefix(string(tx), ValidatorSetChangePrefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// format is "val:pubkey1/power1,addr2/power2,addr3/power3"tx
|
||||||
|
func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.Result {
|
||||||
|
tx = tx[len(ValidatorSetChangePrefix):]
|
||||||
|
pubKeyAndPower := strings.Split(string(tx), "/")
|
||||||
|
if len(pubKeyAndPower) != 2 {
|
||||||
|
return types.ErrEncodingError.SetLog(Fmt("Expected 'pubkey/power'. Got %v", pubKeyAndPower))
|
||||||
|
}
|
||||||
|
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
||||||
|
pubkey, err := hex.DecodeString(pubkeyS)
|
||||||
|
if err != nil {
|
||||||
|
return types.ErrEncodingError.SetLog(Fmt("Pubkey (%s) is invalid hex", pubkeyS))
|
||||||
|
}
|
||||||
|
power, err := strconv.Atoi(powerS)
|
||||||
|
if err != nil {
|
||||||
|
return types.ErrEncodingError.SetLog(Fmt("Power (%s) is not an int", powerS))
|
||||||
|
}
|
||||||
|
|
||||||
|
// update
|
||||||
|
return app.updateValidator(&types.Validator{pubkey, uint64(power)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// add, update, or remove a validator
|
||||||
|
func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types.Result {
|
||||||
|
key := []byte("val:" + string(v.PubKey))
|
||||||
|
if v.Power == 0 {
|
||||||
|
// remove validator
|
||||||
|
if !app.app.state.Has(key) {
|
||||||
|
return types.ErrUnauthorized.SetLog(Fmt("Cannot remove non-existent validator %X", key))
|
||||||
|
}
|
||||||
|
app.app.state.Remove(key)
|
||||||
|
} else {
|
||||||
|
// add or update validator
|
||||||
|
value := bytes.NewBuffer(make([]byte, 0))
|
||||||
|
if err := types.WriteMessage(v, value); err != nil {
|
||||||
|
return types.ErrInternalError.SetLog(Fmt("Error encoding validator: %v", err))
|
||||||
|
}
|
||||||
|
app.app.state.Set(key, value.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
// we only update the changes array if we succesfully updated the tree
|
||||||
|
app.changes = append(app.changes, v)
|
||||||
|
|
||||||
|
return types.OK
|
||||||
|
}
|
||||||
|
22
glide.lock
generated
22
glide.lock
generated
@ -1,8 +1,8 @@
|
|||||||
hash: 603c43870dfc63a3113a3d13ae799038206bd77889e2e9596a860d3644b8fb67
|
hash: 603c43870dfc63a3113a3d13ae799038206bd77889e2e9596a860d3644b8fb67
|
||||||
updated: 2016-11-15T14:46:00.011667442-05:00
|
updated: 2016-11-22T20:57:55.984772241-05:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/btcsuite/btcd
|
- name: github.com/btcsuite/btcd
|
||||||
version: d9a674e1b7bc09d0830d6986c71cf5f535d753c3
|
version: afec1bd1245a4a19e6dfe1306974b733e7cbb9b8
|
||||||
subpackages:
|
subpackages:
|
||||||
- btcec
|
- btcec
|
||||||
- name: github.com/btcsuite/fastsha256
|
- name: github.com/btcsuite/fastsha256
|
||||||
@ -10,7 +10,7 @@ imports:
|
|||||||
- name: github.com/go-stack/stack
|
- name: github.com/go-stack/stack
|
||||||
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
|
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
|
||||||
- name: github.com/golang/protobuf
|
- name: github.com/golang/protobuf
|
||||||
version: da116c3771bf4a398a43f44e069195ef1c9688ef
|
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
|
||||||
subpackages:
|
subpackages:
|
||||||
- proto
|
- proto
|
||||||
- name: github.com/golang/snappy
|
- name: github.com/golang/snappy
|
||||||
@ -39,8 +39,10 @@ imports:
|
|||||||
subpackages:
|
subpackages:
|
||||||
- edwards25519
|
- edwards25519
|
||||||
- extra25519
|
- extra25519
|
||||||
|
- name: github.com/tendermint/go-autofile
|
||||||
|
version: 63186e34b33d78ae47fb0d25e5717b307fdf3603
|
||||||
- name: github.com/tendermint/go-common
|
- name: github.com/tendermint/go-common
|
||||||
version: fa3daa7abc253264c916c12fecce3effa01a1287
|
version: 6b4160f2a57487f277c42bf06fd280195dfdb278
|
||||||
- name: github.com/tendermint/go-crypto
|
- name: github.com/tendermint/go-crypto
|
||||||
version: 4b11d62bdb324027ea01554e5767b71174680ba0
|
version: 4b11d62bdb324027ea01554e5767b71174680ba0
|
||||||
- name: github.com/tendermint/go-db
|
- name: github.com/tendermint/go-db
|
||||||
@ -48,7 +50,7 @@ imports:
|
|||||||
- name: github.com/tendermint/go-logger
|
- name: github.com/tendermint/go-logger
|
||||||
version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2
|
version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2
|
||||||
- name: github.com/tendermint/go-merkle
|
- name: github.com/tendermint/go-merkle
|
||||||
version: 05042c6ab9cad51d12e4cecf717ae68e3b1409a8
|
version: bfc4afe28c7a50045d4d1eb043e67460f8a51a4f
|
||||||
- name: github.com/tendermint/go-process
|
- name: github.com/tendermint/go-process
|
||||||
version: ba01cfbb58d446673beff17e72883cb49c835fb9
|
version: ba01cfbb58d446673beff17e72883cb49c835fb9
|
||||||
- name: github.com/tendermint/go-wire
|
- name: github.com/tendermint/go-wire
|
||||||
@ -58,9 +60,9 @@ imports:
|
|||||||
subpackages:
|
subpackages:
|
||||||
- term
|
- term
|
||||||
- name: github.com/urfave/cli
|
- name: github.com/urfave/cli
|
||||||
version: b4f4786f378c0c1d3336b5bb798094b166edf5a9
|
version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6
|
||||||
- name: golang.org/x/crypto
|
- name: golang.org/x/crypto
|
||||||
version: 9477e0b78b9ac3d0b03822fd95422e2fe07627cd
|
version: ede567c8e044a5913dad1d1af3696d9da953104c
|
||||||
subpackages:
|
subpackages:
|
||||||
- nacl/secretbox
|
- nacl/secretbox
|
||||||
- openpgp/armor
|
- openpgp/armor
|
||||||
@ -69,7 +71,7 @@ imports:
|
|||||||
- ripemd160
|
- ripemd160
|
||||||
- salsa20/salsa
|
- salsa20/salsa
|
||||||
- name: golang.org/x/net
|
- name: golang.org/x/net
|
||||||
version: cac22060de4e495155959e69adcb4b45763ccb10
|
version: 4971afdc2f162e82d185353533d3cf16188a9f4e
|
||||||
subpackages:
|
subpackages:
|
||||||
- context
|
- context
|
||||||
- http2
|
- http2
|
||||||
@ -79,11 +81,11 @@ imports:
|
|||||||
- lex/httplex
|
- lex/httplex
|
||||||
- trace
|
- trace
|
||||||
- name: golang.org/x/sys
|
- name: golang.org/x/sys
|
||||||
version: b699b7032584f0953262cb2788a0ca19bb494703
|
version: 30237cf4eefd639b184d1f2cb77a581ea0be8947
|
||||||
subpackages:
|
subpackages:
|
||||||
- unix
|
- unix
|
||||||
- name: google.golang.org/grpc
|
- name: google.golang.org/grpc
|
||||||
version: 0d9891286aca15aeb2b0a73be9f5946c3cfefa85
|
version: 63bd55dfbf781b183216d2dd4433a659c947648a
|
||||||
subpackages:
|
subpackages:
|
||||||
- codes
|
- codes
|
||||||
- credentials
|
- credentials
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
> query abc
|
> query abc
|
||||||
-> code: OK
|
-> code: OK
|
||||||
-> data: {Index=0 value=abc exists=true}
|
-> data: {{"index":0,"value":"abc","exists":true}}
|
||||||
|
|
||||||
> append_tx def=xyz
|
> append_tx def=xyz
|
||||||
-> code: OK
|
-> code: OK
|
||||||
@ -27,5 +27,5 @@
|
|||||||
|
|
||||||
> query def
|
> query def
|
||||||
-> code: OK
|
-> code: OK
|
||||||
-> data: {Index=1 value=xyz exists=true}
|
-> data: {{"index":1,"value":"xyz","exists":true}}
|
||||||
|
|
||||||
|
@ -1502,7 +1502,7 @@ func (m *TMSPInfo) GetVersion() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LastBlockInfo struct {
|
type LastBlockInfo struct {
|
||||||
BlockHeight int32 `protobuf:"varint,1,opt,name=block_height,json=blockHeight" json:"block_height,omitempty"`
|
BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight" json:"block_height,omitempty"`
|
||||||
BlockHash []byte `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"`
|
BlockHash []byte `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"`
|
||||||
AppHash []byte `protobuf:"bytes,3,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
|
AppHash []byte `protobuf:"bytes,3,opt,name=app_hash,json=appHash,proto3" json:"app_hash,omitempty"`
|
||||||
}
|
}
|
||||||
@ -1512,7 +1512,7 @@ func (m *LastBlockInfo) String() string { return proto.CompactTextStr
|
|||||||
func (*LastBlockInfo) ProtoMessage() {}
|
func (*LastBlockInfo) ProtoMessage() {}
|
||||||
func (*LastBlockInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
|
func (*LastBlockInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} }
|
||||||
|
|
||||||
func (m *LastBlockInfo) GetBlockHeight() int32 {
|
func (m *LastBlockInfo) GetBlockHeight() uint64 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.BlockHeight
|
return m.BlockHeight
|
||||||
}
|
}
|
||||||
@ -1551,7 +1551,7 @@ func (m *ConfigInfo) GetMaxBlockSize() uint64 {
|
|||||||
|
|
||||||
type Header struct {
|
type Header struct {
|
||||||
ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"`
|
ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"`
|
||||||
Height int32 `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
|
Height uint64 `protobuf:"varint,2,opt,name=height" json:"height,omitempty"`
|
||||||
Time uint64 `protobuf:"varint,3,opt,name=time" json:"time,omitempty"`
|
Time uint64 `protobuf:"varint,3,opt,name=time" json:"time,omitempty"`
|
||||||
NumTxs uint64 `protobuf:"varint,4,opt,name=num_txs,json=numTxs" json:"num_txs,omitempty"`
|
NumTxs uint64 `protobuf:"varint,4,opt,name=num_txs,json=numTxs" json:"num_txs,omitempty"`
|
||||||
LastBlockId *BlockID `protobuf:"bytes,5,opt,name=last_block_id,json=lastBlockId" json:"last_block_id,omitempty"`
|
LastBlockId *BlockID `protobuf:"bytes,5,opt,name=last_block_id,json=lastBlockId" json:"last_block_id,omitempty"`
|
||||||
@ -1573,7 +1573,7 @@ func (m *Header) GetChainId() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Header) GetHeight() int32 {
|
func (m *Header) GetHeight() uint64 {
|
||||||
if m != nil {
|
if m != nil {
|
||||||
return m.Height
|
return m.Height
|
||||||
}
|
}
|
||||||
@ -2143,7 +2143,7 @@ var _TMSPApplication_serviceDesc = grpc.ServiceDesc{
|
|||||||
func init() { proto.RegisterFile("types/types.proto", fileDescriptor0) }
|
func init() { proto.RegisterFile("types/types.proto", fileDescriptor0) }
|
||||||
|
|
||||||
var fileDescriptor0 = []byte{
|
var fileDescriptor0 = []byte{
|
||||||
// 1746 bytes of a gzipped FileDescriptorProto
|
// 1743 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0x49, 0x73, 0xdb, 0xc8,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0x49, 0x73, 0xdb, 0xc8,
|
||||||
0x15, 0x16, 0x29, 0x6e, 0x78, 0xa4, 0xa8, 0xd6, 0xd3, 0x46, 0x33, 0x49, 0x95, 0x07, 0xf1, 0x64,
|
0x15, 0x16, 0x29, 0x6e, 0x78, 0xa4, 0xa8, 0xd6, 0xd3, 0x46, 0x33, 0x49, 0x95, 0x07, 0xf1, 0x64,
|
||||||
0x24, 0xc7, 0x65, 0xa7, 0xe4, 0x9a, 0x29, 0x3b, 0x93, 0x4a, 0x95, 0x65, 0x6b, 0x2c, 0xd5, 0xc4,
|
0x24, 0xc7, 0x65, 0xa7, 0xe4, 0x9a, 0x29, 0x3b, 0x93, 0x4a, 0x95, 0x65, 0x6b, 0x2c, 0xd5, 0xc4,
|
||||||
@ -2201,57 +2201,56 @@ var fileDescriptor0 = []byte{
|
|||||||
0xbe, 0x9d, 0x27, 0x27, 0x6b, 0x2b, 0x73, 0x07, 0xf0, 0x66, 0xbf, 0xa8, 0x5b, 0xae, 0xd8, 0x09,
|
0xbe, 0x9d, 0x27, 0x27, 0x6b, 0x2b, 0x73, 0x07, 0xf0, 0x66, 0xbf, 0xa8, 0x5b, 0xae, 0xd8, 0x09,
|
||||||
0xf8, 0x13, 0x68, 0x3a, 0xee, 0x64, 0x12, 0x0f, 0x1a, 0x2b, 0x2e, 0x0a, 0x25, 0x36, 0xef, 0x40,
|
0xf8, 0x13, 0x68, 0x3a, 0xee, 0x64, 0x12, 0x0f, 0x1a, 0x2b, 0x2e, 0x0a, 0x25, 0x36, 0xef, 0x40,
|
||||||
0x27, 0xad, 0x3c, 0xaa, 0xf6, 0xb7, 0x3c, 0x8a, 0x53, 0x94, 0x36, 0xac, 0x94, 0x34, 0x3d, 0xd8,
|
0x27, 0xad, 0x3c, 0xaa, 0xf6, 0xb7, 0x3c, 0x8a, 0x53, 0x94, 0x36, 0xac, 0x94, 0x34, 0x3d, 0xd8,
|
||||||
0x28, 0x14, 0x1c, 0x7e, 0x02, 0x3d, 0x59, 0x95, 0xa3, 0x25, 0xf4, 0x6f, 0x5a, 0x5d, 0xc9, 0x3b,
|
0x28, 0x14, 0x1c, 0x7e, 0x02, 0x3d, 0x59, 0x95, 0xa3, 0x02, 0xfa, 0x77, 0x25, 0xef, 0x54, 0xb2,
|
||||||
0x95, 0x2c, 0xfc, 0x11, 0x80, 0x56, 0xb1, 0xf5, 0x60, 0xd7, 0xb3, 0x0c, 0xa5, 0x40, 0x77, 0xce,
|
0xf0, 0x47, 0x00, 0x5a, 0xc5, 0xd6, 0x83, 0x5d, 0xcf, 0x32, 0x94, 0x02, 0xdd, 0x39, 0xb7, 0x80,
|
||||||
0x2d, 0x20, 0xbc, 0x53, 0xc2, 0x75, 0x29, 0x6c, 0xdb, 0x61, 0x48, 0x22, 0xf3, 0x08, 0x20, 0xaf,
|
0xf0, 0x4e, 0x09, 0xd7, 0xa5, 0xb0, 0x6d, 0x87, 0x21, 0x89, 0xcc, 0x23, 0x80, 0xbc, 0x5a, 0xf1,
|
||||||
0x56, 0xbc, 0x03, 0xfd, 0xb9, 0xbd, 0x50, 0x4d, 0x30, 0x8a, 0xdd, 0xf7, 0x5c, 0x5f, 0x35, 0xbd,
|
0x0e, 0xf4, 0xe7, 0xf6, 0x42, 0x35, 0xc1, 0x28, 0x76, 0xdf, 0x73, 0xbd, 0x58, 0x6f, 0x6e, 0x2f,
|
||||||
0xb9, 0xbd, 0x90, 0x1b, 0x7a, 0xed, 0xbe, 0xe7, 0xe6, 0x1f, 0xeb, 0xd0, 0x52, 0xd7, 0x15, 0x79,
|
0xe4, 0x86, 0x5e, 0xbb, 0xef, 0xb9, 0xf9, 0xc7, 0x3a, 0xb4, 0xd4, 0x75, 0x45, 0x9e, 0x25, 0x48,
|
||||||
0x96, 0x20, 0x35, 0x72, 0x9d, 0xf4, 0x1c, 0x92, 0x3e, 0x73, 0x96, 0xae, 0xab, 0xba, 0xdc, 0xb0,
|
0x8d, 0x5c, 0x27, 0x3d, 0x87, 0xa4, 0xcf, 0x9c, 0xa5, 0xeb, 0xaa, 0xbe, 0x7c, 0x5d, 0x51, 0x4a,
|
||||||
0xa6, 0x28, 0x25, 0xc2, 0x9d, 0x73, 0xb9, 0x91, 0x86, 0x25, 0xbf, 0x71, 0x1f, 0xda, 0x7e, 0x32,
|
0x84, 0x3b, 0xe7, 0x72, 0x23, 0x0d, 0x4b, 0x7e, 0xe3, 0x3e, 0xb4, 0xfd, 0x64, 0x3e, 0x12, 0x8b,
|
||||||
0x1f, 0x89, 0x45, 0x2c, 0x3b, 0xa9, 0x61, 0xb5, 0xfc, 0x64, 0xfe, 0x66, 0x11, 0xe3, 0x11, 0x6c,
|
0x58, 0x76, 0x52, 0xc3, 0x6a, 0xf9, 0xc9, 0xfc, 0xcd, 0x22, 0xc6, 0x23, 0xd8, 0xc8, 0xdb, 0x92,
|
||||||
0xe4, 0x6d, 0x49, 0x8b, 0xa8, 0x3b, 0xa1, 0xaf, 0x43, 0xac, 0x82, 0xf4, 0xcc, 0xea, 0x66, 0x3d,
|
0x16, 0x51, 0x77, 0x42, 0x5f, 0x87, 0x58, 0x05, 0xe9, 0x99, 0xd5, 0xcd, 0x7a, 0xf2, 0xcc, 0xc1,
|
||||||
0x79, 0xe6, 0xe0, 0x01, 0x30, 0x69, 0xa3, 0xa0, 0x57, 0x9d, 0xba, 0x25, 0x4f, 0xdd, 0x27, 0xbe,
|
0x03, 0x60, 0xd2, 0x46, 0x41, 0xaf, 0x3a, 0x75, 0x4b, 0x9e, 0xba, 0x4f, 0x7c, 0x8d, 0xcd, 0x14,
|
||||||
0xc6, 0x66, 0x8a, 0xcb, 0x0f, 0xc0, 0xa0, 0x8a, 0x50, 0x2a, 0x6d, 0xa9, 0xd2, 0x21, 0x86, 0x14,
|
0x97, 0x1f, 0x80, 0x41, 0x15, 0xa1, 0x54, 0xda, 0x52, 0xa5, 0x43, 0x0c, 0x29, 0xfc, 0x0c, 0x36,
|
||||||
0x7e, 0x06, 0x9b, 0xf9, 0xfd, 0xae, 0x54, 0x3a, 0xca, 0x4b, 0xce, 0xbe, 0x11, 0x5d, 0xa3, 0x18,
|
0xf3, 0xfb, 0x5d, 0xa9, 0x74, 0x94, 0x97, 0x9c, 0x7d, 0x23, 0xba, 0x46, 0x31, 0xba, 0x67, 0xd0,
|
||||||
0xdd, 0x33, 0x68, 0xeb, 0x2d, 0x56, 0xce, 0x02, 0x77, 0xa1, 0x19, 0xda, 0x91, 0x88, 0x35, 0x3c,
|
0xd6, 0x5b, 0xac, 0x9c, 0x05, 0xee, 0x42, 0x33, 0xb4, 0x23, 0x11, 0x6b, 0x78, 0x4a, 0xf1, 0xe6,
|
||||||
0xa5, 0x78, 0x73, 0x6e, 0x47, 0x34, 0x43, 0xe9, 0x89, 0x40, 0xa9, 0x98, 0x8f, 0x61, 0xa3, 0xc0,
|
0xdc, 0x8e, 0x68, 0x86, 0xd2, 0x13, 0x81, 0x52, 0x31, 0x1f, 0xc3, 0x46, 0x81, 0x4f, 0xa8, 0x2a,
|
||||||
0x27, 0x54, 0x15, 0x81, 0xb0, 0x3d, 0x9d, 0x22, 0x45, 0x64, 0xcb, 0xd4, 0xf3, 0x65, 0xcc, 0xc7,
|
0x02, 0x61, 0x7b, 0x3a, 0x45, 0x8a, 0xc8, 0x96, 0xa9, 0xe7, 0xcb, 0x98, 0x8f, 0xc1, 0xc8, 0x6a,
|
||||||
0x60, 0x64, 0xb5, 0x48, 0x69, 0x09, 0x93, 0x8b, 0xaf, 0x79, 0x3a, 0x16, 0x69, 0x8a, 0xdc, 0x85,
|
0x91, 0xd2, 0x12, 0x26, 0x17, 0x5f, 0xf3, 0x74, 0x2c, 0xd2, 0x14, 0xb9, 0x0b, 0x83, 0x6f, 0xf5,
|
||||||
0xc1, 0xb7, 0x7a, 0x2c, 0x69, 0x58, 0x8a, 0xb8, 0xfb, 0x97, 0x1a, 0x74, 0x5f, 0x28, 0x18, 0xa6,
|
0x58, 0xd2, 0xb0, 0x14, 0x71, 0xf7, 0x2f, 0x35, 0xe8, 0xbe, 0x50, 0x30, 0x4c, 0x5d, 0x85, 0x9b,
|
||||||
0xae, 0xc2, 0x4d, 0xe8, 0xbe, 0x4c, 0x3c, 0x4f, 0xb3, 0xd8, 0x1a, 0x76, 0xa0, 0x41, 0xe8, 0xcd,
|
0xd0, 0x7d, 0x99, 0x78, 0x9e, 0x66, 0xb1, 0x35, 0xec, 0x40, 0x83, 0xd0, 0x9b, 0xd5, 0xd0, 0x80,
|
||||||
0x6a, 0x68, 0x40, 0x53, 0xa2, 0x33, 0xab, 0x13, 0x93, 0xca, 0x89, 0xad, 0xe3, 0x06, 0x18, 0x19,
|
0xa6, 0x44, 0x67, 0x56, 0x27, 0x26, 0x95, 0x13, 0x5b, 0xc7, 0x0d, 0x30, 0x32, 0xb8, 0x63, 0x0d,
|
||||||
0xdc, 0xb1, 0x06, 0x91, 0xd9, 0xb5, 0xc0, 0x9a, 0xd8, 0x83, 0x4e, 0x8a, 0x72, 0x6c, 0x0b, 0xbb,
|
0x22, 0xb3, 0x6b, 0x81, 0x35, 0xb1, 0x07, 0x9d, 0x14, 0xe5, 0xd8, 0x16, 0x76, 0xa1, 0xad, 0x41,
|
||||||
0xd0, 0xd6, 0xa0, 0xc4, 0x10, 0x01, 0x5a, 0x2a, 0x51, 0x6c, 0x9b, 0x3c, 0x4b, 0x3c, 0x61, 0x3b,
|
0x89, 0x21, 0x02, 0xb4, 0x54, 0xa2, 0xd8, 0x36, 0x79, 0x96, 0x78, 0xc2, 0x76, 0xc8, 0x41, 0xd6,
|
||||||
0xe4, 0x20, 0xeb, 0x50, 0xb6, 0x8b, 0x7d, 0x80, 0xbc, 0x37, 0xd9, 0x1e, 0x39, 0x4c, 0xbb, 0x92,
|
0xa1, 0x6c, 0x17, 0xfb, 0x00, 0x79, 0x6f, 0xb2, 0x3d, 0x72, 0x98, 0x76, 0x25, 0xdb, 0xbf, 0xfb,
|
||||||
0xed, 0xdf, 0xfd, 0x73, 0x13, 0x3a, 0x29, 0x1e, 0x60, 0x0b, 0xea, 0xaf, 0xbe, 0x66, 0x6b, 0xb8,
|
0xe7, 0x26, 0x74, 0x52, 0x3c, 0xc0, 0x16, 0xd4, 0x5f, 0x7d, 0xcd, 0xd6, 0x70, 0x0b, 0x36, 0xce,
|
||||||
0x05, 0x1b, 0x67, 0xbe, 0xe0, 0x91, 0x6f, 0x7b, 0x27, 0x74, 0x0f, 0xb1, 0x1a, 0xb1, 0x4e, 0xfc,
|
0x7c, 0xc1, 0x23, 0xdf, 0xf6, 0x4e, 0xe8, 0x1e, 0x62, 0x35, 0x62, 0x9d, 0xf8, 0xe3, 0xc0, 0x71,
|
||||||
0x71, 0xe0, 0xb8, 0xfe, 0x54, 0xb1, 0xea, 0xe4, 0xe8, 0xd8, 0x76, 0x5e, 0x06, 0xfe, 0x98, 0xb3,
|
0xfd, 0xa9, 0x62, 0xd5, 0xc9, 0xd1, 0xb1, 0xed, 0xbc, 0x0c, 0xfc, 0x31, 0x67, 0xeb, 0xc8, 0xa0,
|
||||||
0x75, 0x64, 0xd0, 0xfb, 0xc6, 0xb7, 0x13, 0x31, 0x0b, 0x22, 0xf7, 0x3d, 0x77, 0x58, 0x03, 0x77,
|
0xf7, 0x8d, 0x6f, 0x27, 0x62, 0x16, 0x44, 0xee, 0x7b, 0xee, 0xb0, 0x06, 0xee, 0xc2, 0xd6, 0x99,
|
||||||
0x61, 0xeb, 0xcc, 0x8f, 0x93, 0xc9, 0xc4, 0x1d, 0xbb, 0xdc, 0x17, 0x5f, 0x25, 0xbe, 0x13, 0xb3,
|
0x1f, 0x27, 0x93, 0x89, 0x3b, 0x76, 0xb9, 0x2f, 0xbe, 0x4a, 0x7c, 0x27, 0x66, 0x4d, 0x44, 0xe8,
|
||||||
0x26, 0x22, 0xf4, 0xbf, 0xf1, 0x2f, 0xfd, 0xe0, 0x5b, 0x5f, 0x0f, 0x6f, 0xac, 0x85, 0x03, 0xd8,
|
0x7f, 0xe3, 0x5f, 0xfa, 0xc1, 0xb7, 0xbe, 0x1e, 0xde, 0x58, 0x0b, 0x07, 0xb0, 0x73, 0x6c, 0xc7,
|
||||||
0x39, 0xb6, 0x63, 0xfe, 0x2c, 0x09, 0x3d, 0x77, 0x6c, 0x0b, 0xfe, 0xc4, 0x71, 0x22, 0x1e, 0xc7,
|
0xfc, 0x59, 0x12, 0x7a, 0xee, 0xd8, 0x16, 0xfc, 0x89, 0xe3, 0x44, 0x3c, 0x8e, 0x19, 0x27, 0x27,
|
||||||
0x8c, 0x93, 0x13, 0x92, 0x14, 0xd7, 0x9e, 0xa4, 0x06, 0x05, 0xff, 0x9c, 0xc7, 0x6c, 0x8a, 0xb7,
|
0x24, 0x29, 0xae, 0x3d, 0x49, 0x0d, 0x0a, 0xfe, 0x39, 0x8f, 0xd9, 0x14, 0x6f, 0xc1, 0xee, 0x0d,
|
||||||
0x60, 0xf7, 0x86, 0x44, 0xae, 0x3c, 0xc3, 0x1f, 0xc2, 0xa0, 0x2c, 0x7a, 0x6e, 0xc7, 0xe7, 0x91,
|
0x89, 0x5c, 0x79, 0x86, 0x3f, 0x84, 0x41, 0x59, 0xf4, 0xdc, 0x8e, 0xcf, 0x23, 0x77, 0xcc, 0x99,
|
||||||
0x3b, 0xe6, 0xcc, 0xc5, 0x1d, 0x60, 0x4a, 0x2a, 0x4b, 0xf7, 0xcc, 0x0f, 0x13, 0xc1, 0xfe, 0x90,
|
0x8b, 0x3b, 0xc0, 0x94, 0x54, 0x96, 0xee, 0x99, 0x1f, 0x26, 0x82, 0xfd, 0x21, 0x5d, 0x5f, 0x73,
|
||||||
0xae, 0xaf, 0xb9, 0xaf, 0x12, 0x41, 0xec, 0xcb, 0x12, 0xfb, 0x5c, 0x96, 0x07, 0xf3, 0x70, 0x1f,
|
0x5f, 0x25, 0x82, 0xd8, 0x97, 0x25, 0xf6, 0xb9, 0x2c, 0x0f, 0xe6, 0xe1, 0x3e, 0x6c, 0x2f, 0xb1,
|
||||||
0xb6, 0x97, 0xd8, 0xaf, 0xe9, 0x7c, 0x14, 0x9d, 0x79, 0xbe, 0x5f, 0x25, 0x70, 0xa7, 0xbe, 0x2d,
|
0x5f, 0xd3, 0xf9, 0x28, 0x3a, 0xf3, 0x7c, 0xbf, 0x4a, 0xe0, 0x4e, 0x7d, 0x5b, 0x24, 0x11, 0x67,
|
||||||
0x92, 0x88, 0x33, 0x1f, 0xf7, 0x00, 0x49, 0xa2, 0x43, 0x92, 0x1e, 0x3c, 0x48, 0x57, 0xd0, 0x7c,
|
0x3e, 0xee, 0x01, 0x92, 0x44, 0x87, 0x24, 0x3d, 0x78, 0x90, 0xae, 0xa0, 0xf9, 0x7a, 0x85, 0xb0,
|
||||||
0xbd, 0x42, 0x58, 0x66, 0x7b, 0xc9, 0xd4, 0xf5, 0xd9, 0x3b, 0xdc, 0x05, 0xf6, 0x3c, 0xb8, 0xd2,
|
0xcc, 0xf6, 0x92, 0xa9, 0xeb, 0xb3, 0x77, 0xb8, 0x0b, 0xec, 0x79, 0x70, 0xa5, 0xb9, 0x27, 0xbe,
|
||||||
0xdc, 0x13, 0x5f, 0xb8, 0xe2, 0x9a, 0xfd, 0xad, 0x86, 0x3b, 0xb0, 0x99, 0xb3, 0x9f, 0x47, 0x41,
|
0x70, 0xc5, 0x35, 0xfb, 0x5b, 0x0d, 0x77, 0x60, 0x33, 0x67, 0x3f, 0x8f, 0x82, 0x24, 0x64, 0x7f,
|
||||||
0x12, 0xb2, 0xbf, 0xd7, 0x70, 0x1f, 0x30, 0xe7, 0x9e, 0x47, 0x41, 0x18, 0xc4, 0xb6, 0xc7, 0xfe,
|
0xaf, 0xe1, 0x3e, 0x60, 0xce, 0x3d, 0x8f, 0x82, 0x30, 0x88, 0x6d, 0x8f, 0xfd, 0xa3, 0x86, 0x7b,
|
||||||
0x51, 0xc3, 0x3d, 0xd8, 0x7a, 0x1e, 0x5c, 0x65, 0x59, 0x50, 0x06, 0xff, 0x4c, 0x0d, 0x32, 0xfe,
|
0xb0, 0xf5, 0x3c, 0xb8, 0xca, 0xb2, 0xa0, 0x0c, 0xfe, 0x99, 0x1a, 0x64, 0xfc, 0x17, 0x7c, 0x7e,
|
||||||
0x0b, 0x3e, 0xbf, 0xe0, 0x11, 0xfb, 0x57, 0x0d, 0x6f, 0xc1, 0xce, 0xb2, 0x20, 0xf3, 0xf5, 0xef,
|
0xc1, 0x23, 0xf6, 0xaf, 0x1a, 0xde, 0x82, 0x9d, 0x65, 0x41, 0xe6, 0xeb, 0xdf, 0x35, 0xbd, 0xa3,
|
||||||
0x9a, 0xde, 0x51, 0x26, 0x7a, 0x1b, 0x08, 0xce, 0xfe, 0x93, 0xb2, 0x75, 0x1c, 0xb4, 0xa3, 0xff,
|
0x4c, 0xf4, 0x36, 0x10, 0x9c, 0xfd, 0x27, 0x65, 0xeb, 0x38, 0x68, 0x47, 0xff, 0xad, 0xe1, 0x36,
|
||||||
0xd6, 0x70, 0x1b, 0xfa, 0x39, 0x5b, 0xea, 0xfe, 0xaf, 0x86, 0x43, 0xd8, 0x2d, 0x30, 0x5d, 0x7f,
|
0xf4, 0x73, 0xb6, 0xd4, 0xfd, 0x5f, 0x0d, 0x87, 0xb0, 0x5b, 0x60, 0xba, 0xfe, 0xf4, 0x9c, 0x3a,
|
||||||
0x7a, 0x4e, 0x1d, 0xc7, 0xfe, 0x5f, 0x3b, 0xfa, 0xae, 0x09, 0x9b, 0x74, 0x51, 0x3c, 0x09, 0xd5,
|
0x8e, 0xfd, 0xbf, 0x76, 0xf4, 0x5d, 0x13, 0x36, 0xe9, 0xa2, 0x78, 0x12, 0xaa, 0x05, 0x68, 0x54,
|
||||||
0x02, 0x34, 0x2a, 0x3c, 0x50, 0x7d, 0x86, 0x15, 0x2f, 0xfb, 0x61, 0xd5, 0xac, 0x8e, 0x47, 0xba,
|
0x78, 0xa0, 0xfa, 0x0c, 0x2b, 0x5e, 0xf6, 0xc3, 0xaa, 0x59, 0x1d, 0x8f, 0x74, 0x3b, 0x62, 0xd5,
|
||||||
0x1d, 0xb1, 0xea, 0x81, 0x3f, 0xac, 0x1c, 0xd9, 0x69, 0x11, 0x35, 0x4e, 0xdd, 0x7c, 0xe7, 0x0f,
|
0x03, 0x7f, 0x58, 0x39, 0xb2, 0xd3, 0x22, 0x6a, 0x9c, 0xba, 0xf9, 0xce, 0x1f, 0x56, 0xcd, 0xed,
|
||||||
0xab, 0xe6, 0x76, 0xfc, 0xe5, 0x52, 0x7b, 0xe3, 0xaa, 0xd7, 0xfe, 0x70, 0xe5, 0x04, 0x8f, 0x5f,
|
0xf8, 0xcb, 0xa5, 0xf6, 0xc6, 0x55, 0xaf, 0xfd, 0xe1, 0xca, 0x09, 0x1e, 0xbf, 0xcc, 0x01, 0x00,
|
||||||
0xe6, 0x00, 0x80, 0x2b, 0xde, 0xfc, 0xc3, 0x55, 0x53, 0x3c, 0x3e, 0xca, 0xf0, 0x02, 0xab, 0x5f,
|
0x57, 0xbc, 0xf9, 0x87, 0xab, 0xa6, 0x78, 0x7c, 0x94, 0xe1, 0x05, 0x56, 0xbf, 0xfc, 0x87, 0x2b,
|
||||||
0xfe, 0xc3, 0x15, 0x93, 0x3c, 0xc5, 0x46, 0x0d, 0x28, 0x55, 0x0f, 0xfa, 0x61, 0xe5, 0x70, 0x8e,
|
0x26, 0x79, 0x8a, 0x8d, 0x1a, 0x50, 0xaa, 0x1e, 0xf4, 0xc3, 0xca, 0xe1, 0x1c, 0x3f, 0x4f, 0x01,
|
||||||
0x9f, 0xa7, 0x80, 0x84, 0x95, 0x7f, 0x1a, 0x0c, 0xab, 0x9f, 0x00, 0x14, 0xa1, 0xfc, 0x59, 0xb9,
|
0x09, 0x2b, 0xff, 0x34, 0x18, 0x56, 0x3f, 0x01, 0x28, 0x42, 0xf9, 0xb3, 0x72, 0xd5, 0xbf, 0x01,
|
||||||
0xea, 0xdf, 0x80, 0xe1, 0xca, 0xe1, 0x1e, 0x9f, 0x2c, 0x23, 0x1c, 0xae, 0xfc, 0x4f, 0x60, 0xb8,
|
0xc3, 0x95, 0xc3, 0x3d, 0x3e, 0x59, 0x46, 0x38, 0x5c, 0xf9, 0x9f, 0xc0, 0x70, 0xf5, 0x88, 0x4f,
|
||||||
0x7a, 0xc4, 0xa7, 0x20, 0xe7, 0x6f, 0xc8, 0xea, 0x7f, 0x06, 0x86, 0xab, 0xa6, 0xfc, 0x8b, 0x96,
|
0x41, 0xce, 0xdf, 0x90, 0xd5, 0xff, 0x0c, 0x0c, 0x57, 0x4d, 0xf9, 0x17, 0x2d, 0xf9, 0x8f, 0xd3,
|
||||||
0xfc, 0xc7, 0xe9, 0xe1, 0xf7, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x0f, 0x72, 0x7a, 0x86, 0x12,
|
0xc3, 0xef, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa2, 0x81, 0xd5, 0x01, 0x86, 0x12, 0x00, 0x00,
|
||||||
0x00, 0x00,
|
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ message TMSPInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message LastBlockInfo {
|
message LastBlockInfo {
|
||||||
int32 block_height = 1;
|
uint64 block_height = 1;
|
||||||
bytes block_hash = 2;
|
bytes block_hash = 2;
|
||||||
bytes app_hash = 3;
|
bytes app_hash = 3;
|
||||||
}
|
}
|
||||||
@ -233,7 +233,7 @@ message ConfigInfo {
|
|||||||
|
|
||||||
message Header {
|
message Header {
|
||||||
string chain_id = 1;
|
string chain_id = 1;
|
||||||
int32 height = 2;
|
uint64 height = 2;
|
||||||
uint64 time = 3;
|
uint64 time = 3;
|
||||||
uint64 num_txs = 4;
|
uint64 num_txs = 4;
|
||||||
BlockID last_block_id = 5;
|
BlockID last_block_id = 5;
|
||||||
|
24
types/validators.go
Normal file
24
types/validators.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// validators implements sort
|
||||||
|
|
||||||
|
type Validators []*Validator
|
||||||
|
|
||||||
|
func (v Validators) Len() int {
|
||||||
|
return len(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Validators) Swap(i, j int) {
|
||||||
|
v1 := v[i]
|
||||||
|
v[i] = v[j]
|
||||||
|
v[j] = v1
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user