Skip to content

[WIP] generalized merkle proofs#1912

Closed
jaekwon wants to merge 8 commits intodevelopfrom
jae/generalmerkle
Closed

[WIP] generalized merkle proofs#1912
jaekwon wants to merge 8 commits intodevelopfrom
jae/generalmerkle

Conversation

@jaekwon
Copy link
Contributor

@jaekwon jaekwon commented Jul 5, 2018

Copy link
Contributor

@mossid mossid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few modifications requested, LGTM.

// Extension of ProofOp (defined in merkle.proto)

func (po ProofOp) Bytes() []byte {
bz, err := amino.MarshalBinary(po)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MustMarshalBinary?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we maybe don't need this function if ProofOpis a member of abci.ResponseQuery because proto will handle marshaling.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

if !bytes.Equal(root, args[0]) {
return cmn.NewError("Calculated root hash is invalid: expected %+v but %+v", root, args[0])
}
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to check len(keys) == 0 before returning nil

}
}

func (prt *ProofRuntime) RegisterAminoOpDecoder(typ string, opType reflect.Type) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to have generator function instead of reflect.Type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine, esp for something called AminoOpDecoder.

computedHash := computeHashFromAunts(index, total, leafHash, sp.Aunts)
return computedHash != nil && bytes.Equal(computedHash, rootHash)
// Verify that the SimpleProof proves the root hash.
func (sp *SimpleProof) Verify(rootHash []byte, index int, total int, leafHash []byte) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we exclude index int, total int, leafHash []byte from the argument list? The fields are exported, the user can check it manually when they need to. Or we can make a new method like Validate to check the fields' validity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can exclude index/total, but we should leave rootHash and leafHash. The other two we can expose GetIndex() and GetTotal(). We should add a comment that the user should check these if they need to verify this info.

@codecov-io
Copy link

codecov-io commented Jul 8, 2018

Codecov Report

Merging #1912 into jae/literefactor4 will decrease coverage by 1.18%.
The diff coverage is 21.42%.

@@                  Coverage Diff                  @@
##           jae/literefactor4    #1912      +/-   ##
=====================================================
- Coverage              61.24%   60.06%   -1.19%     
=====================================================
  Files                    191      162      -29     
  Lines                  15421    13527    -1894     
=====================================================
- Hits                    9445     8125    -1320     
+ Misses                  5128     4649     -479     
+ Partials                 848      753      -95
Impacted Files Coverage Δ
abci/example/kvstore/kvstore.go 80.64% <ø> (ø) ⬆️
crypto/merkle/proof.go 0% <0%> (ø)
crypto/merkle/proof_simple_value.go 0% <0%> (ø)
rpc/client/mock/client.go 20% <0%> (ø) ⬆️
crypto/merkle/wire.go 100% <100%> (ø)
rpc/client/mock/abci.go 80.76% <100%> (ø) ⬆️
types/block.go 29.84% <100%> (ø)
abci/example/kvstore/persistent_kvstore.go 64.04% <100%> (ø) ⬆️
crypto/merkle/merkle.pb.go 14.28% <14.28%> (ø)
crypto/merkle/simple_proof.go 69.23% <90.9%> (+4.11%) ⬆️
... and 117 more

version = "~0.10.1"

[[constraint]]
name = "github.com/tendermint/iavl"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we exclude IAVL dependency from tendermint? IAVL repo will be moved into the SDK, making dependency cycle. The only part in this code that uses IAVL directly is abci example, which can be reverted or moved into the SDK. @liamsi @ebuchman

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked to bucky recently and figured we'll move it into tendermint/tendermint because it's useful to have them for the abci/example/kvstore app.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Truth is that it will still be much more convenient to have it in the SDK as that is where it is primarily used and thus putting it there will maximally reduce developer overhead when changes need to be made. So I'd still advocate for putting it in the SDK and not requiring it in Tendermint if possible

type State struct {
db dbm.DB
db dbm.DB
tree *iavl.VersionedTree
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above

var path KeyPath
keys := make([][]byte, 10)

for d := 0; d < 20; d++ {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe 1e4 or 1e5?

Copy link
Contributor

@liamsi liamsi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1st pass while going through the changes. Will follow up with a more detailed review shortly.

bytes key = 6;
bytes value = 7;
bytes proof = 8;
merkle.Proof proof = 8;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This will be breaking.

protoc --gogo_out=. -I $GOPATH/src/ -I . -I $GOPATH/src/github.com/gogo/protobuf/protobuf merkle.proto
echo "--> adding nolint declarations to protobuf generated files"
awk '/package merkle/ { print "//nolint: gas"; print; next }1' merkle.pb.go > merkle.pb.go.new
mv merkle.pb.go.new merkle.pb.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: proto files often are compiled using a gen.go file. See here for example: https://github.com/google/trillian/blob/e856bae55959e54d2e480790d7c881aced7a4b5c/gen.go#L15-L24

Not sure if this works with gogoproto though.


func RegisterWire(cdc *amino.Codec) {
// Nothing to do.
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I see, this file's only intention is to provide a global variable which does not hold any state. Should we remove RegisterWire and Seal the codec instead?


NOTE: Punycode will never be supported here, because not all values can be
decoded. For example, no string decodes to the string "xn--blah" in
Punycode.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should continue reading first but if it is unsupported / disallowed, it would be great to have a test-case showing what happens if punycode is used.

// ProofOp gets converted to an instance of ProofOperator:

type ProofOperator interface {
Run([][]byte) ([][]byte, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As someone not involved in the reasoning / design of these changes, it is unclear what Run will do (and what it will return) in this context.

// (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}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't the equivalent of Trusted: false be Prove: true instead?

@xla xla changed the title WIP generalized merkle proofs [WIP] generalized merkle proofs Jul 18, 2018
@liamsi liamsi added the C:light Component: Light label Jul 30, 2018
@liamsi
Copy link
Contributor

liamsi commented Jul 30, 2018

Also linking #2052 as both PRs have jae/literefactor4 as a base branch.

@liamsi
Copy link
Contributor

liamsi commented Jul 31, 2018

@mossid I'll submit a PR to resolve above merge conflicts (I'm not if I can push here directly). I'll do so without changing above base branch jae/literefactor4 (for now). After that and when all issues are resolved, we can change the base branch to develop. (Still need to confirm with @jaekwon if this should go into develop or into jae/literefactor4).

@mossid: I think the easiest way to unblock yourself on the outdated protofiles / merge conflicts would be to cherrypick the latest two commits from: https://github.com/tendermint/tendermint/compare/jae/literefactor4...Liamsi:jae/generalmerkle?expand=1
(namely 58fb372 and e9fc2c1)

These changes resolve the merge conflicts, regenerate all relevant protos. They also contain some changes to gogoproto params (and consequential changes).

Let me know if this works for you.


for i, op := range poz {
key := op.GetKey()
if len(key) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add the code for checking the length of the remaining keys for preventing panic if the keypath is too short?

@xla xla added this to the launch milestone Aug 27, 2018
@liamsi liamsi changed the base branch from jae/literefactor4 to develop August 29, 2018 23:44
@ebuchman
Copy link
Contributor

Closing for #2298

@ebuchman ebuchman closed this Sep 12, 2018
@mircea-c mircea-c deleted the jae/generalmerkle branch October 10, 2019 15:28
@mircea-c mircea-c restored the jae/generalmerkle branch October 10, 2019 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C:light Component: Light

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants