mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-05 13:05:09 +00:00
General Merkle Proof (#2298)
* first commit finalize rebase add protoc_merkle to Makefile * in progress * fix kvstore * fix tests * remove iavl dependency * fix tx_test * fix test_abci_cli fix test_apps * fix test_apps * fix test_cover * rm rebase residue * address comment in progress * finalize rebase
This commit is contained in:
@@ -75,7 +75,7 @@ func (c *HTTP) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQuer
|
||||
func (c *HTTP) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
result := new(ctypes.ResultABCIQuery)
|
||||
_, err := c.rpc.Call("abci_query",
|
||||
map[string]interface{}{"path": path, "data": data, "height": opts.Height, "trusted": opts.Trusted},
|
||||
map[string]interface{}{"path": path, "data": data, "height": opts.Height, "prove": opts.Prove},
|
||||
result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ABCIQuery")
|
||||
|
||||
@@ -61,7 +61,7 @@ func (c *Local) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQue
|
||||
}
|
||||
|
||||
func (Local) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
return core.ABCIQuery(path, data, opts.Height, opts.Trusted)
|
||||
return core.ABCIQuery(path, data, opts.Height, opts.Prove)
|
||||
}
|
||||
|
||||
func (Local) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
|
||||
@@ -31,10 +31,18 @@ func (a ABCIApp) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQu
|
||||
}
|
||||
|
||||
func (a ABCIApp) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
q := a.App.Query(abci.RequestQuery{Data: data, Path: path, Height: opts.Height, Prove: opts.Trusted})
|
||||
q := a.App.Query(abci.RequestQuery{
|
||||
Data: data,
|
||||
Path: path,
|
||||
Height: opts.Height,
|
||||
Prove: opts.Prove,
|
||||
})
|
||||
return &ctypes.ResultABCIQuery{q}, nil
|
||||
}
|
||||
|
||||
// NOTE: Caller should call a.App.Commit() separately,
|
||||
// this function does not actually wait for a commit.
|
||||
// TODO: Make it wait for a commit and set res.Height appropriately.
|
||||
func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res := ctypes.ResultBroadcastTxCommit{}
|
||||
res.CheckTx = a.App.CheckTx(tx)
|
||||
@@ -42,6 +50,7 @@ func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit
|
||||
return &res, nil
|
||||
}
|
||||
res.DeliverTx = a.App.DeliverTx(tx)
|
||||
res.Height = -1 // TODO
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
@@ -86,7 +95,7 @@ func (m ABCIMock) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQ
|
||||
}
|
||||
|
||||
func (m ABCIMock) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
res, err := m.Query.GetResponse(QueryArgs{path, data, opts.Height, opts.Trusted})
|
||||
res, err := m.Query.GetResponse(QueryArgs{path, data, opts.Height, opts.Prove})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -133,10 +142,10 @@ func NewABCIRecorder(client client.ABCIClient) *ABCIRecorder {
|
||||
}
|
||||
|
||||
type QueryArgs struct {
|
||||
Path string
|
||||
Data cmn.HexBytes
|
||||
Height int64
|
||||
Trusted bool
|
||||
Path string
|
||||
Data cmn.HexBytes
|
||||
Height int64
|
||||
Prove bool
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) addCall(call Call) {
|
||||
@@ -161,7 +170,7 @@ func (r *ABCIRecorder) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts
|
||||
res, err := r.Client.ABCIQueryWithOptions(path, data, opts)
|
||||
r.addCall(Call{
|
||||
Name: "abci_query",
|
||||
Args: QueryArgs{path, data, opts.Height, opts.Trusted},
|
||||
Args: QueryArgs{path, data, opts.Height, opts.Prove},
|
||||
Response: res,
|
||||
Error: err,
|
||||
})
|
||||
|
||||
@@ -51,7 +51,7 @@ func TestABCIMock(t *testing.T) {
|
||||
assert.Equal("foobar", err.Error())
|
||||
|
||||
// query always returns the response
|
||||
_query, err := m.ABCIQueryWithOptions("/", nil, client.ABCIQueryOptions{Trusted: true})
|
||||
_query, err := m.ABCIQueryWithOptions("/", nil, client.ABCIQueryOptions{Prove: false})
|
||||
query := _query.Response
|
||||
require.Nil(err)
|
||||
require.NotNil(query)
|
||||
@@ -98,7 +98,7 @@ func TestABCIRecorder(t *testing.T) {
|
||||
_, err := r.ABCIInfo()
|
||||
assert.Nil(err, "expected no err on info")
|
||||
|
||||
_, err = r.ABCIQueryWithOptions("path", cmn.HexBytes("data"), client.ABCIQueryOptions{Trusted: false})
|
||||
_, err = r.ABCIQueryWithOptions("path", cmn.HexBytes("data"), client.ABCIQueryOptions{Prove: false})
|
||||
assert.NotNil(err, "expected error on query")
|
||||
require.Equal(2, len(r.Calls))
|
||||
|
||||
@@ -122,7 +122,7 @@ func TestABCIRecorder(t *testing.T) {
|
||||
require.True(ok)
|
||||
assert.Equal("path", qa.Path)
|
||||
assert.EqualValues("data", qa.Data)
|
||||
assert.False(qa.Trusted)
|
||||
assert.False(qa.Prove)
|
||||
|
||||
// now add some broadcasts (should all err)
|
||||
txs := []types.Tx{{1}, {2}, {3}}
|
||||
@@ -173,9 +173,17 @@ func TestABCIApp(t *testing.T) {
|
||||
require.NotNil(res.DeliverTx)
|
||||
assert.True(res.DeliverTx.IsOK())
|
||||
|
||||
// commit
|
||||
// TODO: This may not be necessary in the future
|
||||
if res.Height == -1 {
|
||||
m.App.Commit()
|
||||
}
|
||||
|
||||
// check the key
|
||||
_qres, err := m.ABCIQueryWithOptions("/key", cmn.HexBytes(key), client.ABCIQueryOptions{Trusted: true})
|
||||
_qres, err := m.ABCIQueryWithOptions("/key", cmn.HexBytes(key), client.ABCIQueryOptions{Prove: true})
|
||||
qres := _qres.Response
|
||||
require.Nil(err)
|
||||
assert.EqualValues(value, qres.Value)
|
||||
|
||||
// XXX Check proof
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
package mock
|
||||
|
||||
/*
|
||||
package mock returns a Client implementation that
|
||||
accepts various (mock) implementations of the various methods.
|
||||
@@ -11,7 +13,6 @@ For real clients, you probably want the "http" package. If you
|
||||
want to directly call a tendermint node in process, you can use the
|
||||
"local" package.
|
||||
*/
|
||||
package mock
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@@ -87,7 +88,7 @@ func (c Client) ABCIQuery(path string, data cmn.HexBytes) (*ctypes.ResultABCIQue
|
||||
}
|
||||
|
||||
func (c Client) ABCIQueryWithOptions(path string, data cmn.HexBytes, opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
return core.ABCIQuery(path, data, opts.Height, opts.Trusted)
|
||||
return core.ABCIQuery(path, data, opts.Height, opts.Prove)
|
||||
}
|
||||
|
||||
func (c Client) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
|
||||
@@ -166,10 +166,10 @@ func TestAppCalls(t *testing.T) {
|
||||
if err := client.WaitForHeight(c, apph, nil); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Trusted: true})
|
||||
_qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: false})
|
||||
qres := _qres.Response
|
||||
if assert.Nil(err) && assert.True(qres.IsOK()) {
|
||||
// assert.Equal(k, data.GetKey()) // only returned for proofs
|
||||
assert.Equal(k, qres.Key)
|
||||
assert.EqualValues(v, qres.Value)
|
||||
}
|
||||
|
||||
@@ -221,10 +221,12 @@ func TestAppCalls(t *testing.T) {
|
||||
assert.Equal(block.Block.LastCommit, commit2.Commit)
|
||||
|
||||
// and we got a proof that works!
|
||||
_pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Trusted: false})
|
||||
_pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: true})
|
||||
pres := _pres.Response
|
||||
assert.Nil(err)
|
||||
assert.True(pres.IsOK())
|
||||
|
||||
// XXX Test proof
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +312,7 @@ func TestTx(t *testing.T) {
|
||||
// time to verify the proof
|
||||
proof := ptx.Proof
|
||||
if tc.prove && assert.EqualValues(t, tx, proof.Data) {
|
||||
assert.True(t, proof.Proof.Verify(proof.Index, proof.Total, txHash, proof.RootHash))
|
||||
assert.NoError(t, proof.Proof.Verify(proof.RootHash, txHash))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,7 +350,7 @@ func TestTxSearch(t *testing.T) {
|
||||
// time to verify the proof
|
||||
proof := ptx.Proof
|
||||
if assert.EqualValues(t, tx, proof.Data) {
|
||||
assert.True(t, proof.Proof.Verify(proof.Index, proof.Total, txHash, proof.RootHash))
|
||||
assert.NoError(t, proof.Proof.Verify(proof.RootHash, txHash))
|
||||
}
|
||||
|
||||
// query by height
|
||||
@@ -362,7 +364,7 @@ func TestTxSearch(t *testing.T) {
|
||||
require.Len(t, result.Txs, 0)
|
||||
|
||||
// we query using a tag (see kvstore application)
|
||||
result, err = c.TxSearch("app.creator='jae'", false, 1, 30)
|
||||
result, err = c.TxSearch("app.creator='Cosmoshi Netowoko'", false, 1, 30)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
if len(result.Txs) == 0 {
|
||||
t.Fatal("expected a lot of transactions")
|
||||
|
||||
@@ -3,10 +3,9 @@ package client
|
||||
// ABCIQueryOptions can be used to provide options for ABCIQuery call other
|
||||
// than the DefaultABCIQueryOptions.
|
||||
type ABCIQueryOptions struct {
|
||||
Height int64
|
||||
Trusted bool
|
||||
Height int64
|
||||
Prove bool
|
||||
}
|
||||
|
||||
// DefaultABCIQueryOptions are latest height (0) and trusted equal to false
|
||||
// (which will result in a proof being returned).
|
||||
var DefaultABCIQueryOptions = ABCIQueryOptions{Height: 0, Trusted: false}
|
||||
// DefaultABCIQueryOptions are latest height (0) and prove false.
|
||||
var DefaultABCIQueryOptions = ABCIQueryOptions{Height: 0, Prove: false}
|
||||
|
||||
Reference in New Issue
Block a user