[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.
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
| // 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.
why do need to increase the timeout here?
crypto/merkle/simple_proof.go
Outdated
| "errors" | ||
| "fmt" | ||
|
|
||
| cmn "github.com/tendermint/tmlibs/common" |
There was a problem hiding this comment.
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.
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.
Is there still a race condition?
| Data: data, | ||
| Height: height, | ||
| Prove: !trusted, | ||
| Prove: prove, |
There was a problem hiding this comment.
Everywhere else prove is just a renaming of trusted. Why is it different here?
There was a problem hiding this comment.
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? |
ebuchman
left a comment
There was a problem hiding this comment.
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
proveinstead oftrustedand switches the default behaviour toprove=false
| cmn "github.com/tendermint/tendermint/libs/common" | ||
| ) | ||
|
|
||
| const ProofOpSimpleValue = "simple:v" |
There was a problem hiding this comment.
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.
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.
Was noted in #2090. Added a small comment to docs (d8d268f#diff-69fe72a9f14b8f1a14776025eb902ed3R239) to address this but maybe issue should be re-opened?
|
|
||
| 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.
Oh, was this wrong before? Trusted should mean don't Prove.
| return &res, nil | ||
| } | ||
| res.DeliverTx = a.App.DeliverTx(tx) | ||
| res.Height = -1 // TODO |
| 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}) |
|
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.
Don't we want proofs by default?
| assert.True(res.DeliverTx.IsOK()) | ||
|
|
||
| // commit | ||
| // TODO: This may not be necessary in the future |
There was a problem hiding this comment.
in what future? under what conditions?
| cert := lite.NewBaseVerifier(chainID, seed.Height(), seed.Validators) | ||
|
|
||
| // Wait for tx confirmation. | ||
| done := make(chan int64) |
|
|
||
| func init() { | ||
| cdc = amino.NewCodec() | ||
| cdc.Seal() |
There was a problem hiding this comment.
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") |
|
|
||
| for i := range keys { | ||
| enc := keyEncoding(rand.Intn(int(KeyEncodingMax))) | ||
| keys[i] = make([]byte, rand.Uint32()%20) |
| cmn "github.com/tendermint/tendermint/libs/common" | ||
| ) | ||
|
|
||
| /* |
There was a problem hiding this comment.
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.
no decoder for proof type %v
|
|
||
| type OpDecoder func(ProofOp) (ProofOperator, error) | ||
|
|
||
| type ProofRuntime struct { |
| 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)) |
Closes: #2502