Verify merkle proofs

This commit is contained in:
hu55a1n1 2023-12-19 06:39:03 -08:00
parent 61ee993f81
commit a3480af9eb
3 changed files with 631 additions and 12 deletions

View file

@ -17,6 +17,15 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.5"
@ -71,6 +80,28 @@ version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "async-stream"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-stream-impl"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.41",
]
[[package]]
name = "async-trait"
version = "0.1.74"
@ -88,6 +119,51 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [
"async-trait",
"axum-core",
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"itoa",
"matchit",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"rustversion",
"serde",
"sync_wrapper",
"tower",
"tower-layer",
"tower-service",
]
[[package]]
name = "axum-core"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"mime",
"rustversion",
"tower-layer",
"tower-service",
]
[[package]]
name = "backtrace"
version = "0.3.69"
@ -109,6 +185,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "base64"
version = "0.21.5"
@ -314,6 +396,12 @@ dependencies = [
"libc",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-bigint"
version = "0.5.5"
@ -355,7 +443,12 @@ version = "0.1.0"
dependencies = [
"clap",
"cosmrs",
"ibc-proto",
"ibc-relayer-types",
"ics23",
"prost",
"serde_json",
"tendermint",
"tendermint-rpc",
"tokio",
]
@ -379,6 +472,17 @@ dependencies = [
"powerfmt",
]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "digest"
version = "0.9.0"
@ -497,12 +601,22 @@ dependencies = [
"subtle",
]
[[package]]
name = "fixed-hash"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534"
dependencies = [
"static_assertions",
]
[[package]]
name = "flex-error"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b"
dependencies = [
"anyhow",
"eyre",
"paste",
]
@ -636,13 +750,19 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap",
"indexmap 2.1.0",
"slab",
"tokio",
"tokio-util",
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
@ -748,6 +868,79 @@ dependencies = [
"tokio-rustls",
]
[[package]]
name = "hyper-timeout"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper",
"pin-project-lite",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "ibc-proto"
version = "0.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93cbf4cbe9e5113cc7c70f3208a7029b2205c629502cbb2ae7ea0a09a97d3005"
dependencies = [
"base64 0.21.5",
"bytes",
"flex-error",
"ics23",
"prost",
"serde",
"subtle-encoding",
"tendermint-proto",
"tonic",
]
[[package]]
name = "ibc-relayer-types"
version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c4ea7fe71d63645ff3fd83929abc3cc1cab1db8777a28a7df4643f021f334e4"
dependencies = [
"bytes",
"derive_more",
"flex-error",
"ibc-proto",
"ics23",
"itertools 0.10.5",
"num-rational",
"primitive-types",
"prost",
"regex",
"serde",
"serde_derive",
"serde_json",
"subtle-encoding",
"tendermint",
"tendermint-light-client-verifier",
"tendermint-proto",
"time",
"uint",
]
[[package]]
name = "ics23"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "661e2d6f79952a65bc92b1c81f639ebd37228dae6ff412a5aba7d474bdc4b957"
dependencies = [
"anyhow",
"bytes",
"hex",
"informalsystems-pbjson",
"prost",
"ripemd",
"serde",
"sha2 0.10.8",
"sha3",
]
[[package]]
name = "idna"
version = "0.5.0"
@ -758,12 +951,31 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "impl-serde"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd"
dependencies = [
"serde",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.1.0"
@ -771,7 +983,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.14.3",
]
[[package]]
name = "informalsystems-pbjson"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4eecd90f87bea412eac91c6ef94f6b1e390128290898cbe14f2b926787ae1fb"
dependencies = [
"base64 0.13.1",
"serde",
]
[[package]]
@ -780,6 +1002,15 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.11.0"
@ -816,6 +1047,15 @@ dependencies = [
"sha2 0.10.8",
]
[[package]]
name = "keccak"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940"
dependencies = [
"cpufeatures",
]
[[package]]
name = "libc"
version = "0.2.151"
@ -838,6 +1078,12 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "matchit"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "memchr"
version = "2.6.4"
@ -870,6 +1116,17 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.3.3"
@ -881,6 +1138,28 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.17"
@ -1037,6 +1316,23 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "primitive-types"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2"
dependencies = [
"fixed-hash",
"impl-serde",
"uint",
]
[[package]]
name = "proc-macro2"
version = "1.0.70"
@ -1063,7 +1359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e"
dependencies = [
"anyhow",
"itertools",
"itertools 0.11.0",
"proc-macro2",
"quote",
"syn 2.0.41",
@ -1087,6 +1383,27 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
@ -1105,13 +1422,42 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reqwest"
version = "0.11.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
dependencies = [
"base64",
"base64 0.21.5",
"bytes",
"encoding_rs",
"futures-core",
@ -1214,7 +1560,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
"base64 0.21.5",
]
[[package]]
@ -1227,6 +1573,12 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.16"
@ -1397,6 +1749,16 @@ dependencies = [
"digest 0.10.7",
]
[[package]]
name = "sha3"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
dependencies = [
"digest 0.10.7",
"keccak",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.1"
@ -1467,6 +1829,12 @@ dependencies = [
"der",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "strsim"
version = "0.10.0"
@ -1516,6 +1884,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "system-configuration"
version = "0.5.1"
@ -1582,6 +1956,19 @@ dependencies = [
"url",
]
[[package]]
name = "tendermint-light-client-verifier"
version = "0.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74994da9de4b1144837a367ca2c60c650f5526a7c1a54760a3020959b522e474"
dependencies = [
"derive_more",
"flex-error",
"serde",
"tendermint",
"time",
]
[[package]]
name = "tendermint-proto"
version = "0.34.0"
@ -1714,6 +2101,16 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-io-timeout"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
dependencies = [
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-macros"
version = "2.2.0"
@ -1735,6 +2132,17 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.10"
@ -1758,6 +2166,59 @@ dependencies = [
"serde",
]
[[package]]
name = "tonic"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e"
dependencies = [
"async-stream",
"async-trait",
"axum",
"base64 0.21.5",
"bytes",
"h2",
"http",
"http-body",
"hyper",
"hyper-timeout",
"percent-encoding",
"pin-project",
"prost",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand",
"slab",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
@ -1771,9 +2232,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.41",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
@ -1795,6 +2268,18 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "uint"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
dependencies = [
"byteorder",
"crunchy",
"hex",
"static_assertions",
]
[[package]]
name = "unicode-bidi"
version = "0.3.14"

View file

@ -8,6 +8,11 @@ edition = "2021"
[dependencies]
clap = { version = "4.1.8", features = ["derive"] }
cosmrs = "0.15.0"
ibc-proto = "=0.38.0"
ibc-relayer-types = "=0.26.4"
ics23 = "0.11.0"
prost = "0.12.3"
serde_json = "1.0.108"
tendermint = "0.34.0"
tendermint-rpc = { version = "0.34.0", features = ["http-client"] }
tokio = { version = "1.26.0", features = ["full"] }
serde_json = "1.0.108"

View file

@ -18,6 +18,18 @@ use std::error::Error;
use clap::{Parser, Subcommand};
use cosmrs::AccountId;
use ibc_proto::{
ibc::core::commitment::v1::MerkleProof as RawMerkleProof, ibc::core::commitment::v1::MerkleRoot,
};
use ibc_relayer_types::{
core::ics23_commitment::commitment::CommitmentRoot,
core::ics23_commitment::error::Error as ProofError, core::ics23_commitment::specs::ProofSpecs,
};
use ics23::{
calculate_existence_root, commitment_proof::Proof, verify_membership, CommitmentProof,
ProofSpec,
};
use tendermint::merkle::proof::ProofOps as TendermintProof;
use tendermint_rpc::{client::HttpClient as TmRpcClient, Client, HttpClientUrl};
#[derive(Debug, Parser)]
@ -67,17 +79,134 @@ async fn main() -> Result<(), Box<dyn Error>> {
};
let client = TmRpcClient::builder(rpc_url).build()?;
let latest_height = client.status().await?.sync_info.latest_block_height;
let status = client.status().await?;
let latest_height = status.sync_info.latest_block_height;
let result = client
.abci_query(Some(path), data, Some(latest_height), true)
.abci_query(
Some(path),
data,
Some(
(latest_height.value() - 1)
.try_into()
.expect("infallible conversion"),
),
true,
)
.await?;
println!(
"{}",
serde_json::to_string(&result).expect("infallible serializer")
);
let proof = convert_tm_to_ics_merkle_proof(&result.proof.expect("queried with proof"))?;
proof.verify_membership(
&ProofSpecs::cosmos(),
CommitmentRoot::from_bytes(status.sync_info.latest_app_hash.as_bytes()).into(),
vec!["wasm".to_string().into_bytes(), result.key],
result.value.clone(),
0,
)?;
println!("{}", String::from_utf8(result.value)?);
}
};
Ok(())
}
#[derive(Clone, Debug, PartialEq)]
struct MerkleProof {
proofs: Vec<CommitmentProof>,
}
/// Convert to ics23::CommitmentProof
impl From<RawMerkleProof> for MerkleProof {
fn from(proof: RawMerkleProof) -> Self {
Self {
proofs: proof.proofs,
}
}
}
impl From<MerkleProof> for RawMerkleProof {
fn from(proof: MerkleProof) -> Self {
Self {
proofs: proof.proofs,
}
}
}
impl MerkleProof {
pub fn verify_membership(
&self,
specs: &ProofSpecs,
root: MerkleRoot,
keys: Vec<Vec<u8>>,
value: Vec<u8>,
start_index: usize,
) -> Result<(), ProofError> {
// validate arguments
if self.proofs.is_empty() {
return Err(ProofError::empty_merkle_proof());
}
if root.hash.is_empty() {
return Err(ProofError::empty_merkle_root());
}
let num = self.proofs.len();
let ics23_specs = Vec::<ProofSpec>::from(specs.clone());
if ics23_specs.len() != num {
return Err(ProofError::number_of_specs_mismatch());
}
if keys.len() != num {
return Err(ProofError::number_of_keys_mismatch());
}
if value.is_empty() {
return Err(ProofError::empty_verified_value());
}
let mut subroot = value.clone();
let mut value = value;
// keys are represented from root-to-leaf
for ((proof, spec), key) in self
.proofs
.iter()
.zip(ics23_specs.iter())
.zip(keys.iter().rev())
.skip(start_index)
{
match &proof.proof {
Some(Proof::Exist(existence_proof)) => {
subroot =
calculate_existence_root::<ics23::HostFunctionsManager>(existence_proof)
.map_err(|_| ProofError::invalid_merkle_proof())?;
if !verify_membership::<ics23::HostFunctionsManager>(
proof, spec, &subroot, key, &value,
) {
return Err(ProofError::verification_failure());
}
value = subroot.clone();
}
_ => return Err(ProofError::invalid_merkle_proof()),
}
}
if root.hash != subroot {
return Err(ProofError::verification_failure());
}
Ok(())
}
}
fn convert_tm_to_ics_merkle_proof(tm_proof: &TendermintProof) -> Result<MerkleProof, ProofError> {
let mut proofs = Vec::new();
for op in &tm_proof.ops {
let mut parsed = CommitmentProof { proof: None };
prost::Message::merge(&mut parsed, op.data.as_slice())
.map_err(ProofError::commitment_proof_decoding_failed)?;
proofs.push(parsed);
}
Ok(MerkleProof::from(RawMerkleProof { proofs }))
}