From 9725316d1fa650e761c3a7aa57f5ed44130161ad Mon Sep 17 00:00:00 2001 From: mossid Date: Wed, 12 Jun 2019 14:06:17 +0200 Subject: [PATCH] add test for proving --- x/ibc/23-commitment/README.md | 2 +- x/ibc/23-commitment/merkle/merkle.go | 9 ++- x/ibc/23-commitment/merkle/merkle_test.go | 72 +++++++++++++++++++++++ x/ibc/23-commitment/store.go | 6 +- 4 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 x/ibc/23-commitment/merkle/merkle_test.go diff --git a/x/ibc/23-commitment/README.md b/x/ibc/23-commitment/README.md index 61a46b99d8a4..759128b0c6de 100644 --- a/x/ibc/23-commitment/README.md +++ b/x/ibc/23-commitment/README.md @@ -24,7 +24,7 @@ an argument for `spec: verifyMembership` / `spec: verifyNonMembership`, construc `type Root` implements `spec: type CommitmentRoot`. In Cosmos-SDK implementation, `Root` will be the `AppHash []byte`, and `Proof` will be `merkle.Proof`, which consists -of `SimpleProof` and `IAVLValueProof` +of `SimpleProof` and `IAVLValueProof`. Defined in `merkle/` ### store.go diff --git a/x/ibc/23-commitment/merkle/merkle.go b/x/ibc/23-commitment/merkle/merkle.go index 8e234f4873fe..1eb48385afad 100644 --- a/x/ibc/23-commitment/merkle/merkle.go +++ b/x/ibc/23-commitment/merkle/merkle.go @@ -3,9 +3,10 @@ package merkle import ( "errors" - "github.com/tendermint/iavl" "github.com/tendermint/tendermint/crypto/merkle" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" ) @@ -38,9 +39,7 @@ func (proof Proof) Verify(croot commitment.Root, value []byte) error { return err } // Hard coded for now - runtime := merkle.DefaultProofRuntime() - runtime.RegisterOpDecoder(iavl.ProofOpIAVLAbsence, iavl.IAVLAbsenceOpDecoder) - runtime.RegisterOpDecoder(iavl.ProofOpIAVLValue, iavl.IAVLValueOpDecoder) + runtime := rootmulti.DefaultProofRuntime() if value != nil { return runtime.VerifyValue(proof.Proof, root, keypath.String(), value) @@ -61,7 +60,7 @@ func PrefixKeyPath(prefix string, key []byte) (res merkle.KeyPath, err error) { return } - keys[len(keys)-1] = append(keys[len(keys)], key...) + keys[len(keys)-1] = append(keys[len(keys)-1], key...) for _, key := range keys { res = res.AppendKey(key, merkle.KeyEncodingHex) diff --git a/x/ibc/23-commitment/merkle/merkle_test.go b/x/ibc/23-commitment/merkle/merkle_test.go new file mode 100644 index 000000000000..e252a13268c5 --- /dev/null +++ b/x/ibc/23-commitment/merkle/merkle_test.go @@ -0,0 +1,72 @@ +package merkle + +import ( + "testing" + + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment" +) + +func defaultComponents() (sdk.StoreKey, sdk.Context, types.CommitMultiStore, *codec.Codec) { + key := sdk.NewKVStoreKey("ibc") + db := dbm.NewMemDB() + cms := store.NewCommitMultiStore(db) + cms.MountStoreWithDB(key, sdk.StoreTypeIAVL, db) + err := cms.LoadLatestVersion() + if err != nil { + panic(err) + } + ctx := sdk.NewContext(cms, abci.Header{}, false, log.NewNopLogger()) + cdc := codec.New() + return key, ctx, cms, cdc +} + +func key(str string) []byte { + return append([]byte{0x00}, []byte(str)...) +} + +func query(t *testing.T, cms types.CommitMultiStore, k string) (value []byte, proof Proof) { + qres := cms.(types.Queryable).Query(abci.RequestQuery{Path: "/ibc/key", Data: key(k), Prove: true}) + require.Equal(t, uint32(0), qres.Code, qres.Log) + value = qres.Value + proof = Proof{ + Key: []byte(k), + Proof: qres.Proof, + } + return +} + +func TestStore(t *testing.T) { + k, ctx, cms, _ := defaultComponents() + kvstore := ctx.KVStore(k) + + kvstore.Set(key("hello"), []byte("world")) + kvstore.Set(key("merkle"), []byte("tree")) + kvstore.Set(key("block"), []byte("chain")) + + cid := cms.Commit() + + v1, p1 := query(t, cms, "hello") + require.Equal(t, []byte("world"), v1) + v2, p2 := query(t, cms, "merkle") + require.Equal(t, []byte("tree"), v2) + v3, p3 := query(t, cms, "block") + require.Equal(t, []byte("chain"), v3) + + cstore, err := commitment.NewStore(cid.Hash, []commitment.Proof{p1, p2, p3}) + require.NoError(t, err) + + require.True(t, cstore.Prove([]byte("hello"), []byte("world"))) + require.True(t, cstore.Prove([]byte("merkle"), []byte("tree"))) + require.True(t, cstore.Prove([]byte("block"), []byte("chain"))) +} diff --git a/x/ibc/23-commitment/store.go b/x/ibc/23-commitment/store.go index a82c59cc5fd7..bdc0bb8902dc 100644 --- a/x/ibc/23-commitment/store.go +++ b/x/ibc/23-commitment/store.go @@ -2,6 +2,7 @@ package commitment import ( "bytes" + "fmt" ) type Store interface { @@ -35,7 +36,7 @@ type store struct { } // Proofs must be provided -func Newstore(root Root, proofs []Proof) (res store, err error) { +func NewStore(root Root, proofs []Proof) (res store, err error) { res = store{ root: root, proofs: make(map[string]Proof), @@ -57,14 +58,17 @@ func (store store) Get(key []byte) ([]byte, bool) { func (store store) Prove(key, value []byte) bool { stored, ok := store.Get(key) if ok && bytes.Equal(stored, value) { + fmt.Println(1) return true } proof, ok := store.proofs[string(key)] if !ok { + fmt.Println(2) return false } err := proof.Verify(store.root, value) if err != nil { + fmt.Println(err) return false } store.verified[string(key)] = value