Remove Proof message, replace with more flexible Query

This commit is contained in:
Jae Kwon
2017-01-27 10:35:27 -08:00
parent 4bdddf9829
commit 2a4894310d
22 changed files with 429 additions and 579 deletions
+4 -6
View File
@@ -57,12 +57,10 @@ func (app *ChainAwareApplication) Commit() types.Result {
return types.NewResultOK([]byte("nil"), "")
}
func (app *ChainAwareApplication) Query(query []byte) types.Result {
return types.NewResultOK([]byte(Fmt("%d,%d", app.beginCount, app.endCount)), "")
}
func (app *ChainAwareApplication) Proof(key []byte, blockHeight uint64) types.Result {
return types.NewResultOK(nil, Fmt("Proof is not supported"))
func (app *ChainAwareApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
return types.ResponseQuery{
Value: []byte(Fmt("%d,%d", app.beginCount, app.endCount)),
}
}
func (app *ChainAwareApplication) BeginBlock(hash []byte, header *types.Header) {
+4 -4
View File
@@ -5,10 +5,10 @@ import (
"strings"
"testing"
. "github.com/tendermint/go-common"
"github.com/tendermint/abci/client"
"github.com/tendermint/abci/server"
"github.com/tendermint/abci/types"
. "github.com/tendermint/go-common"
)
func TestChainAware(t *testing.T) {
@@ -39,10 +39,10 @@ func TestChainAware(t *testing.T) {
client.CommitSync()
}
r := app.Query(nil)
spl := strings.Split(string(r.Data), ",")
r := app.Query(types.RequestQuery{})
spl := strings.Split(string(r.Value), ",")
if len(spl) != 2 {
t.Fatal("expected %d,%d ; got %s", n, n, string(r.Data))
t.Fatal("expected %d,%d ; got %s", n, n, string(r.Value))
}
beginCount, _ := strconv.Atoi(spl[0])
endCount, _ := strconv.Atoi(spl[1])
+5 -10
View File
@@ -71,19 +71,14 @@ func (app *CounterApplication) Commit() types.Result {
}
}
func (app *CounterApplication) Query(query []byte) types.Result {
queryStr := string(query)
func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
switch queryStr {
switch reqQuery.Path {
case "hash":
return types.NewResultOK(nil, Fmt("%v", app.hashCount))
return types.ResponseQuery{Value: []byte(Fmt("%v", app.hashCount))}
case "tx":
return types.NewResultOK(nil, Fmt("%v", app.txCount))
return types.ResponseQuery{Value: []byte(Fmt("%v", app.txCount))}
}
return types.ErrUnknownRequest.SetLog(Fmt("Invalid nonce. Expected hash or tx, got %v", queryStr))
}
func (app *CounterApplication) Proof(key []byte, blockHeight uint64) types.Result {
return types.NewResultOK(nil, Fmt("Proof is not supported"))
return types.ResponseQuery{Log: Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
}
+23 -27
View File
@@ -1,13 +1,11 @@
package dummy
import (
"encoding/hex"
"strings"
"github.com/tendermint/abci/types"
. "github.com/tendermint/go-common"
"github.com/tendermint/go-merkle"
"github.com/tendermint/go-wire"
)
type DummyApplication struct {
@@ -47,30 +45,28 @@ func (app *DummyApplication) Commit() types.Result {
return types.NewResultOK(hash, "")
}
func (app *DummyApplication) Query(query []byte) types.Result {
index, value, exists := app.state.Get(query)
queryResult := QueryResult{index, string(value), hex.EncodeToString(value), exists}
return types.NewResultOK(wire.JSONBytes(queryResult), "")
}
func (app *DummyApplication) Proof(key []byte, blockHeight uint64) types.Result {
// TODO: when go-merkle supports querying older blocks without possible panics,
// we should store a cache and allow a query. But for now it is impossible.
// And this is just a Dummy application anyway, what do you expect? ;)
if blockHeight != 0 {
return types.ErrUnknownRequest
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
if reqQuery.Prove {
value, proof, exists := app.state.Proof(reqQuery.Data)
resQuery.Index = -1 // TODO make Proof return index
resQuery.Key = reqQuery.Data
resQuery.Value = value
resQuery.Proof = proof
if exists {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
} else {
index, value, exists := app.state.Get(reqQuery.Data)
resQuery.Index = int64(index)
resQuery.Value = value
if exists {
resQuery.Log = "exists"
} else {
resQuery.Log = "does not exist"
}
return
}
proof, exists := app.state.Proof(key)
if !exists {
return types.NewResultOK(nil, Fmt("Cannot find key = %v", key))
}
return types.NewResultOK(proof, "Found the key")
}
type QueryResult struct {
Index int `json:"index"`
Value string `json:"value"`
ValueHex string `json:"valueHex"`
Exists bool `json:"exists"`
}
+31 -25
View File
@@ -6,7 +6,6 @@ import (
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
abcicli "github.com/tendermint/abci/client"
"github.com/tendermint/abci/server"
@@ -14,7 +13,6 @@ import (
. "github.com/tendermint/go-common"
"github.com/tendermint/go-crypto"
merkle "github.com/tendermint/go-merkle"
"github.com/tendermint/go-wire"
)
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
@@ -25,21 +23,24 @@ func testDummy(t *testing.T, app types.Application, tx []byte, key, value string
require.False(t, ar.IsErr(), ar)
// 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)
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
rp := app.Proof([]byte(key), 0)
require.False(t, rp.IsErr(), rp)
p, err := merkle.LoadProof(rp.Data)
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, p.Valid())
assert.Equal(t, []byte(key), p.Key())
assert.Equal(t, []byte(value), p.Value())
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) {
@@ -285,19 +286,24 @@ func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string)
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)
resQuery, err := app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
})
require.Nil(t, err)
require.Equal(t, value, q.Value)
require.Equal(t, types.CodeType_OK, resQuery.Code)
require.Equal(t, value, string(resQuery.Value))
// make sure proof is fine
rp := app.ProofSync([]byte(key), 0)
require.False(t, rp.IsErr(), rp)
p, err := merkle.LoadProof(rp.Data)
resQuery, err = app.QuerySync(types.RequestQuery{
Path: "/store",
Data: []byte(key),
Prove: true,
})
require.Nil(t, err)
require.True(t, p.Valid())
assert.Equal(t, []byte(key), p.Key())
assert.Equal(t, []byte(value), p.Value())
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
}
+2 -6
View File
@@ -89,12 +89,8 @@ func (app *PersistentDummyApplication) Commit() types.Result {
return types.NewResultOK(appHash, "")
}
func (app *PersistentDummyApplication) Query(query []byte) types.Result {
return app.app.Query(query)
}
func (app *PersistentDummyApplication) Proof(key []byte, blockHeight uint64) types.Result {
return app.app.Proof(key, blockHeight)
func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
return app.app.Query(reqQuery)
}
// Save the validators in the merkle tree
+2 -6
View File
@@ -31,10 +31,6 @@ func (app *NilApplication) Commit() types.Result {
return types.NewResultOK([]byte("nil"), "")
}
func (app *NilApplication) Query(query []byte) types.Result {
return types.NewResultOK(nil, "")
}
func (app *NilApplication) Proof(key []byte, blockHeight uint64) types.Result {
return types.NewResultOK(nil, "")
func (app *NilApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
return resQuery
}