Merge branch 'abci_proof' into develop

This commit is contained in:
Jae Kwon
2017-01-27 22:27:32 -08:00
26 changed files with 903 additions and 368 deletions

View File

@ -7,34 +7,41 @@ import (
"sort"
"testing"
"github.com/stretchr/testify/require"
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/server"
"github.com/tendermint/abci/types"
cmn "github.com/tendermint/go-common"
"github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire"
merkle "github.com/tendermint/go-merkle"
)
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)
}
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)
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)
}
// make sure query is fine
resQuery := app.Query(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Equal(t, types.CodeType_OK, 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.Equal(t, types.CodeType_OK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
proof, err := merkle.ReadProof(resQuery.Proof)
require.Nil(t, err)
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
}
func TestDummyKV(t *testing.T) {
@ -202,3 +209,102 @@ func valsEqual(t *testing.T, vals1, vals2 []*types.Validator) {
}
}
}
func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
server, err := server.NewSocketServer(socket, app)
if err != nil {
return nil, nil, err
}
// Connect to the socket
client, err := abcicli.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) (abcicli.Client, cmn.Service, error) {
// Start the listener
socket := cmn.Fmt("unix://%s.sock", name)
gapp := types.NewGRPCApplication(app)
server, err := server.NewGRPCServer(socket, gapp)
if err != nil {
return nil, nil, err
}
client, err := abcicli.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 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 := app.DeliverTxSync(tx)
require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error
ar = app.DeliverTxSync(tx)
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, types.CodeType_OK, 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, types.CodeType_OK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
proof, err := merkle.ReadProof(resQuery.Proof)
require.Nil(t, err)
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
}