Search Apps Documentation Source Content File Folder Download Copy Actions Download

merkle.gno

2.35 Kb · 61 lines
 1package types
 2
 3import "strings"
 4
 5// MerklePath is the path used to verify commitment proofs, which can be an
 6// arbitrary structured object (defined by a commitment type).
 7// ICS-23 verification supports membership proofs for nested merkle trees.
 8// The ICS-24 standard provable keys MUST be stored in the lowest level tree
 9// with an optional prefix.
10// The IC24 provable tree may then be stored in a higher level tree(s) that
11// hash up to the root hash stored in the consensus state of the client.
12// Each element of the path represents the key of a merkle tree from the root
13// to the leaf.
14// The elements of the path before the final element must be the path to the
15// tree that contains the ICS24 provable store. Thus, it should remain constant
16// for all ICS24 proofs.
17// The final element of the path is the key of the leaf in the ICS24 provable
18// store, thus IBC core will append the ICS24 path to the final element of the
19// MerklePath stored in the counterparty to create the full path to the leaf
20// for proof verification.
21//
22// Examples:
23// Cosmos SDK:
24// The Cosmos SDK commits to a multi-tree where each store is an IAVL tree and
25// all store hashes are hashed in a simple merkle tree to get the final root
26// hash. Thus, the MerklePath in the counterparty MerklePrefix has the
27// following structure: ["ibc", ""]
28// The core IBC handler will append the ICS24 path to the final element of the
29// MerklePath like so: ["ibc", "{packetCommitmentPath}"] which will then be
30// used for final verification.
31type MerklePath struct {
32	KeyPath [][]byte
33}
34
35func (mp MerklePath) String() string {
36	var strs []string
37	for _, p := range mp.KeyPath {
38		strs = append(strs, string(p))
39	}
40	return "[" + strings.Join(strs, ", ") + "]"
41}
42
43// BuildMerklePath takes the merkle path prefix and an ICS24 path and builds a
44// new path by appending the ICS24 path to the last element of the merkle path
45// prefix.
46func BuildMerklePath(prefix [][]byte, path []byte) MerklePath {
47	prefixLength := len(prefix)
48	if prefixLength == 0 {
49		panic("cannot build merkle path with empty prefix")
50	}
51
52	// copy prefix to avoid modifying the original slice
53	fullPath := make([][]byte, len(prefix))
54	for i, p := range prefix {
55		fullPath[i] = make([]byte, len(p))
56		copy(fullPath[i], p)
57	}
58	// append path to last element
59	fullPath[prefixLength-1] = append(fullPath[prefixLength-1], path...)
60	return MerklePath{KeyPath: fullPath}
61}