Skip to content

Commit

Permalink
R4R: Fix merkle proof verification (#122)
Browse files Browse the repository at this point in the history
* Fix merkle proof verification

* existence iavl proof and iavl absence proof

* make lcd test with proof verification
  • Loading branch information
HaoyangLiu authored May 23, 2019
1 parent 4847726 commit 6b338b0
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 7 deletions.
7 changes: 5 additions & 2 deletions client/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import (
const ctxAccStoreName = "acc"

var (
verifier tmlite.Verifier
verifier tmlite.Verifier
verifierHome string
)

// CLIContext implements a typical CLI context created in SDK modules for
Expand All @@ -46,6 +47,7 @@ type CLIContext struct {
JSON bool
PrintResponse bool
Verifier tmlite.Verifier
VerifierHome string
DryRun bool
GenerateOnly bool
fromAddress types.AccAddress
Expand All @@ -67,8 +69,9 @@ func NewCLIContext() CLIContext {
fromAddress, fromName := fromFields(from)

// We need to use a single verifier for all contexts
if verifier == nil {
if verifier == nil || verifierHome != viper.GetString(cli.HomeFlag) {
verifier = createVerifier()
verifierHome = viper.GetString(cli.HomeFlag)
}

return CLIContext{
Expand Down
10 changes: 9 additions & 1 deletion client/context/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,17 @@ func (ctx CLIContext) verifyProof(queryPath string, resp abci.ResponseQuery) err
kp = kp.AppendKey([]byte(storeName), merkle.KeyEncodingURL)
kp = kp.AppendKey(resp.Key, merkle.KeyEncodingURL)

if resp.Value == nil {
err = prt.VerifyAbsence(resp.Proof, commit.Header.AppHash, kp.String())
if err != nil {
return errors.Wrap(err, "failed to prove merkle absence proof")
}
return nil
}

err = prt.VerifyValue(resp.Proof, commit.Header.AppHash, kp.String(), resp.Value)
if err != nil {
return errors.Wrap(err, "failed to prove merkle proof")
return errors.Wrap(err, "failed to prove merkle existence proof")
}

return nil
Expand Down
3 changes: 1 addition & 2 deletions client/lcd/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,7 @@ func InitializeTestLCD(
// XXX: Need to set this so LCD knows the tendermint node address!
viper.Set(client.FlagNode, config.RPC.ListenAddress)
viper.Set(client.FlagChainID, genDoc.ChainID)
// TODO Set to false once the upstream Tendermint proof verification issue is fixed.
viper.Set(client.FlagTrustNode, true)
viper.Set(client.FlagTrustNode, false)
dir, err := ioutil.TempDir("", "lcd_test")
require.NoError(t, err)
viper.Set(cli.HomeFlag, dir)
Expand Down
17 changes: 15 additions & 2 deletions store/iavlstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,21 @@ func (st *IavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
res.Log = err.Error()
break
}
res.Value = value
res.Proof = &merkle.Proof{Ops: []merkle.ProofOp{iavl.NewIAVLValueOp(key, proof).ProofOp()}}
if proof == nil {
// Proof == nil implies that the store is empty.
if value != nil {
panic("unexpected value for an empty proof")
}
}
if value != nil {
// value was found
res.Value = value
res.Proof = &merkle.Proof{Ops: []merkle.ProofOp{iavl.NewIAVLValueOp(key, proof).ProofOp()}}
} else {
// value wasn't found
res.Value = nil
res.Proof = &merkle.Proof{Ops: []merkle.ProofOp{iavl.NewIAVLAbsenceOp(key, proof).ProofOp()}}
}
} else {
_, res.Value = tree.GetVersioned(key, res.Height)
}
Expand Down

0 comments on commit 6b338b0

Please sign in to comment.