-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] General Merkle Proof #2298
[WIP] General Merkle Proof #2298
Conversation
25fc69e
to
aacba15
Compare
Should we close #2296 then? |
6b253b0
to
8eac3bc
Compare
@ValarDragon That PR is for making reference squashed branch, so I think it is good to close that. |
Codecov Report
@@ Coverage Diff @@
## develop #2298 +/- ##
==========================================
Coverage ? 61.16%
==========================================
Files ? 202
Lines ? 16658
Branches ? 0
==========================================
Hits ? 10189
Misses ? 5600
Partials ? 869
|
Ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments. Mostly about documentation and few. But I also still think, we might split this up into two PRs: the general merkle stuff and the examples? It will make this slightly easier to review, too.
There are a bunch of TODOs and XXXs in the PR. If they won't be addressed in this PR, can we open an issue that summarizes what is letft to be done?
A brief description in an issue what the overall goal is, would be beneficial too.
consensus/common_test.go
Outdated
@@ -39,7 +39,7 @@ const ( | |||
|
|||
// genesis, chain_id, priv_val | |||
var config *cfg.Config // NOTE: must be reset for each _test.go file | |||
var ensureTimeout = time.Second * 1 // must be in seconds because CreateEmptyBlocksInterval is | |||
var ensureTimeout = time.Second * 5 // must be in seconds because CreateEmptyBlocksInterval is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do need to increase the timeout here?
crypto/merkle/simple_proof.go
Outdated
"fmt" | ||
|
||
cmn "github.com/tendermint/tmlibs/common" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use common package in tendermint
crypto/merkle/simple_tree_test.go
Outdated
if ok { | ||
t.Errorf("Expected verification to fail for wrong trail length.") | ||
err = proof.Verify(rootHash, itemHash) | ||
if err == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency: can we use require.Error
here? And everywhere else?
require.NoError(err, "%#v", err) | ||
// require.NotNil(proof) | ||
// TODO: Ensure that *some* keys will be there, ensuring that proof is nil, | ||
// (currently there's a race condition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there still a race condition?
resQuery, err := proxyAppQuery.QuerySync(abci.RequestQuery{ | ||
Path: path, | ||
Data: data, | ||
Height: height, | ||
Prove: !trusted, | ||
Prove: prove, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everywhere else prove
is just a renaming of trusted
. Why is it different here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is because this was the place where the trusted
finally converted into prove
which abci.RequestQuery
wants.
Would be really great if we could get an ADR here that explains what we're trying to do, why, and how. Would also help orient folks looking at cosmos/iavl#105 |
finalize rebase add protoc_merkle to Makefile
fix test_apps
9bc4bd6
to
02eb642
Compare
@mossid thanks for updating - is this still a WIP or want to remove that? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, other than some deficiencies in documentation, both in code and the docs/spec/abci/
dir (since we're updating ABCI). We also need an ADR. There's also a few TODO/XXX that we should probably track in new issues.
We also need to update CHANGELOG. This is a breaking change to:
- [abci] ResponseQuery
- [rpc] /abci_query takes
prove
instead oftrusted
and switches the default behaviour toprove=false
cmn "github.com/tendermint/tendermint/libs/common" | ||
) | ||
|
||
const ProofOpSimpleValue = "simple:v" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should include the encoding scheme in here? eg. amino
? or maybe use IPFS multicodec: https://github.com/multiformats/multicodec
|
||
for i, op := range poz { | ||
key := op.GetKey() | ||
if len(key) != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the meaning of an op with an empty key, and should it still be represented in the keypath? Should we have len(poz) == len(keys)
?
// GetWithProofOptions is useful if you want full access to the ABCIQueryOptions | ||
func GetWithProofOptions(path string, key []byte, opts rpcclient.ABCIQueryOptions, | ||
// GetWithProofOptions is useful if you want full access to the ABCIQueryOptions. | ||
// XXX Usage of path? It's not used, and sometimes it's /, sometimes /key, sometimes /store. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was noted in #2090. Added a small comment to docs (d8d268f#diff-69fe72a9f14b8f1a14776025eb902ed3R239) to address this but maybe issue should be re-opened?
@@ -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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, was this wrong before? Trusted
should mean don't Prove
.
func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { | ||
res := ctypes.ResultBroadcastTxCommit{} | ||
res.CheckTx = a.App.CheckTx(tx) | ||
if res.CheckTx.IsErr() { | ||
return &res, nil | ||
} | ||
res.DeliverTx = a.App.DeliverTx(tx) | ||
res.Height = -1 // TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
@@ -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}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true?
I'll address some of my comments and open an issue for the rest. Thanks. |
* tmlibs -> libs * update changelog * address some comments from review of #2298
} | ||
|
||
// | height | int64 | 0 | false | Height (0 means latest) | | ||
// | prove | bool | false | false | Includes proof if true | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want proofs by default?
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in what future? under what conditions?
cert := lite.NewBaseVerifier(chainID, seed.Height(), seed.Validators) | ||
|
||
// Wait for tx confirmation. | ||
done := make(chan int64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
txConfirmedCh
|
||
func init() { | ||
cdc = amino.NewCodec() | ||
cdc.Seal() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what Seal()
does? prevents future modifications?
// Check sp.Index/sp.Total manually if needed | ||
func (sp *SimpleProof) Verify(rootHash []byte, leafHash []byte) error { | ||
if sp.Total < 0 { | ||
return errors.New("Proof total must be positive") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cannot be negative
|
||
for i := range keys { | ||
enc := keyEncoding(rand.Intn(int(KeyEncodingMax))) | ||
keys[i] = make([]byte, rand.Uint32()%20) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
20
magic const
cmn "github.com/tendermint/tendermint/libs/common" | ||
) | ||
|
||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
non-standard comment style https://blog.golang.org/godoc-documenting-go-code
func (prt *ProofRuntime) Decode(pop ProofOp) (ProofOperator, error) { | ||
decoder := prt.decoders[pop.Type] | ||
if decoder == nil { | ||
return nil, cmn.NewError("unrecognized proof type %v", pop.Type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no decoder for proof type %v
|
||
type OpDecoder func(ProofOp) (ProofOperator, error) | ||
|
||
type ProofRuntime struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
godoc is missing
key := op.GetKey() | ||
if len(key) != 0 { | ||
if !bytes.Equal(keys[0], key) { | ||
return cmn.NewError("Key mismatch on operation #%d: expected %+v but %+v", i, []byte(keys[0]), []byte(key)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
, but got
Closes: #2502