mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-18 07:31:20 +00:00
fixes from review
This commit is contained in:
@ -17,12 +17,18 @@ import (
|
|||||||
|
|
||||||
// Structure for data passed to print response.
|
// Structure for data passed to print response.
|
||||||
type response struct {
|
type response struct {
|
||||||
Data []byte
|
// generic abci response
|
||||||
Code types.CodeType
|
Data []byte
|
||||||
|
Code types.CodeType
|
||||||
|
Log string
|
||||||
|
|
||||||
|
Query *queryResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type queryResponse struct {
|
||||||
Key []byte
|
Key []byte
|
||||||
Value []byte
|
Value []byte
|
||||||
Log string
|
Height uint64
|
||||||
Height string
|
|
||||||
Proof []byte
|
Proof []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +287,7 @@ func cmdCheckTx(c *cli.Context) error {
|
|||||||
func cmdCommit(c *cli.Context) error {
|
func cmdCommit(c *cli.Context) error {
|
||||||
res := client.CommitSync()
|
res := client.CommitSync()
|
||||||
printResponse(c, response{
|
printResponse(c, response{
|
||||||
|
Code: res.Code,
|
||||||
Data: res.Data,
|
Data: res.Data,
|
||||||
Log: res.Log,
|
Log: res.Log,
|
||||||
})
|
})
|
||||||
@ -308,12 +315,14 @@ func cmdQuery(c *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printResponse(c, response{
|
printResponse(c, response{
|
||||||
Code: resQuery.Code,
|
Code: resQuery.Code,
|
||||||
Key: resQuery.Key,
|
Log: resQuery.Log,
|
||||||
Value: resQuery.Value,
|
Query: &queryResponse{
|
||||||
Log: resQuery.Log,
|
Key: resQuery.Key,
|
||||||
Height: fmt.Sprintf("%v", resQuery.Height),
|
Value: resQuery.Value,
|
||||||
//Proof: resQuery.Proof,
|
Height: resQuery.Height,
|
||||||
|
Proof: resQuery.Proof,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -328,29 +337,30 @@ func printResponse(c *cli.Context, rsp response) {
|
|||||||
fmt.Println(">", c.Command.Name, strings.Join(c.Args(), " "))
|
fmt.Println(">", c.Command.Name, strings.Join(c.Args(), " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
if rsp.Code != types.CodeType_OK {
|
if !rsp.Code.IsOK() {
|
||||||
fmt.Printf("-> code: %s\n", rsp.Code.String())
|
fmt.Printf("-> code: %s\n", rsp.Code.String())
|
||||||
}
|
}
|
||||||
if len(rsp.Data) != 0 {
|
if len(rsp.Data) != 0 {
|
||||||
fmt.Printf("-> data: %s\n", rsp.Data)
|
fmt.Printf("-> data: %s\n", rsp.Data)
|
||||||
fmt.Printf("-> data.hex: %X\n", rsp.Data)
|
fmt.Printf("-> data.hex: %X\n", rsp.Data)
|
||||||
}
|
}
|
||||||
if len(rsp.Key) != 0 {
|
|
||||||
fmt.Printf("-> key: %s\n", rsp.Key)
|
|
||||||
fmt.Printf("-> key.hex: %X\n", rsp.Key)
|
|
||||||
}
|
|
||||||
if len(rsp.Value) != 0 {
|
|
||||||
fmt.Printf("-> value: %s\n", rsp.Value)
|
|
||||||
fmt.Printf("-> value.hex: %X\n", rsp.Value)
|
|
||||||
}
|
|
||||||
if rsp.Log != "" {
|
if rsp.Log != "" {
|
||||||
fmt.Printf("-> log: %s\n", rsp.Log)
|
fmt.Printf("-> log: %s\n", rsp.Log)
|
||||||
}
|
}
|
||||||
if rsp.Height != "" {
|
|
||||||
fmt.Printf("-> height: %s\n", rsp.Height)
|
if rsp.Query != nil {
|
||||||
}
|
fmt.Printf("-> height: %d\n", rsp.Query.Height)
|
||||||
if rsp.Proof != nil {
|
if rsp.Query.Key != nil {
|
||||||
fmt.Printf("-> proof: %X\n", rsp.Proof)
|
fmt.Printf("-> key: %s\n", rsp.Query.Key)
|
||||||
|
fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
|
||||||
|
}
|
||||||
|
if rsp.Query.Value != nil {
|
||||||
|
fmt.Printf("-> value: %s\n", rsp.Query.Value)
|
||||||
|
fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
|
||||||
|
}
|
||||||
|
if rsp.Query.Proof != nil {
|
||||||
|
fmt.Printf("-> proof: %X\n", rsp.Query.Proof)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose {
|
if verbose {
|
||||||
|
@ -2,10 +2,9 @@ package counter
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/tendermint/abci/types"
|
"github.com/tendermint/abci/types"
|
||||||
. "github.com/tendermint/go-common"
|
cmn "github.com/tendermint/go-common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CounterApplication struct {
|
type CounterApplication struct {
|
||||||
@ -21,7 +20,7 @@ func NewCounterApplication(serial bool) *CounterApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *CounterApplication) Info() types.ResponseInfo {
|
func (app *CounterApplication) Info() types.ResponseInfo {
|
||||||
return types.ResponseInfo{Data: fmt.Sprintf("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
|
return types.ResponseInfo{Data: cmn.Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *CounterApplication) SetOption(key string, value string) (log string) {
|
func (app *CounterApplication) SetOption(key string, value string) (log string) {
|
||||||
@ -34,13 +33,13 @@ func (app *CounterApplication) SetOption(key string, value string) (log string)
|
|||||||
func (app *CounterApplication) DeliverTx(tx []byte) types.Result {
|
func (app *CounterApplication) DeliverTx(tx []byte) types.Result {
|
||||||
if app.serial {
|
if app.serial {
|
||||||
if len(tx) > 8 {
|
if len(tx) > 8 {
|
||||||
return types.ErrEncodingError.SetLog(fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx)))
|
return types.ErrEncodingError.SetLog(cmn.Fmt("Max tx size is 8 bytes, got %d", len(tx)))
|
||||||
}
|
}
|
||||||
tx8 := make([]byte, 8)
|
tx8 := make([]byte, 8)
|
||||||
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.ErrBadNonce.SetLog(fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue))
|
return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected %v, got %v", app.txCount, txValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
app.txCount++
|
app.txCount++
|
||||||
@ -50,13 +49,13 @@ func (app *CounterApplication) DeliverTx(tx []byte) types.Result {
|
|||||||
func (app *CounterApplication) CheckTx(tx []byte) types.Result {
|
func (app *CounterApplication) CheckTx(tx []byte) types.Result {
|
||||||
if app.serial {
|
if app.serial {
|
||||||
if len(tx) > 8 {
|
if len(tx) > 8 {
|
||||||
return types.ErrEncodingError.SetLog(fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx)))
|
return types.ErrEncodingError.SetLog(cmn.Fmt("Max tx size is 8 bytes, got %d", len(tx)))
|
||||||
}
|
}
|
||||||
tx8 := make([]byte, 8)
|
tx8 := make([]byte, 8)
|
||||||
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.ErrBadNonce.SetLog(fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue))
|
return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return types.OK
|
return types.OK
|
||||||
@ -75,10 +74,10 @@ func (app *CounterApplication) Commit() types.Result {
|
|||||||
func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
|
func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
|
||||||
switch reqQuery.Path {
|
switch reqQuery.Path {
|
||||||
case "hash":
|
case "hash":
|
||||||
return types.ResponseQuery{Value: []byte(Fmt("%v", app.hashCount))}
|
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.hashCount))}
|
||||||
case "tx":
|
case "tx":
|
||||||
return types.ResponseQuery{Value: []byte(Fmt("%v", app.txCount))}
|
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.txCount))}
|
||||||
default:
|
default:
|
||||||
return types.ResponseQuery{Log: Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
|
return types.ResponseQuery{Log: cmn.Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package dummy
|
package dummy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/tendermint/abci/types"
|
"github.com/tendermint/abci/types"
|
||||||
|
cmn "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/go-merkle"
|
"github.com/tendermint/go-merkle"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ func NewDummyApplication() *DummyApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *DummyApplication) Info() (resInfo types.ResponseInfo) {
|
func (app *DummyApplication) Info() (resInfo types.ResponseInfo) {
|
||||||
return types.ResponseInfo{Data: fmt.Sprintf("{\"size\":%v}", app.state.Size())}
|
return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tx is either "key=value" or just arbitrary bytes
|
// tx is either "key=value" or just arbitrary bytes
|
||||||
|
@ -2,7 +2,6 @@ package dummy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
@ -13,7 +12,7 @@ import (
|
|||||||
"github.com/tendermint/abci/types"
|
"github.com/tendermint/abci/types"
|
||||||
cmn "github.com/tendermint/go-common"
|
cmn "github.com/tendermint/go-common"
|
||||||
"github.com/tendermint/go-crypto"
|
"github.com/tendermint/go-crypto"
|
||||||
merkle "github.com/tendermint/go-merkle"
|
"github.com/tendermint/go-merkle"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
|
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
|
||||||
@ -115,7 +114,7 @@ func TestValSetChanges(t *testing.T) {
|
|||||||
nInit := 5
|
nInit := 5
|
||||||
vals := make([]*types.Validator, total)
|
vals := make([]*types.Validator, total)
|
||||||
for i := 0; i < total; i++ {
|
for i := 0; i < total; i++ {
|
||||||
pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(fmt.Sprintf("test%d", i))).PubKey().Bytes()
|
pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(cmn.Fmt("test%d", i))).PubKey().Bytes()
|
||||||
power := cmn.RandInt()
|
power := cmn.RandInt()
|
||||||
vals[i] = &types.Validator{pubkey, uint64(power)}
|
vals[i] = &types.Validator{pubkey, uint64(power)}
|
||||||
}
|
}
|
||||||
|
@ -1,321 +0,0 @@
|
|||||||
package dummy
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
. "github.com/tendermint/go-common"
|
|
||||||
"github.com/tendermint/go-crypto"
|
|
||||||
merkle "github.com/tendermint/go-merkle"
|
|
||||||
"github.com/tendermint/go-wire"
|
|
||||||
<<<<<<< HEAD
|
|
||||||
"github.com/tendermint/abci/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func testDummy(t *testing.T, dummy types.Application, tx []byte, key, value string) {
|
|
||||||
if r := dummy.DeliverTx(tx); r.IsErr() {
|
|
||||||
t.Fatal(r)
|
|
||||||
}
|
|
||||||
if r := dummy.DeliverTx(tx); r.IsErr() {
|
|
||||||
t.Fatal(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := dummy.Query([]byte(key))
|
|
||||||
if r.IsErr() {
|
|
||||||
t.Fatal(r)
|
|
||||||
}
|
|
||||||
=======
|
|
||||||
tmspcli "github.com/tendermint/tmsp/client"
|
|
||||||
"github.com/tendermint/tmsp/server"
|
|
||||||
"github.com/tendermint/tmsp/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
|
|
||||||
ar := app.AppendTx(tx)
|
|
||||||
require.False(t, ar.IsErr(), ar)
|
|
||||||
// repeating tx doesn't raise error
|
|
||||||
ar = app.AppendTx(tx)
|
|
||||||
require.False(t, ar.IsErr(), ar)
|
|
||||||
>>>>>>> Add tests for client-server proofs over socket and grpc
|
|
||||||
|
|
||||||
// make sure query is fine
|
|
||||||
r := app.Query([]byte(key))
|
|
||||||
require.False(t, r.IsErr(), r)
|
|
||||||
q := new(QueryResult)
|
|
||||||
err := wire.ReadJSONBytes(r.Data, q)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.Equal(t, value, q.Value)
|
|
||||||
|
|
||||||
// make sure proof is fine
|
|
||||||
rp := app.Proof([]byte(key), 0)
|
|
||||||
require.False(t, rp.IsErr(), rp)
|
|
||||||
p, err := merkle.LoadProof(rp.Data)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, p.Valid())
|
|
||||||
assert.Equal(t, []byte(key), p.Key())
|
|
||||||
assert.Equal(t, []byte(value), p.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)
|
|
||||||
height := uint64(0)
|
|
||||||
|
|
||||||
resInfo := dummy.Info()
|
|
||||||
if resInfo.LastBlockHeight != height {
|
|
||||||
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
|
||||||
|
|
||||||
resInfo = dummy.Info()
|
|
||||||
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 TestValSetChanges(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 := 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.DeliverTx(tx); r.IsErr() {
|
|
||||||
t.Fatal(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resEndBlock := dummyChain.EndBlock(height)
|
|
||||||
dummy.Commit()
|
|
||||||
|
|
||||||
valsEqual(t, diff, resEndBlock.Diffs)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) (tmspcli.Client, Service, error) {
|
|
||||||
// Start the listener
|
|
||||||
socket := Fmt("unix://%s.sock", name)
|
|
||||||
server, err := server.NewSocketServer(socket, app)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to the socket
|
|
||||||
client, err := tmspcli.NewSocketClient(socket, false)
|
|
||||||
if err != nil {
|
|
||||||
server.Stop()
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
client.Start()
|
|
||||||
|
|
||||||
return client, server, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeGRPCClientServer(app types.Application, name string) (tmspcli.Client, Service, error) {
|
|
||||||
// Start the listener
|
|
||||||
socket := Fmt("unix://%s.sock", name)
|
|
||||||
|
|
||||||
gapp := types.NewGRPCApplication(app)
|
|
||||||
server, err := server.NewGRPCServer(socket, gapp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
client, err := tmspcli.NewGRPCClient(socket, true)
|
|
||||||
if err != nil {
|
|
||||||
server.Stop()
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return client, server, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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 tmspcli.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 tmspcli.Client, tx []byte, key, value string) {
|
|
||||||
ar := app.AppendTxSync(tx)
|
|
||||||
require.False(t, ar.IsErr(), ar)
|
|
||||||
// repeating tx doesn't raise error
|
|
||||||
ar = app.AppendTxSync(tx)
|
|
||||||
require.False(t, ar.IsErr(), ar)
|
|
||||||
|
|
||||||
// make sure query is fine
|
|
||||||
r := app.QuerySync([]byte(key))
|
|
||||||
require.False(t, r.IsErr(), r)
|
|
||||||
q := new(QueryResult)
|
|
||||||
err := wire.ReadJSONBytes(r.Data, q)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.Equal(t, value, q.Value)
|
|
||||||
|
|
||||||
// make sure proof is fine
|
|
||||||
rp := app.ProofSync([]byte(key), 0)
|
|
||||||
require.False(t, rp.IsErr(), rp)
|
|
||||||
p, err := merkle.LoadProof(rp.Data)
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.True(t, p.Valid())
|
|
||||||
assert.Equal(t, []byte(key), p.Key())
|
|
||||||
assert.Equal(t, []byte(value), p.Value())
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package dummy
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -136,7 +135,7 @@ func LoadLastBlock(db dbm.DB) (lastBlock LastBlockInfo) {
|
|||||||
wire.ReadBinaryPtr(&lastBlock, r, 0, n, err)
|
wire.ReadBinaryPtr(&lastBlock, r, 0, n, err)
|
||||||
if *err != nil {
|
if *err != nil {
|
||||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||||
log.Crit(fmt.Sprintf("Data has been corrupted or its spec has changed: %v\n", *err))
|
log.Crit(cmn.Fmt("Data has been corrupted or its spec has changed: %v\n", *err))
|
||||||
}
|
}
|
||||||
// TODO: ensure that buf is completely read.
|
// TODO: ensure that buf is completely read.
|
||||||
}
|
}
|
||||||
@ -174,7 +173,7 @@ func (app *PersistentDummyApplication) Validators() (validators []*types.Validat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func MakeValSetChangeTx(pubkey []byte, power uint64) []byte {
|
func MakeValSetChangeTx(pubkey []byte, power uint64) []byte {
|
||||||
return []byte(fmt.Sprintf("val:%X/%d", pubkey, power))
|
return []byte(cmn.Fmt("val:%X/%d", pubkey, power))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValidatorTx(tx []byte) bool {
|
func isValidatorTx(tx []byte) bool {
|
||||||
@ -189,16 +188,16 @@ func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.Result {
|
|||||||
tx = tx[len(ValidatorSetChangePrefix):]
|
tx = tx[len(ValidatorSetChangePrefix):]
|
||||||
pubKeyAndPower := strings.Split(string(tx), "/")
|
pubKeyAndPower := strings.Split(string(tx), "/")
|
||||||
if len(pubKeyAndPower) != 2 {
|
if len(pubKeyAndPower) != 2 {
|
||||||
return types.ErrEncodingError.SetLog(fmt.Sprintf("Expected 'pubkey/power'. Got %v", pubKeyAndPower))
|
return types.ErrEncodingError.SetLog(cmn.Fmt("Expected 'pubkey/power'. Got %v", pubKeyAndPower))
|
||||||
}
|
}
|
||||||
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
||||||
pubkey, err := hex.DecodeString(pubkeyS)
|
pubkey, err := hex.DecodeString(pubkeyS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ErrEncodingError.SetLog(fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS))
|
return types.ErrEncodingError.SetLog(cmn.Fmt("Pubkey (%s) is invalid hex", pubkeyS))
|
||||||
}
|
}
|
||||||
power, err := strconv.Atoi(powerS)
|
power, err := strconv.Atoi(powerS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ErrEncodingError.SetLog(fmt.Sprintf("Power (%s) is not an int", powerS))
|
return types.ErrEncodingError.SetLog(cmn.Fmt("Power (%s) is not an int", powerS))
|
||||||
}
|
}
|
||||||
|
|
||||||
// update
|
// update
|
||||||
@ -211,14 +210,14 @@ func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types
|
|||||||
if v.Power == 0 {
|
if v.Power == 0 {
|
||||||
// remove validator
|
// remove validator
|
||||||
if !app.app.state.Has(key) {
|
if !app.app.state.Has(key) {
|
||||||
return types.ErrUnauthorized.SetLog(fmt.Sprintf("Cannot remove non-existent validator %X", key))
|
return types.ErrUnauthorized.SetLog(cmn.Fmt("Cannot remove non-existent validator %X", key))
|
||||||
}
|
}
|
||||||
app.app.state.Remove(key)
|
app.app.state.Remove(key)
|
||||||
} else {
|
} else {
|
||||||
// add or update validator
|
// add or update validator
|
||||||
value := bytes.NewBuffer(make([]byte, 0))
|
value := bytes.NewBuffer(make([]byte, 0))
|
||||||
if err := types.WriteMessage(v, value); err != nil {
|
if err := types.WriteMessage(v, value); err != nil {
|
||||||
return types.ErrInternalError.SetLog(fmt.Sprintf("Error encoding validator: %v", err))
|
return types.ErrInternalError.SetLog(cmn.Fmt("Error encoding validator: %v", err))
|
||||||
}
|
}
|
||||||
app.app.state.Set(key, value.Bytes())
|
app.app.state.Set(key, value.Bytes())
|
||||||
}
|
}
|
||||||
|
@ -41,14 +41,14 @@ func testStream(t *testing.T, app types.Application) {
|
|||||||
// Start the listener
|
// Start the listener
|
||||||
server, err := server.NewSocketServer("unix://test.sock", app)
|
server, err := server.NewSocketServer("unix://test.sock", app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(fmt.Sprintf("Error starting socket server: %v", err.Error()))
|
log.Fatal(cmn.Fmt("Error starting socket server: %v", err.Error()))
|
||||||
}
|
}
|
||||||
defer server.Stop()
|
defer server.Stop()
|
||||||
|
|
||||||
// Connect to the socket
|
// Connect to the socket
|
||||||
client, err := abcicli.NewSocketClient("unix://test.sock", false)
|
client, err := abcicli.NewSocketClient("unix://test.sock", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(fmt.Sprintf("Error starting socket client: %v", err.Error()))
|
log.Fatal(cmn.Fmt("Error starting socket client: %v", err.Error()))
|
||||||
}
|
}
|
||||||
client.Start()
|
client.Start()
|
||||||
defer client.Stop()
|
defer client.Stop()
|
||||||
@ -114,14 +114,14 @@ func testGRPCSync(t *testing.T, app *types.GRPCApplication) {
|
|||||||
// Start the listener
|
// Start the listener
|
||||||
server, err := server.NewGRPCServer("unix://test.sock", app)
|
server, err := server.NewGRPCServer("unix://test.sock", app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(fmt.Sprintf("Error starting GRPC server: %v", err.Error()))
|
log.Fatal(cmn.Fmt("Error starting GRPC server: %v", err.Error()))
|
||||||
}
|
}
|
||||||
defer server.Stop()
|
defer server.Stop()
|
||||||
|
|
||||||
// Connect to the socket
|
// Connect to the socket
|
||||||
conn, err := grpc.Dial("unix://test.sock", grpc.WithInsecure(), grpc.WithDialer(dialerFunc))
|
conn, err := grpc.Dial("unix://test.sock", grpc.WithInsecure(), grpc.WithDialer(dialerFunc))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(fmt.Sprintf("Error dialing GRPC server: %v", err.Error()))
|
log.Fatal(cmn.Fmt("Error dialing GRPC server: %v", err.Error()))
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
-> data.hex: 750502FC7E84BBD788ED589624F06CFA871845D1
|
-> data.hex: 750502FC7E84BBD788ED589624F06CFA871845D1
|
||||||
|
|
||||||
> query "abc"
|
> query "abc"
|
||||||
-> value: abc
|
|
||||||
-> value.hex: 616263
|
|
||||||
-> log: exists
|
-> log: exists
|
||||||
-> height: 0
|
-> height: 0
|
||||||
|
-> value: abc
|
||||||
|
-> value.hex: 616263
|
||||||
|
|
||||||
> deliver_tx "def=xyz"
|
> deliver_tx "def=xyz"
|
||||||
|
|
||||||
@ -31,8 +31,8 @@
|
|||||||
-> data.hex: 76393B8A182E450286B0694C629ECB51B286EFD5
|
-> data.hex: 76393B8A182E450286B0694C629ECB51B286EFD5
|
||||||
|
|
||||||
> query "def"
|
> query "def"
|
||||||
-> value: xyz
|
|
||||||
-> value.hex: 78797A
|
|
||||||
-> log: exists
|
-> log: exists
|
||||||
-> height: 0
|
-> height: 0
|
||||||
|
-> value: xyz
|
||||||
|
-> value.hex: 78797A
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user