Skip to content

Commit

Permalink
add README, keypath
Browse files Browse the repository at this point in the history
  • Loading branch information
mossid committed Jun 11, 2019
1 parent 927b4be commit d170b46
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
50 changes: 50 additions & 0 deletions x/ibc/23-commitment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ICS 23: Commitment

Package `commitment` defines types and methods to verify other chain's state. The main type is `Store`, containing
proofs that can be verified when the correct value is provided. The spec functions those are directly related to
verification are:

## Spec

```typescript
type verifyMembership = (root: CommitmentRoot, proof: CommitmentProof, key: Key, value: Value) => bool
type verifyNonMembership = (root: CommitmentRoot, proof: CommitmentProof, key: Key) => bool
```
## Impl
### types.go
`type Proof` implements `spec: type CommitmentProof`. CommitmentProof is an arbitrary object which can be used as
an argument for `spec: verifyMembership` / `spec: verifyNonMembership`, constructed with `spec: createMembershipProof` /
`spec: createNonMembershipProof`. The implementation type `Proof` defines `spec: verify(Non)Membership` as its method
`Verify(Root, []byte) error`, which takes the commitment root and the value bytes argument. The method acts as
`spec: verifyMembership` when the value bytes is not nil, and `spec: verifyNonMembership` if it is nil.
`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`
### store.go
`Store` assumes that the keys are already known at the time when the transaction is included, so the type `Proof` has
the method `Key() []byte`. The values should also have to be provided in order to verify the proof, but to reduce the
size of the transaction, they are excluded from `Proof` and provided by the application on runtime.
`NewStore` takes `[]Proof` as its argument, without verifying, since the values are yet unknown. They are stored in
`store.proofs`.
Proofs can be verified with `store.Prove()` method which takes the key of the proof it will verify and the value
that will be given to the `proof.Verify()`. Verified proofs are stored in `store.verified`.
### context.go
All of the ICS internals that requires verification on other chains' state are expected to take `ctx sdk.Context`
argument initialized by `WithStore()`. `WithStore()` sets the `Store` that contains the proofs for the other chain
in the context. Any attept to verify other chain's state without setting `Store` will lead to panic.
### value.go
Types in `value.go` is a replication of `store/mapping/*.go`, but only with a single method
`Is(ctx sdk.Context, value T) bool`, which access on the underlying `Store` and performs verification.
27 changes: 27 additions & 0 deletions x/ibc/23-commitment/keypath.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package commitment

import (
"github.com/tendermint/tendermint/crypto/merkle"
)

// Hard coded for now
func SDKPrefix() merkle.KeyPath {
return new(merkle.KeyPath).
AppendKey([]byte("ibc"), merkle.KeyEncodingHex).
AppendKey([]byte{0x00}, merkle.KeyEncodingHex)
}

func PrefixKeyPath(prefix string, key []byte) (res merkle.KeyPath, err error) {
keys, err := merkle.KeyPathToKeys(prefix)
if err != nil {
return
}

keys[len(keys)-1] = append(keys[len(keys)], key...)

for _, key := range keys {
res = res.AppendKey(key, merkle.KeyEncodingHex)
}

return
}
12 changes: 2 additions & 10 deletions x/ibc/23-commitment/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type store struct {
}

// Proofs must be provided
func Newstore(root Root, proofs []Proof, fullProofs []FullProof) (res store, err error) {
func Newstore(root Root, proofs []Proof) (res store, err error) {
res = store{
root: root,
proofs: make(map[string]Proof),
Expand All @@ -46,14 +46,6 @@ func Newstore(root Root, proofs []Proof, fullProofs []FullProof) (res store, err
res.proofs[string(proof.Key())] = proof
}

for _, proof := range fullProofs {
err = proof.Verify(root)
if err != nil {
return
}
res.verified[string(proof.Proof.Key())] = proof.Value
}

return
}

Expand All @@ -71,7 +63,7 @@ func (store store) Prove(key, value []byte) bool {
if !ok {
return false
}
err := proof.Verify(store.root, key, value)
err := proof.Verify(store.root, value)
if err != nil {
return false
}
Expand Down
11 changes: 1 addition & 10 deletions x/ibc/23-commitment/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,5 @@ type Root interface{}
// XXX: need to separate membership and non membership proof types
type Proof interface {
Key() []byte
Verify(Root, []byte, []byte) error
}

type FullProof struct {
Proof Proof
Value []byte
}

func (proof FullProof) Verify(root Root) error {
return proof.Proof.Verify(root, proof.Proof.Key(), proof.Value)
Verify(Root, []byte) error
}

0 comments on commit d170b46

Please sign in to comment.