diff --git a/.github/workflows/programs.yml b/.github/workflows/programs.yml index 3856d80..d6729ca 100644 --- a/.github/workflows/programs.yml +++ b/.github/workflows/programs.yml @@ -38,10 +38,10 @@ jobs: cd programs/update-client ~/.config/.sp1/bin/cargo-prove prove build - verify-membership: + membership: strategy: fail-fast: true - name: Build verify-membership + name: Build membership runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v4 @@ -65,3 +65,31 @@ jobs: run: | cd programs/membership ~/.config/.sp1/bin/cargo-prove prove build + + uc-and-membership: + strategy: + fail-fast: true + name: Build uc-and-membership + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly-2024-04-17 + override: true + + - name: Install SP1 toolchain + run: | + curl -L https://sp1.succinct.xyz | bash + ~/.config/.sp1/bin/sp1up + ~/.config/.sp1/bin/cargo-prove prove --version + + - name: Build SP1 program + run: | + cd programs/uc-and-membership + ~/.config/.sp1/bin/cargo-prove prove build diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 68ca92c..408c762 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -31,10 +31,9 @@ jobs: with: command: clippy - build-all-features: - name: Build (without programs) + tests: + name: Unit Tests runs-on: ubuntu-latest - continue-on-error: true steps: - name: Checkout sources uses: actions/checkout@v4 @@ -49,11 +48,26 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --locked --all-features + args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership --exclude sp1-ics07-tendermint-uc-and-membership --locked env: RUST_BACKTRACE: 1 + + build-all-features: + name: Build (without programs) + runs-on: ubuntu-latest + continue-on-error: true + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Install stable toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: 1.79.0 + override: true + components: rustfmt, clippy - name: Build uses: actions-rs/cargo@v1 with: command: build - args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership--locked --all-features + args: --workspace --exclude sp1-ics07-tendermint-update-client --exclude sp1-ics07-tendermint-membership--locked --exclude sp1-ics07-tendermint-uc-and-membership --all-features diff --git a/Cargo.lock b/Cargo.lock index 0d4c058..7bec098 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5643,6 +5643,22 @@ dependencies = [ "time", ] +[[package]] +name = "sp1-ics07-tendermint-uc-and-membership" +version = "0.1.0" +dependencies = [ + "alloy-sol-types", + "bincode", + "ibc-client-tendermint-types", + "ibc-core-commitment-types", + "ibc-proto", + "serde_cbor", + "sp1-ics07-tendermint-membership", + "sp1-ics07-tendermint-solidity", + "sp1-ics07-tendermint-update-client", + "sp1-zkvm", +] + [[package]] name = "sp1-ics07-tendermint-update-client" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6eb299a..4983481 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ sp1-helper = { git = "https://github.com/succinctlabs/sp1.git", tag = "v1.0.5-te sp1-ics07-tendermint-solidity = { path = "./packages/solidity/" } sp1-ics07-tendermint-update-client = { path = "./programs/update-client/" } +sp1-ics07-tendermint-membership = { path = "./programs/membership/" } tendermint-light-client-verifier = { version = "0.36.0", default-features = false } ibc-client-tendermint = { version = "0.53.0", default-features = false, features = ["serde"] } diff --git a/contracts/abi/SP1ICS07Tendermint.json b/contracts/abi/SP1ICS07Tendermint.json index 94bb826..a591743 100644 --- a/contracts/abi/SP1ICS07Tendermint.json +++ b/contracts/abi/SP1ICS07Tendermint.json @@ -3,12 +3,17 @@ "type": "constructor", "inputs": [ { - "name": "_ics07UpdateClientProgramVkey", + "name": "_updateClientProgramVkey", "type": "bytes32", "internalType": "bytes32" }, { - "name": "_ics07VerifyMembershipProgramVkey", + "name": "_membershipProgramVkey", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "_updateClientAndMembershipProgramVkey", "type": "bytes32", "internalType": "bytes32" }, @@ -43,6 +48,191 @@ ], "stateMutability": "view" }, + { + "type": "function", + "name": "abiPublicTypes", + "inputs": [ + { + "name": "output", + "type": "tuple", + "internalType": "struct MembershipProgram.MembershipOutput", + "components": [ + { + "name": "commitment_root", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "kv_pairs", + "type": "tuple[]", + "internalType": "struct MembershipProgram.KVPair[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + }, + { + "name": "output2", + "type": "tuple", + "internalType": "struct UpdateClientAndMembershipProgram.UcAndMembershipOutput", + "components": [ + { + "name": "update_client_output", + "type": "tuple", + "internalType": "struct UpdateClientProgram.UpdateClientOutput", + "components": [ + { + "name": "trusted_consensus_state", + "type": "tuple", + "internalType": "struct ICS07Tendermint.ConsensusState", + "components": [ + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "next_validators_hash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "new_consensus_state", + "type": "tuple", + "internalType": "struct ICS07Tendermint.ConsensusState", + "components": [ + { + "name": "timestamp", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "root", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "next_validators_hash", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "name": "env", + "type": "tuple", + "internalType": "struct UpdateClientProgram.Env", + "components": [ + { + "name": "chain_id", + "type": "string", + "internalType": "string" + }, + { + "name": "trust_threshold", + "type": "tuple", + "internalType": "struct ICS07Tendermint.TrustThreshold", + "components": [ + { + "name": "numerator", + "type": "uint8", + "internalType": "uint8" + }, + { + "name": "denominator", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "name": "trusting_period", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "now", + "type": "uint64", + "internalType": "uint64" + } + ] + }, + { + "name": "trusted_height", + "type": "tuple", + "internalType": "struct ICS07Tendermint.Height", + "components": [ + { + "name": "revision_number", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "revision_height", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "name": "new_height", + "type": "tuple", + "internalType": "struct ICS07Tendermint.Height", + "components": [ + { + "name": "revision_number", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "revision_height", + "type": "uint32", + "internalType": "uint32" + } + ] + } + ] + }, + { + "name": "kv_pairs", + "type": "tuple[]", + "internalType": "struct MembershipProgram.KVPair[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "pure" + }, { "type": "function", "name": "getClientState", @@ -133,7 +323,7 @@ }, { "type": "function", - "name": "ics07UpdateClientProgramVkey", + "name": "membershipProgramVkey", "inputs": [], "outputs": [ { @@ -146,7 +336,20 @@ }, { "type": "function", - "name": "ics07VerifyMembershipProgramVkey", + "name": "updateClientAndMembershipProgramVkey", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "updateClientProgramVkey", "inputs": [], "outputs": [ { @@ -162,33 +365,9 @@ "name": "validateMembershipOutput", "inputs": [ { - "name": "output", - "type": "tuple", - "internalType": "struct MembershipProgram.MembershipOutput", - "components": [ - { - "name": "commitment_root", - "type": "bytes32", - "internalType": "bytes32" - }, - { - "name": "kv_pairs", - "type": "tuple[]", - "internalType": "struct MembershipProgram.KVPair[]", - "components": [ - { - "name": "key", - "type": "string", - "internalType": "string" - }, - { - "name": "value", - "type": "bytes", - "internalType": "bytes" - } - ] - } - ] + "name": "outputCommitmentRoot", + "type": "bytes32", + "internalType": "bytes32" }, { "name": "proofHeight", @@ -382,6 +561,29 @@ "outputs": [], "stateMutability": "view" }, + { + "type": "function", + "name": "verifyIcs07UcAndMembershipProof", + "inputs": [ + { + "name": "proof", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "publicValues", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "kvPairHashes", + "type": "bytes32[]", + "internalType": "bytes32[]" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, { "type": "function", "name": "verifyIcs07UpdateClientProof", diff --git a/contracts/fixtures/memberships_fixture.json b/contracts/fixtures/memberships_fixture.json index feed1f2..8a71516 100644 --- a/contracts/fixtures/memberships_fixture.json +++ b/contracts/fixtures/memberships_fixture.json @@ -1,11 +1,12 @@ { - "proofHeight": 2110658, - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "commitmentRoot": "994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf", - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "proof": "0x16b7a55336d5ec7ca39056b6c196e4b9b8064cc1d265bddcf0002ac3f8bc7b110bdbdbc35133b34f43edb6e151383133c12341b436e09135617723e97b8c68291d58db5d9b0dcf7e41b4e32e384c5ac0a36aadf7c5827ec0b753d1905a4fb79d2e406de821e612024ed9ffb8a57b54dcd5d29aa57339d770cdaf8e9ff17539dc2ed822f8f00b7fd68f3be3dcc53d6a4565f3098e6d1e4dbcd6fad4a53759833d089e4ad0409f058af0fd710929ecd472184545c1dc241ecb3aaf81fbbd5a3bd302c45c2ee2deda40dc7a215b48ef29f1ccb8c4f250999cd0c6c813caa1a731f112c5b17e7dba05078de10456edcf97e2722174645ad123ab1b0530ecb9eaa00b20c99b04d82a2bab4d3b38dbb0f17123866f1c6d352d1d7883a4fba21e7b163000b7b79f7c0a30cbad1b94fd813fa903566301412d36540124ae41a9aa63869802f2ae7f0838bc84892cc2a9c2a4e7c90ac94644cc2f596922c0bc3c29491b0f1c237c0dfef0346e55ef6abd1b2ddc22c72642885593a7c7d167b1a92682ad262f6b17de5d09ebc1b902f660da4764240ab1a77143b5796237b80af686c4924815179569b1802d32c6442979c7f77087c5179e1aa375660371f76ab22d7715e607e3d611dcee3a1a004971017ae7189ec43dda4500f8a63dbb69ae8fcb9372aa1cd3f1fed9f2f41b1843630ba313a549c8694f58af1975e61ef3ef4076b8132e058ae7e36d6daea788cdd9d6175e022689e023f48d607d280ccf07b7e6cc54a406eb1c12a9331e14d7836b4fdaa4624ce9a5fb5d16435f6c039fa07af4554b0d0caf56c2e314fbdbf74ae8dde597fee501548db6ef467a0bfc5d7b299eda4d4a139fc47354c40035aa8cbad583aa4991bcf757d702ca50fddf3449e2ee4beb610cf3f82210e65708430a0d97737b9dd0e2364cff88eff26d456ee305d9caab1127e508bae2df774cf3600862152e0403006fd819504d1d7d2b6fe6c0642a7cc61cb30d1f23901e596e03057e6536b42d49ba2143df02497832faf7a24eabedc90893a49eb38b3d6e6fd52031d58b832654b532257e2394f5ffe3f54695f3bbc208fb3c3166672edd08535ae93cf2ef5ece36e52e81c174fe5688bfa14bf065c32590102d6800b82e6d965bf486d1c8779cca6481359fbe0a741ed836400fafb31d6ffaa13804ef0134544b5f835ee72191b9cf4b3806afeba6b6700111926438", + "proofHeight": 2230264, + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "commitmentRoot": "c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1", + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "proof": "0x02427f7ed4526c66427c5edaf0c503013f7a6ace0df44f0ce334a2231fdeb5a3195df4262848a336628f1a54b5c842e6ecbff3509e64f22d4e8bca23a0595d4601736c5b8f4bc88dfb6bed2533f52b7e992fdafec4cb06fbcd4990e89a65ba5307c8e29a3959b77f7b6a4b523e805c9826a7361ac2c2b07f94404bce8e3377730e8cc57ac818924882f5eb0cffd72431f3d7a7331fc8e63f020f30bb0b70939b040035c6c70d1cb315425d4ce9777c002718171747e867d65dbebc481d9f0e48171fdad145919b1b2d58305d2fcad07580a74972636eb9c291dca43077e86fdc23a1f67b3b160e3b7592257e8e6ab8627001be540863ba314c55065ba715eab725162a1db667a7e9b68a94f049e5f9695683380977ead66984aa6fa68ebd56001cd54e554f8ec58b0848a88927f758f4fe66edd851eeee657c6612d7b21dd572239b0940f95ec34a2566b1ccc6ea386194e39042bef1704d7f7fa65ae21cc6da1e396ed6a559af8f40fc6edb8314eebc733e90d7da6aded35615917a22e14bab2f3714713baa123135a52d8d3a719c5facebc445f2bb5be891ccdac01cb765251ae93ea6206811d9a8048dd0e60b4132ae3e1d7d8033f0133ff7132230033a922ccb37b1cd048f562545eda8a9a3128ae7277185ebb07e85d34209a526ce4b920cb6177b9467a742005c0ab23d342f89fbf89ee46edecf6378fa9c2abe09238e1f2a6e408d17726e00cab010aaeef9772be8c5956391ca2d8d14ff332c9165d5124034fc4f9bb3e4f44750d6ff76773577fa4cfc02a6f601f11d071cd0781095163c8fc869c5c93e315f20f7b4a382aa15ed98523657be24d0342d69199afbb71c8be6cc33d0cd8888313d0eea32c4ed1ce6f4d805f528021d4a3b0ee542273218f2b93dc8c7f5d49b7a37623f69b6f6771e70a0f6decea2d4634227ee8824b121e87dcdf605c6fbea1c133ab2cbcaac61e2c1be85fb91c890bd13acc4654b4a002c8295616ae6e8009a750262fd4900f7f245434f783a44ab7ffb7cb2035c062c20d0f81ac35909c083839ed6193285d73747adb48e9300414b3707bcda3348080f2249ebba1f05cb25bb2eb8264516fe0aad02b49969328214a313593b7b5618cd400007b8d8151548a49cc034511327ea8cbe1cd03cfc3238b87bbedcfcc12c6c9e25b68490e2d50dd6cbb287a175f9d067de8f4c2b2ba5a386deea158725", "kvPairs": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/mock_memberships_fixture.json b/contracts/fixtures/mock_memberships_fixture.json index 071be31..9bdfe8f 100644 --- a/contracts/fixtures/mock_memberships_fixture.json +++ b/contracts/fixtures/mock_memberships_fixture.json @@ -1,11 +1,12 @@ { - "proofHeight": 2110658, - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "commitmentRoot": "994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf", - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "proofHeight": 2230264, + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "commitmentRoot": "c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1", + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "proof": "0x", "kvPairs": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/mock_uc_and_memberships_fixture.json b/contracts/fixtures/mock_uc_and_memberships_fixture.json new file mode 100644 index 000000000..7fc319b --- /dev/null +++ b/contracts/fixtures/mock_uc_and_memberships_fixture.json @@ -0,0 +1,12 @@ +{ + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetConsensusState": "00000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetHeight": 2230274, + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce000000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000022080200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668df68100000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "proof": "0x", + "kvPairs": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/contracts/fixtures/mock_update_client_fixture.json b/contracts/fixtures/mock_update_client_fixture.json index b0312ae..4390459 100644 --- a/contracts/fixtures/mock_update_client_fixture.json +++ b/contracts/fixtures/mock_update_client_fixture.json @@ -1,10 +1,11 @@ { - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "targetConsensusState": "000000000000000000000000000000000000000000000000000000006677e25092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fdb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "targetHeight": 2110668, - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419000000000000000000000000000000000000000000000000000000006677e25092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fdb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c4190000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668a3a9600000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetConsensusState": "00000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetHeight": 2230274, + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce000000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000022080200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668df68100000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", "proof": "0x" } \ No newline at end of file diff --git a/contracts/fixtures/mock_verify_membership_fixture.json b/contracts/fixtures/mock_verify_membership_fixture.json index be2deb6..1d5b60b 100644 --- a/contracts/fixtures/mock_verify_membership_fixture.json +++ b/contracts/fixtures/mock_verify_membership_fixture.json @@ -1,11 +1,12 @@ { - "proofHeight": 2110658, - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "commitmentRoot": "994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf", - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000", + "proofHeight": 2230264, + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "commitmentRoot": "c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1", + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000", "proof": "0x", "kvPairs": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000" } \ No newline at end of file diff --git a/contracts/fixtures/uc_and_memberships_fixture.json b/contracts/fixtures/uc_and_memberships_fixture.json new file mode 100644 index 000000000..297bc70 --- /dev/null +++ b/contracts/fixtures/uc_and_memberships_fixture.json @@ -0,0 +1,12 @@ +{ + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetConsensusState": "00000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetHeight": 2230274, + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce000000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000022080200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668df6ff00000000000000000000000000000000000000000000000000000000000000076d6f6368612d34000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "proof": "0x0ebb07796ba5cc4770ff46ad71d09d147ae5f3f468d39062bc99ce415aa239822c061b9207b7128eac3b2645a88254fa45878e8881d3575fa1eb0c1c4353133528cda18b6a58f34aa520f72f2dc1de2e8b59f6bf7f5da81a3c0d8f1669f1cdc83028a5486ca793d65a762e4f958b0218089fd12380adfe8f61bd687142b78edc1363ba6d0bfab6dfb2cfee1e7e0c44600ed0366b20cc89dc9f181b78068297381eb2a19a96f34e09abdb9381a931ec7bba7572535e32bf5919779e7c0e112f841af4e0eedd7703b7cc74806e8f3ee507db3d44acc8270c769fc2267327ee8ddf22e5115ae87fe908f9ba97d17c521db8b05d5a63b355cf41ef2ba20d8c7d681107677f58c3dbf080e330fc9ed6ca87676572a8f2255977cf9430bcaf2c1c780a04065b7b5b03069c1dd385b9097b0acd43f54b9f0944bdfbc30e8c15346f4457277118dac9709ae9f2211c341a5ce3587611df74304eec5ee1a24f88caab43200426c8909324dac2018ffd9c5604e061bc4c3b3ce10113ea083d81c06783bdec24fd25e207047c76f3612bf13163046fd7f190a4dcadefe957a4aaa96aa821892b652fb3f7b0f269fd23ec03be8ea4b423d74636a2dec93a4f4758e5bb7b365f24401b9f79a061d8105d4fa961277718c73494bb9741828bd2e06e2fdb8633650e4ecdc70f7c2a80560cfe7d29e4fe6c4c00306879cf2e144a405a2b636ba1f41cbd0c7c3361fa082556e9d6b2e8aea59c350834a8c1cb9c3add2381ba67fe581a029cff33add592f0875c8e6bd3ce2456424ef19dd713c644f409259d8295c3120e7fdfae2ab1383fd5e755496885e01b8366635e60382afa5023a65f941df41f2daff7da3da6a96e5a90798631397ebe59e118112938d90015b40ce4b1ffac1c5427ebb1ae3f172228af7b09661543552f87bfcc613366fe202a259bc47eaa0723e320ead2c32c17723fc5599dadd6f914108f34849f134fe49530a68f5a3b145ce15cbade1d7c19d122abd3beadaa3d40107cbf3d2a2aa55b45c337e90d1b0584bb1051ae552a404e885832c2c9ea6974b72a1bf7ad8ed096d810e9c6889d279af9e635b43e8776f21344e942e1a64ba53c1d85279de58ffba49ac6dd797b124b95c5a5a6ed2754d2d70f5a9666a1f5db6c9c2557570da3d54f259386350503b848d8c6c909a32077d5b9d0e0cc8cf728ab2c3a4913591ca22ac81897bf9c", + "kvPairs": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000025636c69656e74732f30372d74656e6465726d696e742d3030312f636c69656e7453746174650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file diff --git a/contracts/fixtures/update_client_fixture.json b/contracts/fixtures/update_client_fixture.json index 61a9bc6..774975d 100644 --- a/contracts/fixtures/update_client_fixture.json +++ b/contracts/fixtures/update_client_fixture.json @@ -1,10 +1,11 @@ { - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "targetConsensusState": "000000000000000000000000000000000000000000000000000000006677e25092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fdb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "targetHeight": 2110668, - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419000000000000000000000000000000000000000000000000000000006677e25092a23d699a0d59f2e1b034c129b0051fb711a3d0d1f2e895fce82e933b8e36fdb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c4190000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034cc00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668a3b4b00000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "proof": "0x28ab170baec91a8e28a47432c2f5cf5b6ee1b96960091be65bdbbed19af1fbbf0f3c90d4531d0332d06dc8e1e1eb84b2076649b80a72a346a18f5d5ab7d8f2c71f3504f214ddba2d881cdafd75fb520a78e7822f7afe85a9f50234927c3f7aa20be0d421c2a05f9ddff75c436a9e1ec1075a5c619ecfa89b85ed5eb563c118980ff977366c07218d2abce851804fb6ad976275f16561d5a1d770320a4357f71c08ce6660a75d2cbb6cfaf767c76d24c57a4440bbf853eecd42da1ac1fe1cd93115c20b5b9b31d3854d4ba7ab63edf68c3a6a47b6fe9eb19371e02f670473f8f92b99e490b0b0c83ec4ec0117497ea609b4837713e7dd8d9610b509b4b81f65e01ee5c165d9d345c60720525aa8b22b3da651269720a867dea45996cb7f8477b009a150ba77bb2381e1a1f2208c1781fb1bff65fb24da9eeb3202ff46662e4d95069f2a0edbaf595cc20d921f49b84ca2d73cfef386ad3e84a018d741c666ac8521c05eb4be21e614ff85a84338e80f0b93bc961e92a8f22c0d1f17e0a6437fd2268aac53acc5f1e71b2b27c26de75246d57332b3689833f2363cfff29bc9cf281cb59ec6d32af3a84e6fb7d097b791b830fbfe6264eeb8cfbd0e2ddc922c46f02788f8cef5c420d7a225f487a64eb4fa2275d8e03bd09aacde5d1f99315cfd791be42e25d6ae3eae113ccf6a244885bc90b15e790e6ad996e81f4f2660ff96de13e4bfa2f5e70771cefca8be9fc031d9452d06179c0c65903fe7278022fdd18212920f66a7567ae7939e27c4d1c9181b31b753ad82d4cb8aceadbab241ac5a822dbd717e45817cee754d564ba47a30293c0b1744132b35fbb9dd8984289a341c2e4f73ff5d142bf083ab32c36e007efe4c379e5a5972b26e304883fbbf01cb2b1b9f7499e71991c3968f865cd718e8f64d6dcda4f29794e2576748dfbb51ac921651a42a4b5f4ba729f7a4b27dd16c26a0e9415d5c8e2cdfc5481230da25baa0080e9229fde28d14c510577f2e2e2f851abc49dec6d5741dff007b153376575f254bbed35798bf1c687d01b0d84e15b015bdb9bab17f381c9d4f32806ba0f9df0c28eea7155fcc1194d30984af9a89369a0eda59b85852da72459406fda13ad6161521da4adfac3373bf73548a059a8cde5176cf2fabec19df32e194316d50951352275589a808a7b0c45564446ea739dce60f147b2a9223f01bbd8f485cc200" + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetConsensusState": "00000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "targetHeight": 2230274, + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce000000000000000000000000000000000000000000000000000000000668df1ea6a10b1857c778e02df342a0471476f44bc80e94e6e53e73e33b4e2bf94261150b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f80000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000022080200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000668df6f000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "proof": "0x0fbf204e1d50a8a5bea83cfa630a7f63bdde6af658e1edadcba264e4521562fd0680a2890cc024413092d6b263a904fcd08dc85274317f23f0aa4183baae27cd10cead8f182503a43f88af302bd2518eb5680945483428d9c60de011b67827bb2d7ae5aff748db2687a49a88592d8dd06072b419eb5048aa7d28632b818637570964dd56b567f5c4d45d0fb966a78e906041c0cc0032c869559dd55bf1d9cdd61cd17cd6610b37d1c28bfda36d7358839105ed56ec200fee5b89c690b43075d0036ec6c61ba20bccbb92a6075a10def85609dbcc8ca3f6550baa1f30a87daeed03f83109fa492a4ab2599fa981dd99c97a20db0fddb93083292dce6e23f3e210120255d8db3d78439ada4e74e0cc2b19903082b46f45f8e86ac5730117253e60101ae64a7212d533525c03167834c1230bbb2ebb8a1529051ebdd30c476ee8a52b797368c0c8c6b7f87ffc27d4a9b2d2a53ce3aabab4ea83b525445ce6fb3a9b04abce5ab427a101bdd2f4154b7a43fa7309b148afe587137c16e54bcb7c67b820f787f266d44aa33e24d70492261a814f3541075e2e7286de8d134167ba6aef1521b53861b190406ab821dae7e57d73a9393f52fe55945bc1095e6a4c4bc6fb0abdea6501e5b5b7f58322436b463146b769f8b431cabf381c1ff0eff59febd70fa79a1085f6ace95dccdaca9e9c3966152c9916561458a2d05c32d724daa1f51c0219e2e18c385610f4fcd139d6e1dda677b2d6ea72fe9aed57c55e172ddefb0203fb21369043d77ed15719c52d0373ab07805e0835ebd28e36ebfc4b7bcca3054c4d0434a91566ffe2fbccb16525ab63b78e9ee02f7e027a4ce693b1a8502b0b518cf94be943ca4e5a583463893cd7ff61154b7af6351132d83237da6ecc522643790faa5ff2abc5f119abcc587070374bcefb89ff0e31586164a7ce3923ad11a09170aaa2c4326171d5bc5247c3893478c6435f51bab85799a2b263332e4000c2647fc62508428f64346cb639c3da310b5e7e51f65b08d54531369809152b172ed19dedfbcc22f8513615c7fe489a89a54a4aa1bb659771ac01f542c4f5e612369704af97040475ba8aad29d497e65f9184ae89aaebe11ad052cf8bd154601697b040a229c0f16d26fb6e193d437bfefdc9536c35203fe1ac96de444ba9ff28a087f3c6c8f270c0528a8d62cdff7b5b288754aea44b84ebe7fd4e7b919166" } \ No newline at end of file diff --git a/contracts/fixtures/verify_membership_fixture.json b/contracts/fixtures/verify_membership_fixture.json index fc3d816..193a0b5 100644 --- a/contracts/fixtures/verify_membership_fixture.json +++ b/contracts/fixtures/verify_membership_fixture.json @@ -1,11 +1,12 @@ { - "proofHeight": 2110658, - "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002034c200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000006677e1da994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bfb73058223e788b1b021cd25d9d8b80f1e21f742014d270fc850bacda1e63c419", - "commitmentRoot": "994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf", - "updateClientVkey": "0x00eb2455c8d14f1f4a2287daa622a411b2e4a764d522fa5172ef9d1a5b8a0f5c", - "membershipVkey": "0x0045c54ed5927a845940a1b05eb768a384189a43f0ce816f2b7b0621600045b1", - "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020994a2058af458e1a97f19bfa85c99ba5db6534473e8040e671a45431f78651bf000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000", - "proof": "0x20087d2cec6a91e6883ce38f346a0afab8b136961af22e33c5ba4ab62b9db6e32774b91c8d89ac74c46ad8e2780a300e98ecec3ededcacf3dac1482d6ffc8dc4304e50a4f533ce51293f58a243c2a3a2f7f6adfa261d574ebce9e0397379f8140762bc2155aca0e8dd41c8e74a4d7601c840bbaa5ff1b1739618f05aaffc45821836558e63e51784519292003151a9b9f250cb8b94d8a672cfdb6746b60d773c2dd2b9e886328aab8d0d37fb1772a9b2e5866415611fcb0de15d1dc82e9e37f01f431adb7f7dca449215d5cfea5acc73939e44731f08c9c38774599647c7ed892716a1073aeeee4a5906653725147f3decd45f2ab4230ac87d7a0f885e43c7a712a57f90c7c7f1497cad47da7f7d15d8a84a489af66086fc05bca5d9f706e75d0929487dc3473ec07741b6f2d89647113c1e67319476fda8d1eaacf576beaaa424fa859453a2d03b968215bbac666870ad5d9b23101a9fe973059d689163897f0199365cde6d895b7f8c3c8d82425f32be0fcde170af51766bef06d5cfe901b41dcb251270bc0ec7dfda462dfeaa36a4567f76dd2bd861e0439880e83453f15810483ffa1d094ce287683335e03a9e838a3813e995ce4ea4af876eabe4aacf452c32261c73965925cd899b4ac5040a3f2bb1213f08ec2f57b3fdc777a32a6c581803a528874edfb6236f1b160326e75d2458b1213643a1cde140df518d6bbbca285ec8e46e26136e1624a4f74ca7e5a0d4c51efc3bb50fff86d95eb4498a8400155a7823965449008cb50b77121cf74b1105e8762ebbf247b2ec8c9540c0d5ef200b92d954fdf466f4e78d2131ef3e61c4310dd6d1a237731cff9d09907fea132e43365d72d5bd82538198dde27a8367c3ecbc33b880eabb815683ef09dd2523127b6a6d7e4bd037a1486b2002c70e5333127c442e63aec3cdf4acf865c2d2dd19852a32a4aa2320ecad3accbf8df6c2260291c9b45f2fb17eda1d45f789f1fa1089622f2b8549e319404a4cf68d4638cd22d588e251fbd52d3a7cf2f72424d526a2e6123f9452a00a5a5438a3c5a57f925efa6e8f24e329bf6ffdd39178a0c22df3fb1ceba04b38dad892184111bc92ba5ec642d6c37be7cae0f34bf12fe8a213ef17c007c0c79188e60b621cc3d8f4b4983f98ec14a6c318f57187d52bb40c1a94119a58d4488a2637bbd6ec1b1b5cbb8f3dd28a0440c6f1255dcb05f9ea7a", + "proofHeight": 2230264, + "trustedClientState": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000002207f800000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668df173c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1b655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "commitmentRoot": "c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1", + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d", + "publicValues": "0x0000000000000000000000000000000000000000000000000000000000000020c7656d84561185b88f82507efaa6d578b46ebe5010c0d37de05109254d2f9ff1000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000", + "proof": "0x239cdbbb845843337d484445cedcb099fca13315f5302c3dcf7b6fded2de1d6b0fb2c118127aa807b757edd7c1e9e56a0a96a85882d065a069e77df0593b7853273ad52c56c120cf3b63b4c1b5ef8d089a9e413f113cf8ae1a8048bc21da2a4d2d561a2d161eb9b5838bfecb1238ca2bc161bbfe5690714b71438ae87c3a28c51e9910119a6d2b0da6273baa73dd1a00ec98a209a81aa7dfda3aaa25d5f60e2f27384b03678ea80550c7d5dc3474f31b7243fd7a6d54cbded45642c3e0a8ec3400d54f10f87211a32a2b5808fa0a6507d229a94bd68ada5f70947d120cf1d9bc00a065bb9e1715b0a22ef5ccb85f63efd7914f23aa2a4712ad589e937d52a6071c6aa52affa80cb5923b988b44d40c4d5d88cc052e4ddccd86e5c22124eca93e1bd283d8d4b3f9bbb9e24ea0d1e8bb2233912253a34d023776e36b215806ed53013bde1e92ea889c2659445494bb20a99939de36eed44fff63b932cd7f6a25df12d9df5b3ab35fa048d131da7deeaf1f3373ee84cf725e52cb8eec8fa9f2d8f628b6f103cf7f55a3031c119661c08d0a4d79a58ebb662b28ecd1b587a85217ec1f4644427dd3d1da30b9e3f175a6ecc0cd0f802a7b7dec1ba3869a7ada8fa40f167cb27493a138f97c8bbd2aec3ae9dc107f0058c589b3a2b88bf6796ac347920bf3170bfffa7cfbc50ee18f979c3d8d6bf330b36a9895ef8470a3603e1033b62b9edcc4300818a8438a7960fb9aa201e69969ff59944d194c1b7496dd2be63c2c4b996e6645dfd31e5de998b3c94965135006f2344bc430733f4a0968410a0709109d6e1825e2b4b501ba894968a6e7c497c7deb0572055c1a3d4c78cb1586f22af1d9845d1b686f99a88b7c66cc17220b62b74f1eb439c285983ab325285850d0b82b7d2896ac6b67e2d7ebd4e837cfb15e49e0fb440435274d84d15b1dad105bc433af9d761037039cfd813391d8a4c802482afd82848f197c3932d54f200160a9ab83d39d9ee1e925361d1d70a283eff095bf6532faed8b6b3256d8b912a26584c71fabbe1c9cae1afe38e2c029ace586f3b5190583e959195a1560d17bf0cbab86e2390bb54c729365071f810feff5d9ae3e2882765df658de211308c851cda6d67650a14f02ad02b137b2620b8878bb11525ea61607afe3175927839092248e7944646bbdbd472fd08e760ce8e478df9fafa8c6eb3f686cd7ec8035d43", "kvPairs": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000023636c69656e74732f30372d74656e6465726d696e742d302f636c69656e745374617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b70a2b2f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e436c69656e7453746174651287010a1174686574612d746573746e65742d3030311204080110031a040880840722040880c60a2a02082832003a0510b7e3c60842190a090801180120012a0100120c0a02000110211804200c300142190a090801180120012a0100120c0a02000110201801200130014a07757067726164654a107570677261646564494243537461746550015801000000000000000000" } \ No newline at end of file diff --git a/contracts/script/SP1ICS07Tendermint.s.sol b/contracts/script/SP1ICS07Tendermint.s.sol index a44930c..4db7140 100644 --- a/contracts/script/SP1ICS07Tendermint.s.sol +++ b/contracts/script/SP1ICS07Tendermint.s.sol @@ -13,6 +13,7 @@ struct SP1ICS07TendermintGenesisJson { bytes trustedConsensusState; bytes32 updateClientVkey; bytes32 membershipVkey; + bytes32 ucAndMembershipVkey; } contract SP1TendermintScript is Script { @@ -45,6 +46,7 @@ contract SP1TendermintScript is Script { ics07Tendermint = new SP1ICS07Tendermint( genesis.updateClientVkey, genesis.membershipVkey, + genesis.ucAndMembershipVkey, address(verifier), genesis.trustedClientState, trustedConsensusHash @@ -80,13 +82,15 @@ contract SP1TendermintScript is Script { ); bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); bytes32 membershipVkey = json.readBytes32(".membershipVkey"); + bytes32 ucAndMembershipVkey = json.readBytes32(".ucAndMembershipVkey"); SP1ICS07TendermintGenesisJson memory fixture = SP1ICS07TendermintGenesisJson({ trustedClientState: trustedClientState, trustedConsensusState: trustedConsensusState, updateClientVkey: updateClientVkey, - membershipVkey: membershipVkey + membershipVkey: membershipVkey, + ucAndMembershipVkey: ucAndMembershipVkey }); return fixture; diff --git a/contracts/script/genesis.json b/contracts/script/genesis.json index acd8273..cf52750 100644 --- a/contracts/script/genesis.json +++ b/contracts/script/genesis.json @@ -1,6 +1,7 @@ { - "trustedClientState": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000021648500000000000000000000000000000000000000000000000000044c1ff252000000000000000000000000000000000000000000000000000000044c1ff2520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", - "trustedConsensusState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000017deed5d38e47d76000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000201716177e878dcc71bc2c79c9c616b4d871c9c71e4f77c9afc4cdba34068c21030000000000000000000000000000000000000000000000000000000000000020311b8792abf344e87ea6195af239b6b88218023281895ff3dcf304473746b7c2", - "updateClientVkey": "0x008b88467d52d7cf1ab66b0078910bda0695f00fb8a3c77a71ffc6979d885c3f", - "verifyMembershipVkey": "0x0017bb63f05750c8ea00b7c5733317ae0d2c048f17317d3c052a05aa6b016b40" + "trustedClientState": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000220c3d00000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076d6f6368612d3400000000000000000000000000000000000000000000000000", + "trustedConsensusState": "00000000000000000000000000000000000000000000000000000000668e249b730598dee25b183d575ad88f00985b176d0783363837f8e20dde0749050e927cb655d16f9452ed96e4d7cf8143e927a1e0d9ff1e1d315f134f2ad6b798b35ce0", + "updateClientVkey": "0x00e43c9c112c22948738c5eb4bedbee71c9fd387ea7b2b18379d541c0f7768cc", + "membershipVkey": "0x00cca224de03cee0c7ba699fe9a7a9fbf931ba81e4055c33982d5c5f369e5fbd", + "ucAndMembershipVkey": "0x00aa1a5fc6344745ccf17a6470b402e949084755f05766cb00a0366b4fc05c9d" } \ No newline at end of file diff --git a/contracts/src/SP1ICS07Tendermint.sol b/contracts/src/SP1ICS07Tendermint.sol index 04427ec..cd215e3 100644 --- a/contracts/src/SP1ICS07Tendermint.sol +++ b/contracts/src/SP1ICS07Tendermint.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.13; import {ICS07Tendermint} from "./ics07-tendermint/ICS07Tendermint.sol"; import {UpdateClientProgram} from "./ics07-tendermint/UpdateClientProgram.sol"; import {MembershipProgram} from "./ics07-tendermint/MembershipProgram.sol"; +import {UpdateClientAndMembershipProgram} from "./ics07-tendermint/UcAndMembershipProgram.sol"; import {ISP1Verifier} from "@sp1-contracts/ISP1Verifier.sol"; import "forge-std/console.sol"; @@ -13,11 +14,13 @@ import "forge-std/console.sol"; /// @custom:poc This is a proof of concept implementation. contract SP1ICS07Tendermint { /// @notice The verification key for the update client program. - bytes32 public immutable ics07UpdateClientProgramVkey; - /// @notice The verification key for the verify membership program. - bytes32 public immutable ics07VerifyMembershipProgramVkey; + bytes32 public immutable updateClientProgramVkey; + /// @notice The verification key for the verify (non)membership program. + bytes32 public immutable membershipProgramVkey; + /// @notice The verification key for the update client and membership program. + bytes32 public immutable updateClientAndMembershipProgramVkey; /// @notice The SP1 verifier contract. - ISP1Verifier public verifier; + ISP1Verifier public immutable verifier; /// @notice The ICS07Tendermint client state ICS07Tendermint.ClientState private clientState; @@ -28,19 +31,23 @@ contract SP1ICS07Tendermint { uint64 public constant ALLOWED_SP1_CLOCK_DRIFT = 3000; // 3000 seconds /// @notice The constructor sets the program verification key and the initial client and consensus states. - /// @param _ics07UpdateClientProgramVkey The verification key for the update client program. + /// @param _updateClientProgramVkey The verification key for the update client program. + /// @param _membershipProgramVkey The verification key for the verify (non)membership program. + /// @param _updateClientAndMembershipProgramVkey The verification key for the update client and membership program. /// @param _verifier The address of the SP1 verifier contract. /// @param _clientState The encoded initial client state. /// @param _consensusState The encoded initial consensus state. constructor( - bytes32 _ics07UpdateClientProgramVkey, - bytes32 _ics07VerifyMembershipProgramVkey, + bytes32 _updateClientProgramVkey, + bytes32 _membershipProgramVkey, + bytes32 _updateClientAndMembershipProgramVkey, address _verifier, bytes memory _clientState, bytes32 _consensusState ) { - ics07UpdateClientProgramVkey = _ics07UpdateClientProgramVkey; - ics07VerifyMembershipProgramVkey = _ics07VerifyMembershipProgramVkey; + updateClientProgramVkey = _updateClientProgramVkey; + membershipProgramVkey = _membershipProgramVkey; + updateClientAndMembershipProgramVkey = _updateClientAndMembershipProgramVkey; verifier = ISP1Verifier(_verifier); clientState = abi.decode(_clientState, (ICS07Tendermint.ClientState)); @@ -85,7 +92,7 @@ contract SP1ICS07Tendermint { // TODO: Make sure that other checks have been made in the proof verification // such as the consensus state not being outside the trusting period. - verifier.verifyProof(ics07UpdateClientProgramVkey, publicValues, proof); + verifier.verifyProof(updateClientProgramVkey, publicValues, proof); // adding the new consensus state to the mapping clientState.latest_height = output.new_height; @@ -133,33 +140,85 @@ contract SP1ICS07Tendermint { continue; } - MembershipProgram.KVPair memory kvPair = output.kv_pairs[i]; - require( - kvPairHash == keccak256(abi.encode(kvPair)), + kvPairHash == keccak256(abi.encode(output.kv_pairs[i])), "SP1ICS07Tendermint: kvPair hash mismatch" ); + } + + validateMembershipOutput( + output.commitment_root, + proofHeight, + trustedConsensusStateBz + ); + + verifier.verifyProof(membershipProgramVkey, publicValues, proof); + } - validateMembershipOutput( - output, - proofHeight, - trustedConsensusStateBz + /// @notice The entrypoint for updating the client and membership proof. + /// @dev This function verifies the public values and forwards the proof to the SP1 verifier. + /// @param proof The encoded proof. + /// @param publicValues The encoded public values. + /// @param kvPairHashes The hashes of the key-value pairs. + function verifyIcs07UcAndMembershipProof( + bytes memory proof, + bytes memory publicValues, + bytes32[] memory kvPairHashes + ) public { + UpdateClientAndMembershipProgram.UcAndMembershipOutput + memory output = abi.decode( + publicValues, + (UpdateClientAndMembershipProgram.UcAndMembershipOutput) + ); + + validateUpdateClientPublicValues(output.update_client_output); + // adding the new consensus state to the mapping + clientState.latest_height = output.update_client_output.new_height; + consensusStateHashes[ + output.update_client_output.new_height.revision_height + ] = keccak256( + abi.encode(output.update_client_output.new_consensus_state) + ); + + require( + kvPairHashes.length != 0, + "SP1ICS07Tendermint: kvPairs length is zero" + ); + + require( + kvPairHashes.length <= output.kv_pairs.length, + "SP1ICS07Tendermint: kvPairs length mismatch" + ); + + // loop through the key-value pairs and validate them + for (uint8 i = 0; i < kvPairHashes.length; i++) { + bytes32 kvPairHash = kvPairHashes[i]; + if (kvPairHash == 0) { + // skip the empty hash + continue; + } + + require( + kvPairHash == keccak256(abi.encode(output.kv_pairs[i])), + "SP1ICS07Tendermint: kvPair hash mismatch" ); } - verifier.verifyProof( - ics07VerifyMembershipProgramVkey, - publicValues, - proof + validateMembershipOutput( + output.update_client_output.new_consensus_state.root, + output.update_client_output.new_height.revision_height, + abi.encode(output.update_client_output.new_consensus_state) ); + + verifier.verifyProof(updateClientProgramVkey, publicValues, proof); } - /// @notice Validates the MembershipOutput public values and decodes the trusted consensus state. - /// @param output The public values. + /// @notice Validates the MembershipOutput public values. + /// @param outputCommitmentRoot The commitment root of the output. /// @param proofHeight The height of the proof. /// @param trustedConsensusStateBz The encoded trusted consensus state. function validateMembershipOutput( - MembershipProgram.MembershipOutput memory output, + bytes32 outputCommitmentRoot, uint32 proofHeight, bytes memory trustedConsensusStateBz ) public view { @@ -173,7 +232,7 @@ contract SP1ICS07Tendermint { .decode(trustedConsensusStateBz, (ICS07Tendermint.ConsensusState)); require( - output.commitment_root == trustedConsensusState.root, + outputCommitmentRoot == trustedConsensusState.root, "SP1ICS07Tendermint: invalid commitment root" ); } @@ -222,4 +281,14 @@ contract SP1ICS07Tendermint { ); // TODO: Make sure that we don't need more checks. } + + /// @notice A dummy function to generate the ABI for the parameters. + function abiPublicTypes( + MembershipProgram.MembershipOutput memory output, + UpdateClientAndMembershipProgram.UcAndMembershipOutput memory output2 + ) public pure { + // This is a dummy function to generate the ABI for MembershipOutput + // so that it can be used in the SP1 verifier contract. + // The function is not used in the contract. + } } diff --git a/contracts/src/ics07-tendermint/UcAndMembershipProgram.sol b/contracts/src/ics07-tendermint/UcAndMembershipProgram.sol new file mode 100644 index 000000000..08cfddd --- /dev/null +++ b/contracts/src/ics07-tendermint/UcAndMembershipProgram.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {ICS07Tendermint} from "./ICS07Tendermint.sol"; +import {MembershipProgram} from "./MembershipProgram.sol"; +import {UpdateClientProgram} from "./UpdateClientProgram.sol"; + +/// @title UpdateClientAndMembershipProgram +/// @author srdtrk +/// @notice Defines shared types for the update client and membership program. +contract UpdateClientAndMembershipProgram { + /// @notice The public value output for the sp1 update client and membership program. + struct UcAndMembershipOutput { + /// Update client program output. + UpdateClientProgram.UpdateClientOutput update_client_output; + /// The key-value pairs verified by the membership program in the proposed header. + MembershipProgram.KVPair[] kv_pairs; + } +} diff --git a/contracts/test/MembershipTest.sol b/contracts/test/MembershipTest.sol index fb0d008..3e51f6e 100644 --- a/contracts/test/MembershipTest.sol +++ b/contracts/test/MembershipTest.sol @@ -16,8 +16,6 @@ struct SP1ICS07MembershipFixtureJson { uint32 proofHeight; bytes trustedClientState; bytes trustedConsensusState; - bytes32 updateClientVkey; - bytes32 membershipVkey; bytes32 commitmentRoot; bytes publicValues; bytes proof; @@ -63,8 +61,6 @@ abstract contract MembershipTest is SP1ICS07TendermintTest { ".trustedConsensusState" ); uint32 proofHeight = uint32(json.readUint(".proofHeight")); - bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); - bytes32 membershipVkey = json.readBytes32(".membershipVkey"); bytes32 commitmentRoot = json.readBytes32(".commitmentRoot"); bytes memory publicValues = json.readBytes(".publicValues"); bytes memory proof = json.readBytes(".proof"); @@ -76,8 +72,6 @@ abstract contract MembershipTest is SP1ICS07TendermintTest { trustedClientState: trustedClientState, trustedConsensusState: trustedConsensusState, proofHeight: proofHeight, - updateClientVkey: updateClientVkey, - membershipVkey: membershipVkey, publicValues: publicValues, proof: proof, kvPairsBz: kvPairsBz diff --git a/contracts/test/SP1ICS07TendermintTest.sol b/contracts/test/SP1ICS07TendermintTest.sol index 17f8526..785079c 100644 --- a/contracts/test/SP1ICS07TendermintTest.sol +++ b/contracts/test/SP1ICS07TendermintTest.sol @@ -15,6 +15,7 @@ struct SP1ICS07GenesisFixtureJson { bytes trustedConsensusState; bytes32 updateClientVkey; bytes32 membershipVkey; + bytes32 ucAndMembershipVkey; } abstract contract SP1ICS07TendermintTest is Test { @@ -46,6 +47,7 @@ abstract contract SP1ICS07TendermintTest is Test { ics07Tendermint = new SP1ICS07Tendermint( genesisFixture.updateClientVkey, genesisFixture.membershipVkey, + genesisFixture.ucAndMembershipVkey, address(verifier), genesisFixture.trustedClientState, trustedConsensusHash @@ -67,6 +69,7 @@ abstract contract SP1ICS07TendermintTest is Test { mockIcs07Tendermint = new SP1ICS07Tendermint( mockGenesisFixture.updateClientVkey, mockGenesisFixture.membershipVkey, + mockGenesisFixture.ucAndMembershipVkey, address(mockVerifier), mockGenesisFixture.trustedClientState, mockTrustedConsensusHash @@ -81,12 +84,13 @@ abstract contract SP1ICS07TendermintTest is Test { assert(clientState.trust_level.numerator == 1); assert(clientState.trust_level.denominator == 3); assert(clientState.latest_height.revision_number == 4); - assert(clientState.latest_height.revision_height == 2110658); assert(clientState.trusting_period == 1_209_600); assert(clientState.unbonding_period == 1_209_600); assert(clientState.is_frozen == false); - bytes32 consensusHash = mockIcs07Tendermint.getConsensusState(2110658); + bytes32 consensusHash = mockIcs07Tendermint.getConsensusState( + clientState.latest_height.revision_height + ); assert(consensusHash == mockTrustedConsensusHash); } @@ -102,12 +106,14 @@ abstract contract SP1ICS07TendermintTest is Test { ); bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); bytes32 membershipVkey = json.readBytes32(".membershipVkey"); + bytes32 ucAndMembershipVkey = json.readBytes32(".ucAndMembershipVkey"); SP1ICS07GenesisFixtureJson memory fix = SP1ICS07GenesisFixtureJson({ trustedClientState: trustedClientState, trustedConsensusState: trustedConsensusState, updateClientVkey: updateClientVkey, - membershipVkey: membershipVkey + membershipVkey: membershipVkey, + ucAndMembershipVkey: ucAndMembershipVkey }); return fix; diff --git a/contracts/test/UcAndMembership.t.sol b/contracts/test/UcAndMembership.t.sol new file mode 100644 index 000000000..cec441d --- /dev/null +++ b/contracts/test/UcAndMembership.t.sol @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/console.sol"; +import {Test} from "forge-std/Test.sol"; +import {stdJson} from "forge-std/StdJson.sol"; +import {stdError} from "forge-std/StdError.sol"; +import {ICS07Tendermint} from "../src/ics07-tendermint/ICS07Tendermint.sol"; +import {UpdateClientProgram} from "../src/ics07-tendermint/UpdateClientProgram.sol"; +import {UpdateClientAndMembershipProgram} from "../src/ics07-tendermint/UcAndMembershipProgram.sol"; +import {MembershipProgram} from "../src/ics07-tendermint/MembershipProgram.sol"; +import {SP1ICS07TendermintTest} from "./SP1ICS07TendermintTest.sol"; +import {SP1ICS07Tendermint} from "../src/SP1ICS07Tendermint.sol"; +import {SP1Verifier} from "@sp1-contracts/SP1Verifier.sol"; +import {SP1MockVerifier} from "@sp1-contracts/SP1MockVerifier.sol"; + +struct SP1ICS07UcAndMemberhsipFixtureJson { + bytes trustedClientState; + bytes trustedConsensusState; + bytes targetConsensusState; + uint32 targetHeight; + bytes publicValues; + bytes proof; + bytes kvPairsBz; +} + +string constant verifyMembershipPath = "clients/07-tendermint-0/clientState"; +string constant verifyNonMembershipPath = "clients/07-tendermint-001/clientState"; + +contract SP1ICS07UpdateClientAndMembershipTest is SP1ICS07TendermintTest { + using stdJson for string; + + SP1ICS07UcAndMemberhsipFixtureJson public fixture; + SP1ICS07UcAndMemberhsipFixtureJson public mockFixture; + + function setUp() public { + fixture = loadFixture("uc_and_memberships_fixture.json"); + mockFixture = loadFixture("mock_uc_and_memberships_fixture.json"); + + setUpTest( + "uc_and_memberships_fixture.json", + "mock_uc_and_memberships_fixture.json" + ); + + ICS07Tendermint.ClientState memory clientState = mockIcs07Tendermint + .getClientState(); + assert( + clientState.latest_height.revision_height < mockFixture.targetHeight + ); + } + + function loadFixture( + string memory fileName + ) public view returns (SP1ICS07UcAndMemberhsipFixtureJson memory) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/fixtures/", fileName); + string memory json = vm.readFile(path); + bytes memory trustedClientState = json.readBytes(".trustedClientState"); + bytes memory trustedConsensusState = json.readBytes( + ".trustedConsensusState" + ); + bytes memory targetConsensusState = json.readBytes( + ".targetConsensusState" + ); + uint32 targetHeight = uint32(json.readUint(".targetHeight")); + bytes memory publicValues = json.readBytes(".publicValues"); + bytes memory proof = json.readBytes(".proof"); + bytes memory kvPairsBz = json.readBytes(".kvPairs"); + + SP1ICS07UcAndMemberhsipFixtureJson + memory fix = SP1ICS07UcAndMemberhsipFixtureJson({ + trustedClientState: trustedClientState, + trustedConsensusState: trustedConsensusState, + targetConsensusState: targetConsensusState, + targetHeight: targetHeight, + publicValues: publicValues, + proof: proof, + kvPairsBz: kvPairsBz + }); + + return fix; + } + + // Confirm that submitting a real proof passes the verifier. + function test_ValidUpdateClientAndMultiMembership() public { + UpdateClientAndMembershipProgram.UcAndMembershipOutput + memory output = abi.decode( + fixture.publicValues, + (UpdateClientAndMembershipProgram.UcAndMembershipOutput) + ); + // set a correct timestamp + vm.warp(output.update_client_output.env.now + 300); + + bytes32[] memory kvPairHashes = new bytes32[](2); + kvPairHashes[0] = keccak256(abi.encode(kvPairs()[0])); + kvPairHashes[1] = keccak256(abi.encode(kvPairs()[1])); + + // run verify + ics07Tendermint.verifyIcs07UcAndMembershipProof( + fixture.proof, + fixture.publicValues, + kvPairHashes + ); + + // to console + console.log( + "UpdateClientAndMultiMembership gas used: ", + vm.lastCallGas().gasTotalUsed + ); + + ICS07Tendermint.ClientState memory clientState = ics07Tendermint + .getClientState(); + assert( + keccak256(bytes(clientState.chain_id)) == + keccak256(bytes("mocha-4")) + ); + assert(clientState.trust_level.numerator == 1); + assert(clientState.trust_level.denominator == 3); + assert(clientState.latest_height.revision_number == 4); + assert( + clientState.latest_height.revision_height == fixture.targetHeight + ); + assert(clientState.trusting_period == 1_209_600); + assert(clientState.unbonding_period == 1_209_600); + assert(clientState.is_frozen == false); + + bytes32 consensusHash = ics07Tendermint.getConsensusState( + fixture.targetHeight + ); + ICS07Tendermint.ConsensusState memory expConsensusState = abi.decode( + fixture.targetConsensusState, + (ICS07Tendermint.ConsensusState) + ); + assert(consensusHash == keccak256(abi.encode(expConsensusState))); + } + + function test_ValidMockUpdateClientAndMultiMembership() public { + UpdateClientAndMembershipProgram.UcAndMembershipOutput + memory output = abi.decode( + mockFixture.publicValues, + (UpdateClientAndMembershipProgram.UcAndMembershipOutput) + ); + vm.warp(output.update_client_output.env.now + 300); + + bytes32[] memory kvPairHashes = new bytes32[](2); + kvPairHashes[0] = keccak256(abi.encode(mockKvPairs()[0])); + kvPairHashes[1] = keccak256(abi.encode(mockKvPairs()[1])); + + mockIcs07Tendermint.verifyIcs07UcAndMembershipProof( + bytes(""), + mockFixture.publicValues, + kvPairHashes + ); + + ICS07Tendermint.ClientState memory clientState = mockIcs07Tendermint + .getClientState(); + assert( + keccak256(bytes(clientState.chain_id)) == + keccak256(bytes("mocha-4")) + ); + assert(clientState.trust_level.numerator == 1); + assert(clientState.trust_level.denominator == 3); + assert(clientState.latest_height.revision_number == 4); + assert( + clientState.latest_height.revision_height == fixture.targetHeight + ); + assert(clientState.trusting_period == 1_209_600); + assert(clientState.unbonding_period == 1_209_600); + assert(clientState.is_frozen == false); + + bytes32 consensusHash = mockIcs07Tendermint.getConsensusState( + mockFixture.targetHeight + ); + ICS07Tendermint.ConsensusState memory expConsensusState = abi.decode( + mockFixture.targetConsensusState, + (ICS07Tendermint.ConsensusState) + ); + assert(consensusHash == keccak256(abi.encode(expConsensusState))); + } + + function test_ValidUpdateClientAndVerifyMembership() public { + UpdateClientAndMembershipProgram.UcAndMembershipOutput + memory output = abi.decode( + fixture.publicValues, + (UpdateClientAndMembershipProgram.UcAndMembershipOutput) + ); + // set a correct timestamp + vm.warp(output.update_client_output.env.now + 300); + + bytes32[] memory kvPairHashes = new bytes32[](2); + kvPairHashes[0] = keccak256(abi.encode(kvPairs()[0])); + kvPairHashes[1] = bytes32(0); + + // run verify + ics07Tendermint.verifyIcs07UcAndMembershipProof( + fixture.proof, + fixture.publicValues, + kvPairHashes + ); + + // to console + console.log( + "UpdateClientAndVerifyMembership gas used: ", + vm.lastCallGas().gasTotalUsed + ); + + ICS07Tendermint.ClientState memory clientState = ics07Tendermint + .getClientState(); + assert( + keccak256(bytes(clientState.chain_id)) == + keccak256(bytes("mocha-4")) + ); + assert(clientState.trust_level.numerator == 1); + assert(clientState.trust_level.denominator == 3); + assert(clientState.latest_height.revision_number == 4); + assert( + clientState.latest_height.revision_height == fixture.targetHeight + ); + assert(clientState.trusting_period == 1_209_600); + assert(clientState.unbonding_period == 1_209_600); + assert(clientState.is_frozen == false); + + bytes32 consensusHash = ics07Tendermint.getConsensusState( + fixture.targetHeight + ); + ICS07Tendermint.ConsensusState memory expConsensusState = abi.decode( + fixture.targetConsensusState, + (ICS07Tendermint.ConsensusState) + ); + assert(consensusHash == keccak256(abi.encode(expConsensusState))); + } + + // Confirm that submitting a non-empty proof with the mock verifier fails. + function test_Invalid_MockUpdateClient() public { + bytes32[] memory kvPairHashes = new bytes32[](2); + kvPairHashes[0] = keccak256(abi.encode(mockKvPairs()[0])); + kvPairHashes[1] = keccak256(abi.encode(mockKvPairs()[1])); + + vm.expectRevert(); + mockIcs07Tendermint.verifyIcs07UcAndMembershipProof( + bytes("invalid"), + mockFixture.publicValues, + kvPairHashes + ); + + // wrong hash + kvPairHashes[0] = keccak256("random"); + vm.expectRevert(); + mockIcs07Tendermint.verifyIcs07UcAndMembershipProof( + bytes(""), + mockFixture.publicValues, + kvPairHashes + ); + } + + // Confirm that submitting a random proof with the real verifier fails. + function test_Invalid_UpdateClient() public { + bytes32[] memory kvPairHashes = new bytes32[](2); + kvPairHashes[0] = keccak256(abi.encode(kvPairs()[0])); + kvPairHashes[1] = keccak256(abi.encode(kvPairs()[1])); + + vm.expectRevert(); + ics07Tendermint.verifyIcs07UcAndMembershipProof( + bytes("invalid"), + fixture.publicValues, + kvPairHashes + ); + } + + function kvPairs() public view returns (MembershipProgram.KVPair[] memory) { + return abi.decode(fixture.kvPairsBz, (MembershipProgram.KVPair[])); + } + + function mockKvPairs() + public + view + returns (MembershipProgram.KVPair[] memory) + { + return abi.decode(mockFixture.kvPairsBz, (MembershipProgram.KVPair[])); + } +} diff --git a/contracts/test/UpdateClient.t.sol b/contracts/test/UpdateClient.t.sol index 9520ac3..eb96c66 100644 --- a/contracts/test/UpdateClient.t.sol +++ b/contracts/test/UpdateClient.t.sol @@ -17,8 +17,6 @@ struct SP1ICS07UpdateClientFixtureJson { bytes trustedConsensusState; bytes targetConsensusState; uint32 targetHeight; - bytes32 updateClientVkey; - bytes32 membershipVkey; bytes publicValues; bytes proof; } @@ -37,6 +35,12 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest { "update_client_fixture.json", "mock_update_client_fixture.json" ); + + ICS07Tendermint.ClientState memory clientState = mockIcs07Tendermint + .getClientState(); + assert( + clientState.latest_height.revision_height < mockFixture.targetHeight + ); } function loadFixture( @@ -53,8 +57,6 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest { ".targetConsensusState" ); uint32 targetHeight = uint32(json.readUint(".targetHeight")); - bytes32 updateClientVkey = json.readBytes32(".updateClientVkey"); - bytes32 membershipVkey = json.readBytes32(".membershipVkey"); bytes memory publicValues = json.readBytes(".publicValues"); bytes memory proof = json.readBytes(".proof"); @@ -64,8 +66,6 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest { trustedConsensusState: trustedConsensusState, targetConsensusState: targetConsensusState, targetHeight: targetHeight, - updateClientVkey: updateClientVkey, - membershipVkey: membershipVkey, publicValues: publicValues, proof: proof }); @@ -100,12 +100,16 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest { assert(clientState.trust_level.numerator == 1); assert(clientState.trust_level.denominator == 3); assert(clientState.latest_height.revision_number == 4); - assert(clientState.latest_height.revision_height == 2110668); + assert( + clientState.latest_height.revision_height == fixture.targetHeight + ); assert(clientState.trusting_period == 1_209_600); assert(clientState.unbonding_period == 1_209_600); assert(clientState.is_frozen == false); - bytes32 consensusHash = ics07Tendermint.getConsensusState(2110668); + bytes32 consensusHash = ics07Tendermint.getConsensusState( + fixture.targetHeight + ); ICS07Tendermint.ConsensusState memory expConsensusState = abi.decode( fixture.targetConsensusState, (ICS07Tendermint.ConsensusState) @@ -137,12 +141,17 @@ contract SP1ICS07UpdateClientTest is SP1ICS07TendermintTest { assert(clientState.trust_level.numerator == 1); assert(clientState.trust_level.denominator == 3); assert(clientState.latest_height.revision_number == 4); - assert(clientState.latest_height.revision_height == 2110668); + assert( + clientState.latest_height.revision_height == + mockFixture.targetHeight + ); assert(clientState.trusting_period == 1_209_600); assert(clientState.unbonding_period == 1_209_600); assert(clientState.is_frozen == false); - bytes32 consensusHash = mockIcs07Tendermint.getConsensusState(2110668); + bytes32 consensusHash = mockIcs07Tendermint.getConsensusState( + mockFixture.targetHeight + ); ICS07Tendermint.ConsensusState memory expConsensusState = abi.decode( fixture.targetConsensusState, (ICS07Tendermint.ConsensusState) diff --git a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go index 70a071b..98e8e1b 100644 --- a/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go +++ b/e2e/interchaintestv8/types/sp1ics07tendermint/contract.go @@ -70,6 +70,12 @@ type MembershipProgramMembershipOutput struct { KvPairs []MembershipProgramKVPair } +// UpdateClientAndMembershipProgramUcAndMembershipOutput is an auto generated low-level Go binding around an user-defined struct. +type UpdateClientAndMembershipProgramUcAndMembershipOutput struct { + UpdateClientOutput UpdateClientProgramUpdateClientOutput + KvPairs []MembershipProgramKVPair +} + // UpdateClientProgramEnv is an auto generated low-level Go binding around an user-defined struct. type UpdateClientProgramEnv struct { ChainId string @@ -89,7 +95,7 @@ type UpdateClientProgramUpdateClientOutput struct { // ContractMetaData contains all meta data concerning the Contract contract. var ContractMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_ics07UpdateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_ics07VerifyMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ClientState\",\"components\":[{\"name\":\"chain_id\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trust_level\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latest_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trusting_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbonding_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"is_frozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusState\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ics07UpdateClientProgramVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ics07VerifyMembershipProgramVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateMembershipOutput\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structMembershipProgram.MembershipOutput\",\"components\":[{\"name\":\"commitment_root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kv_pairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateUpdateClientPublicValues\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.UpdateClientOutput\",\"components\":[{\"name\":\"trusted_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"new_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.Env\",\"components\":[{\"name\":\"chain_id\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trust_threshold\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trusting_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trusted_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"new_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyIcs07MembershipProof\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyIcs07UpdateClientProof\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"}]", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_updateClientProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_membershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_updateClientAndMembershipProgramVkey\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_verifier\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_clientState\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"_consensusState\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"ALLOWED_SP1_CLOCK_DRIFT\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"abiPublicTypes\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structMembershipProgram.MembershipOutput\",\"components\":[{\"name\":\"commitment_root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"kv_pairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]},{\"name\":\"output2\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientAndMembershipProgram.UcAndMembershipOutput\",\"components\":[{\"name\":\"update_client_output\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.UpdateClientOutput\",\"components\":[{\"name\":\"trusted_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"new_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.Env\",\"components\":[{\"name\":\"chain_id\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trust_threshold\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trusting_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trusted_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"new_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]},{\"name\":\"kv_pairs\",\"type\":\"tuple[]\",\"internalType\":\"structMembershipProgram.KVPair[]\",\"components\":[{\"name\":\"key\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"value\",\"type\":\"bytes\",\"internalType\":\"bytes\"}]}]}],\"outputs\":[],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"getClientState\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ClientState\",\"components\":[{\"name\":\"chain_id\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trust_level\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"latest_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"trusting_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"unbonding_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"is_frozen\",\"type\":\"bool\",\"internalType\":\"bool\"}]}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getConsensusState\",\"inputs\":[{\"name\":\"revisionHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"membershipProgramVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateClientAndMembershipProgramVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"updateClientProgramVkey\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateMembershipOutput\",\"inputs\":[{\"name\":\"outputCommitmentRoot\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"validateUpdateClientPublicValues\",\"inputs\":[{\"name\":\"output\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.UpdateClientOutput\",\"components\":[{\"name\":\"trusted_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"new_consensus_state\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.ConsensusState\",\"components\":[{\"name\":\"timestamp\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"root\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"next_validators_hash\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}]},{\"name\":\"env\",\"type\":\"tuple\",\"internalType\":\"structUpdateClientProgram.Env\",\"components\":[{\"name\":\"chain_id\",\"type\":\"string\",\"internalType\":\"string\"},{\"name\":\"trust_threshold\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.TrustThreshold\",\"components\":[{\"name\":\"numerator\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"denominator\",\"type\":\"uint8\",\"internalType\":\"uint8\"}]},{\"name\":\"trusting_period\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"now\",\"type\":\"uint64\",\"internalType\":\"uint64\"}]},{\"name\":\"trusted_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]},{\"name\":\"new_height\",\"type\":\"tuple\",\"internalType\":\"structICS07Tendermint.Height\",\"components\":[{\"name\":\"revision_number\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"revision_height\",\"type\":\"uint32\",\"internalType\":\"uint32\"}]}]}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractISP1Verifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyIcs07MembershipProof\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"proofHeight\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"trustedConsensusStateBz\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"verifyIcs07UcAndMembershipProof\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"kvPairHashes\",\"type\":\"bytes32[]\",\"internalType\":\"bytes32[]\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"verifyIcs07UpdateClientProof\",\"inputs\":[{\"name\":\"proof\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"publicValues\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"}]", } // ContractABI is the input ABI used to generate the binding from. @@ -269,6 +275,35 @@ func (_Contract *ContractCallerSession) ALLOWEDSP1CLOCKDRIFT() (uint64, error) { return _Contract.Contract.ALLOWEDSP1CLOCKDRIFT(&_Contract.CallOpts) } +// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() +func (_Contract *ContractCaller) AbiPublicTypes(opts *bind.CallOpts, output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "abiPublicTypes", output, output2) + + if err != nil { + return err + } + + return err + +} + +// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() +func (_Contract *ContractSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2) +} + +// AbiPublicTypes is a free data retrieval call binding the contract method 0x31debad4. +// +// Solidity: function abiPublicTypes((bytes32,(string,bytes)[]) output, (((uint64,bytes32,bytes32),(uint64,bytes32,bytes32),(string,(uint8,uint8),uint32,uint64),(uint32,uint32),(uint32,uint32)),(string,bytes)[]) output2) pure returns() +func (_Contract *ContractCallerSession) AbiPublicTypes(output MembershipProgramMembershipOutput, output2 UpdateClientAndMembershipProgramUcAndMembershipOutput) error { + return _Contract.Contract.AbiPublicTypes(&_Contract.CallOpts, output, output2) +} + // GetClientState is a free data retrieval call binding the contract method 0xef913a4b. // // Solidity: function getClientState() view returns((string,(uint8,uint8),(uint32,uint32),uint32,uint32,bool)) @@ -331,12 +366,12 @@ func (_Contract *ContractCallerSession) GetConsensusState(revisionHeight uint32) return _Contract.Contract.GetConsensusState(&_Contract.CallOpts, revisionHeight) } -// Ics07UpdateClientProgramVkey is a free data retrieval call binding the contract method 0x975c0796. +// MembershipProgramVkey is a free data retrieval call binding the contract method 0x2b69debf. // -// Solidity: function ics07UpdateClientProgramVkey() view returns(bytes32) -func (_Contract *ContractCaller) Ics07UpdateClientProgramVkey(opts *bind.CallOpts) ([32]byte, error) { +// Solidity: function membershipProgramVkey() view returns(bytes32) +func (_Contract *ContractCaller) MembershipProgramVkey(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "ics07UpdateClientProgramVkey") + err := _Contract.contract.Call(opts, &out, "membershipProgramVkey") if err != nil { return *new([32]byte), err @@ -348,26 +383,26 @@ func (_Contract *ContractCaller) Ics07UpdateClientProgramVkey(opts *bind.CallOpt } -// Ics07UpdateClientProgramVkey is a free data retrieval call binding the contract method 0x975c0796. +// MembershipProgramVkey is a free data retrieval call binding the contract method 0x2b69debf. // -// Solidity: function ics07UpdateClientProgramVkey() view returns(bytes32) -func (_Contract *ContractSession) Ics07UpdateClientProgramVkey() ([32]byte, error) { - return _Contract.Contract.Ics07UpdateClientProgramVkey(&_Contract.CallOpts) +// Solidity: function membershipProgramVkey() view returns(bytes32) +func (_Contract *ContractSession) MembershipProgramVkey() ([32]byte, error) { + return _Contract.Contract.MembershipProgramVkey(&_Contract.CallOpts) } -// Ics07UpdateClientProgramVkey is a free data retrieval call binding the contract method 0x975c0796. +// MembershipProgramVkey is a free data retrieval call binding the contract method 0x2b69debf. // -// Solidity: function ics07UpdateClientProgramVkey() view returns(bytes32) -func (_Contract *ContractCallerSession) Ics07UpdateClientProgramVkey() ([32]byte, error) { - return _Contract.Contract.Ics07UpdateClientProgramVkey(&_Contract.CallOpts) +// Solidity: function membershipProgramVkey() view returns(bytes32) +func (_Contract *ContractCallerSession) MembershipProgramVkey() ([32]byte, error) { + return _Contract.Contract.MembershipProgramVkey(&_Contract.CallOpts) } -// Ics07VerifyMembershipProgramVkey is a free data retrieval call binding the contract method 0xc77eb6c2. +// UpdateClientAndMembershipProgramVkey is a free data retrieval call binding the contract method 0x2e930d2f. // -// Solidity: function ics07VerifyMembershipProgramVkey() view returns(bytes32) -func (_Contract *ContractCaller) Ics07VerifyMembershipProgramVkey(opts *bind.CallOpts) ([32]byte, error) { +// Solidity: function updateClientAndMembershipProgramVkey() view returns(bytes32) +func (_Contract *ContractCaller) UpdateClientAndMembershipProgramVkey(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "ics07VerifyMembershipProgramVkey") + err := _Contract.contract.Call(opts, &out, "updateClientAndMembershipProgramVkey") if err != nil { return *new([32]byte), err @@ -379,26 +414,57 @@ func (_Contract *ContractCaller) Ics07VerifyMembershipProgramVkey(opts *bind.Cal } -// Ics07VerifyMembershipProgramVkey is a free data retrieval call binding the contract method 0xc77eb6c2. +// UpdateClientAndMembershipProgramVkey is a free data retrieval call binding the contract method 0x2e930d2f. // -// Solidity: function ics07VerifyMembershipProgramVkey() view returns(bytes32) -func (_Contract *ContractSession) Ics07VerifyMembershipProgramVkey() ([32]byte, error) { - return _Contract.Contract.Ics07VerifyMembershipProgramVkey(&_Contract.CallOpts) +// Solidity: function updateClientAndMembershipProgramVkey() view returns(bytes32) +func (_Contract *ContractSession) UpdateClientAndMembershipProgramVkey() ([32]byte, error) { + return _Contract.Contract.UpdateClientAndMembershipProgramVkey(&_Contract.CallOpts) } -// Ics07VerifyMembershipProgramVkey is a free data retrieval call binding the contract method 0xc77eb6c2. +// UpdateClientAndMembershipProgramVkey is a free data retrieval call binding the contract method 0x2e930d2f. // -// Solidity: function ics07VerifyMembershipProgramVkey() view returns(bytes32) -func (_Contract *ContractCallerSession) Ics07VerifyMembershipProgramVkey() ([32]byte, error) { - return _Contract.Contract.Ics07VerifyMembershipProgramVkey(&_Contract.CallOpts) +// Solidity: function updateClientAndMembershipProgramVkey() view returns(bytes32) +func (_Contract *ContractCallerSession) UpdateClientAndMembershipProgramVkey() ([32]byte, error) { + return _Contract.Contract.UpdateClientAndMembershipProgramVkey(&_Contract.CallOpts) } -// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x46264891. +// UpdateClientProgramVkey is a free data retrieval call binding the contract method 0xbad9af88. // -// Solidity: function validateMembershipOutput((bytes32,(string,bytes)[]) output, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() -func (_Contract *ContractCaller) ValidateMembershipOutput(opts *bind.CallOpts, output MembershipProgramMembershipOutput, proofHeight uint32, trustedConsensusStateBz []byte) error { +// Solidity: function updateClientProgramVkey() view returns(bytes32) +func (_Contract *ContractCaller) UpdateClientProgramVkey(opts *bind.CallOpts) ([32]byte, error) { var out []interface{} - err := _Contract.contract.Call(opts, &out, "validateMembershipOutput", output, proofHeight, trustedConsensusStateBz) + err := _Contract.contract.Call(opts, &out, "updateClientProgramVkey") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// UpdateClientProgramVkey is a free data retrieval call binding the contract method 0xbad9af88. +// +// Solidity: function updateClientProgramVkey() view returns(bytes32) +func (_Contract *ContractSession) UpdateClientProgramVkey() ([32]byte, error) { + return _Contract.Contract.UpdateClientProgramVkey(&_Contract.CallOpts) +} + +// UpdateClientProgramVkey is a free data retrieval call binding the contract method 0xbad9af88. +// +// Solidity: function updateClientProgramVkey() view returns(bytes32) +func (_Contract *ContractCallerSession) UpdateClientProgramVkey() ([32]byte, error) { + return _Contract.Contract.UpdateClientProgramVkey(&_Contract.CallOpts) +} + +// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x0ac733e2. +// +// Solidity: function validateMembershipOutput(bytes32 outputCommitmentRoot, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() +func (_Contract *ContractCaller) ValidateMembershipOutput(opts *bind.CallOpts, outputCommitmentRoot [32]byte, proofHeight uint32, trustedConsensusStateBz []byte) error { + var out []interface{} + err := _Contract.contract.Call(opts, &out, "validateMembershipOutput", outputCommitmentRoot, proofHeight, trustedConsensusStateBz) if err != nil { return err @@ -408,18 +474,18 @@ func (_Contract *ContractCaller) ValidateMembershipOutput(opts *bind.CallOpts, o } -// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x46264891. +// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x0ac733e2. // -// Solidity: function validateMembershipOutput((bytes32,(string,bytes)[]) output, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() -func (_Contract *ContractSession) ValidateMembershipOutput(output MembershipProgramMembershipOutput, proofHeight uint32, trustedConsensusStateBz []byte) error { - return _Contract.Contract.ValidateMembershipOutput(&_Contract.CallOpts, output, proofHeight, trustedConsensusStateBz) +// Solidity: function validateMembershipOutput(bytes32 outputCommitmentRoot, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() +func (_Contract *ContractSession) ValidateMembershipOutput(outputCommitmentRoot [32]byte, proofHeight uint32, trustedConsensusStateBz []byte) error { + return _Contract.Contract.ValidateMembershipOutput(&_Contract.CallOpts, outputCommitmentRoot, proofHeight, trustedConsensusStateBz) } -// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x46264891. +// ValidateMembershipOutput is a free data retrieval call binding the contract method 0x0ac733e2. // -// Solidity: function validateMembershipOutput((bytes32,(string,bytes)[]) output, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() -func (_Contract *ContractCallerSession) ValidateMembershipOutput(output MembershipProgramMembershipOutput, proofHeight uint32, trustedConsensusStateBz []byte) error { - return _Contract.Contract.ValidateMembershipOutput(&_Contract.CallOpts, output, proofHeight, trustedConsensusStateBz) +// Solidity: function validateMembershipOutput(bytes32 outputCommitmentRoot, uint32 proofHeight, bytes trustedConsensusStateBz) view returns() +func (_Contract *ContractCallerSession) ValidateMembershipOutput(outputCommitmentRoot [32]byte, proofHeight uint32, trustedConsensusStateBz []byte) error { + return _Contract.Contract.ValidateMembershipOutput(&_Contract.CallOpts, outputCommitmentRoot, proofHeight, trustedConsensusStateBz) } // ValidateUpdateClientPublicValues is a free data retrieval call binding the contract method 0x8de6ce1a. @@ -511,6 +577,27 @@ func (_Contract *ContractCallerSession) VerifyIcs07MembershipProof(proof []byte, return _Contract.Contract.VerifyIcs07MembershipProof(&_Contract.CallOpts, proof, publicValues, proofHeight, trustedConsensusStateBz, kvPairHashes) } +// VerifyIcs07UcAndMembershipProof is a paid mutator transaction binding the contract method 0xfceb230d. +// +// Solidity: function verifyIcs07UcAndMembershipProof(bytes proof, bytes publicValues, bytes32[] kvPairHashes) returns() +func (_Contract *ContractTransactor) VerifyIcs07UcAndMembershipProof(opts *bind.TransactOpts, proof []byte, publicValues []byte, kvPairHashes [][32]byte) (*types.Transaction, error) { + return _Contract.contract.Transact(opts, "verifyIcs07UcAndMembershipProof", proof, publicValues, kvPairHashes) +} + +// VerifyIcs07UcAndMembershipProof is a paid mutator transaction binding the contract method 0xfceb230d. +// +// Solidity: function verifyIcs07UcAndMembershipProof(bytes proof, bytes publicValues, bytes32[] kvPairHashes) returns() +func (_Contract *ContractSession) VerifyIcs07UcAndMembershipProof(proof []byte, publicValues []byte, kvPairHashes [][32]byte) (*types.Transaction, error) { + return _Contract.Contract.VerifyIcs07UcAndMembershipProof(&_Contract.TransactOpts, proof, publicValues, kvPairHashes) +} + +// VerifyIcs07UcAndMembershipProof is a paid mutator transaction binding the contract method 0xfceb230d. +// +// Solidity: function verifyIcs07UcAndMembershipProof(bytes proof, bytes publicValues, bytes32[] kvPairHashes) returns() +func (_Contract *ContractTransactorSession) VerifyIcs07UcAndMembershipProof(proof []byte, publicValues []byte, kvPairHashes [][32]byte) (*types.Transaction, error) { + return _Contract.Contract.VerifyIcs07UcAndMembershipProof(&_Contract.TransactOpts, proof, publicValues, kvPairHashes) +} + // VerifyIcs07UpdateClientProof is a paid mutator transaction binding the contract method 0x61d311c5. // // Solidity: function verifyIcs07UpdateClientProof(bytes proof, bytes publicValues) returns() diff --git a/elf/membership-riscv32im-succinct-zkvm-elf b/elf/membership-riscv32im-succinct-zkvm-elf index 1d0489d..dfdd4e0 100755 Binary files a/elf/membership-riscv32im-succinct-zkvm-elf and b/elf/membership-riscv32im-succinct-zkvm-elf differ diff --git a/elf/uc-and-membership-riscv32im-succinct-zkvm-elf b/elf/uc-and-membership-riscv32im-succinct-zkvm-elf new file mode 100755 index 000000000..66d2a86 Binary files /dev/null and b/elf/uc-and-membership-riscv32im-succinct-zkvm-elf differ diff --git a/elf/update-client-riscv32im-succinct-zkvm-elf b/elf/update-client-riscv32im-succinct-zkvm-elf index 8a9834f..80bc58b 100755 Binary files a/elf/update-client-riscv32im-succinct-zkvm-elf and b/elf/update-client-riscv32im-succinct-zkvm-elf differ diff --git a/justfile b/justfile index 81aa3af..82d5bdd 100644 --- a/justfile +++ b/justfile @@ -8,6 +8,9 @@ build-programs: cd programs/membership && cargo prove build mv elf/riscv32im-succinct-zkvm-elf elf/membership-riscv32im-succinct-zkvm-elf @echo "ELF created at 'elf/membership-riscv32im-succinct-zkvm-elf'" + cd programs/uc-and-membership && cargo prove build + mv elf/riscv32im-succinct-zkvm-elf elf/uc-and-membership-riscv32im-succinct-zkvm-elf + @echo "ELF created at 'elf/uc-and-membership-riscv32im-succinct-zkvm-elf'" # Build the operator executable using `cargo build` command build-operator: @@ -41,10 +44,11 @@ fixtures prover: @echo "Building the operator..." just build-operator @echo "Generating fixtures... This may take a while (up to 20 minutes)" - parallel --progress --shebang --ungroup -j 3 ::: \ - "RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures update-client --trusted-block 2110658 --target-block 2110668 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}update_client_fixture.json'" \ - "{{ if prover == "network" { "sleep 15 &&" } else { "" } }} RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures membership --key-paths 'clients/07-tendermint-0/clientState' --trusted-block 2110658 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}verify_membership_fixture.json'" \ - "{{ if prover == "network" { "sleep 30 &&" } else { "" } }} RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block 2110658 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}memberships_fixture.json'" + parallel --progress --shebang --ungroup -j 4 ::: \ + "RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures update-client --trusted-block 2230264 --target-block 2230274 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}update_client_fixture.json'" \ + "{{ if prover == "network" { "sleep 15 &&" } else { "" } }} RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures update-client-and-membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block 2230264 --target-block 2230274 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}uc_and_memberships_fixture.json'" \ + "{{ if prover == "network" { "sleep 30 &&" } else { "" } }} RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures membership --key-paths 'clients/07-tendermint-0/clientState' --trusted-block 2230264 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}verify_membership_fixture.json'" \ + "{{ if prover == "network" { "sleep 45 &&" } else { "" } }} RUST_LOG=info SP1_PROVER={{prover}} TENDERMINT_RPC_URL='https://rpc.celestia-mocha.com/' ./target/release/operator fixtures membership --key-paths clients/07-tendermint-0/clientState,clients/07-tendermint-001/clientState --trusted-block 2230264 -o 'contracts/fixtures/{{ if prover == "mock" { "mock_" } else { "" } }}memberships_fixture.json'" @echo "Fixtures generated at 'contracts/fixtures'" # Generate the `SP1ICS07Tendermint.json` file containing the ABI of the SP1ICS07Tendermint contract diff --git a/operator/src/bin/operator.rs b/operator/src/bin/operator.rs index f39b354..898cb9c 100644 --- a/operator/src/bin/operator.rs +++ b/operator/src/bin/operator.rs @@ -3,7 +3,7 @@ use sp1_ics07_tendermint_operator::{ cli::command::{fixtures, Commands, OperatorCli}, runners::{ self, - fixtures::{membership, update_client}, + fixtures::{membership, uc_and_mem, update_client}, }, }; use sp1_sdk::utils::setup_logger; @@ -26,6 +26,7 @@ async fn main() -> anyhow::Result<()> { Commands::Fixtures(cmd) => match cmd.command { fixtures::Cmds::UpdateClient(args) => update_client::run(args).await, fixtures::Cmds::Membership(args) => membership::run(args).await, + fixtures::Cmds::UpdateClientAndMembership(args) => uc_and_mem::run(args).await, }, } } diff --git a/operator/src/cli/command.rs b/operator/src/cli/command.rs index 5efd6ce..04e5514 100644 --- a/operator/src/cli/command.rs +++ b/operator/src/cli/command.rs @@ -68,8 +68,10 @@ pub mod fixtures { pub enum Cmds { /// The subcommand to generate the update client fixtures. UpdateClient(UpdateClientCmd), - /// The subcommand to generate the verify membership fixtures. + /// The subcommand to generate the verify (non)membership fixtures. Membership(MembershipCmd), + /// The subcommand to generate the update client and verify (non)membership fixtures. + UpdateClientAndMembership(UpdateClientAndMembershipCmd), } /// The arguments for the `UpdateClient` fixture executable. @@ -105,4 +107,25 @@ pub mod fixtures { #[clap(long, short = 'o')] pub output_path: String, } + + /// The arguments for the `UpdateClientAndMembership` fixture executable. + #[derive(Parser, Debug, Clone)] + #[command(about = "Generate the update client and membership fixture")] + pub struct UpdateClientAndMembershipCmd { + /// Trusted block. + #[clap(long)] + pub trusted_block: u32, + + /// Target block. + #[clap(long, env)] + pub target_block: u32, + + /// Key paths to prove membership. + #[clap(long, value_delimiter = ',')] + pub key_paths: Vec, + + /// Fixture path. + #[clap(long, short = 'o')] + pub output_path: String, + } } diff --git a/operator/src/programs.rs b/operator/src/programs.rs index 4bdfa23..e9720ba 100644 --- a/operator/src/programs.rs +++ b/operator/src/programs.rs @@ -19,9 +19,12 @@ pub trait SP1Program { /// SP1 ICS07 Tendermint update client program. pub struct UpdateClientProgram; -/// SP1 ICS07 Tendermint verify membership program. +/// SP1 ICS07 Tendermint verify (non)membership program. pub struct MembershipProgram; +/// SP1 ICS07 Tendermint update client and verify (non)membership program. +pub struct UpdateClientAndMembershipProgram; + impl SP1Program for UpdateClientProgram { const ELF: &'static [u8] = include_bytes!("../../elf/update-client-riscv32im-succinct-zkvm-elf"); @@ -30,3 +33,8 @@ impl SP1Program for UpdateClientProgram { impl SP1Program for MembershipProgram { const ELF: &'static [u8] = include_bytes!("../../elf/membership-riscv32im-succinct-zkvm-elf"); } + +impl SP1Program for UpdateClientAndMembershipProgram { + const ELF: &'static [u8] = + include_bytes!("../../elf/uc-and-membership-riscv32im-succinct-zkvm-elf"); +} diff --git a/operator/src/prover.rs b/operator/src/prover.rs index b59916f..82de357 100644 --- a/operator/src/prover.rs +++ b/operator/src/prover.rs @@ -1,6 +1,8 @@ //! Prover for SP1 ICS07 Tendermint programs. -use crate::programs::{MembershipProgram, SP1Program, UpdateClientProgram}; +use crate::programs::{ + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, +}; use ibc_client_tendermint::types::Header; use ibc_core_commitment_types::merkle::MerkleProof; use ibc_proto::Protobuf; @@ -127,3 +129,58 @@ impl SP1ICS07TendermintProver { proof } } + +impl SP1ICS07TendermintProver { + /// Generate a proof of an update from `trusted_consensus_state` to a proposed header and + /// verify (non)membership for multiple key-value pairs on the commitment root of + /// `proposed_header`. + /// + /// # Panics + /// Panics if the inputs cannot be encoded, the proof cannot be generated or the proof is + /// invalid. + #[must_use] + pub fn generate_proof( + &self, + trusted_consensus_state: &SolConsensusState, + proposed_header: &Header, + contract_env: &Env, + kv_proofs: Vec<(String, MerkleProof, Vec)>, + ) -> SP1PlonkBn254Proof { + assert!(!kv_proofs.is_empty(), "No key-value pairs to prove"); + let len = u8::try_from(kv_proofs.len()).expect("too many key-value pairs"); + // Encode the inputs into our program. + // NOTE: We are using SolConsensusState because I'm failing to serialize the + // ConsensusState struct properly. It always seems modified when deserialized. + let encoded_1 = bincode::serialize(&trusted_consensus_state).unwrap(); + // NOTE: The Header struct is not deserializable by bincode, so we use CBOR instead. + let encoded_2 = serde_cbor::to_vec(proposed_header).unwrap(); + let encoded_3 = bincode::serialize(contract_env).unwrap(); + // TODO: find an encoding that works for all the structs above. + + // Write the encoded light blocks to stdin. + let mut stdin = SP1Stdin::new(); + stdin.write_vec(encoded_1); + stdin.write_vec(encoded_2); + stdin.write_vec(encoded_3); + stdin.write_vec(vec![len]); + for (path, proof, value) in kv_proofs { + stdin.write_slice(path.as_bytes()); + stdin.write_vec(proof.encode_vec()); + stdin.write_vec(value); + } + + // Generate the proof. Depending on SP1_PROVER env variable, this may be a mock, local or network proof. + let proof = self + .prover_client + .prove_plonk(&self.pkey, stdin) + .expect("proving failed"); + + // Verify proof. + self.prover_client + .verify_plonk(&proof, &self.vkey) + .expect("Verification failed"); + + // Return the proof. + proof + } +} diff --git a/operator/src/runners/fixtures/membership.rs b/operator/src/runners/fixtures/membership.rs index 53816e6..066c50f 100644 --- a/operator/src/runners/fixtures/membership.rs +++ b/operator/src/runners/fixtures/membership.rs @@ -3,7 +3,9 @@ use crate::{ cli::command::fixtures::MembershipCmd, helpers::light_block::LightBlockWrapper, - programs::{MembershipProgram, SP1Program, UpdateClientProgram}, + programs::{ + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + }, prover::SP1ICS07TendermintProver, rpc::TendermintRPCClient, }; @@ -34,6 +36,8 @@ struct SP1ICS07MembershipFixture { update_client_vkey: String, /// The encoded key for the [`MembershipProgram`]. membership_vkey: String, + /// The encoded key for the [`UpdateClientAndMembershipProgram`]. + uc_and_membership_vkey: String, /// The encoded public values. public_values: String, /// The encoded proof. @@ -102,6 +106,7 @@ pub async fn run(args: MembershipCmd) -> anyhow::Result<()> { commitment_root: hex::encode(&commitment_root_bytes), update_client_vkey: UpdateClientProgram::get_vkey().bytes32(), membership_vkey: verify_mem_prover.vkey.bytes32(), + uc_and_membership_vkey: UpdateClientAndMembershipProgram::get_vkey().bytes32(), public_values: proof_data.public_values.bytes(), proof: proof_data.bytes(), kv_pairs: hex::encode(output.kv_pairs.abi_encode()), diff --git a/operator/src/runners/fixtures/mod.rs b/operator/src/runners/fixtures/mod.rs index c9e2bd3..7e40869 100644 --- a/operator/src/runners/fixtures/mod.rs +++ b/operator/src/runners/fixtures/mod.rs @@ -1,4 +1,5 @@ //! Runners for generating fixtures for testing of the programs. pub mod membership; +pub mod uc_and_mem; pub mod update_client; diff --git a/operator/src/runners/fixtures/uc_and_mem.rs b/operator/src/runners/fixtures/uc_and_mem.rs new file mode 100644 index 000000000..7206d0d --- /dev/null +++ b/operator/src/runners/fixtures/uc_and_mem.rs @@ -0,0 +1,140 @@ +//! Runner for generating `update_client` fixtures + +use crate::{ + cli::command::fixtures::UpdateClientAndMembershipCmd, + helpers::light_block::LightBlockWrapper, + programs::{ + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + }, + prover::SP1ICS07TendermintProver, + rpc::TendermintRPCClient, +}; +use alloy_sol_types::SolValue; +use ibc_core_commitment_types::merkle::MerkleProof; +use serde::{Deserialize, Serialize}; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, UcAndMembershipOutput}; +use sp1_ics07_tendermint_utils::convert_tm_to_ics_merkle_proof; +use sp1_sdk::HashableKey; +use std::path::PathBuf; +use tendermint_rpc::Client; + +/// The fixture data to be used in [`UpdateClientProgram`] tests. +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +struct SP1ICS07UpdateClientAndMembershipFixture { + /// The encoded trusted client state. + trusted_client_state: String, + /// The encoded trusted consensus state. + trusted_consensus_state: String, + /// The encoded target consensus state. + target_consensus_state: String, + /// Target height. + target_height: u32, + /// The encoded key for the [`UpdateClientProgram`]. + update_client_vkey: String, + /// The encoded key for the [`MembershipProgram`]. + membership_vkey: String, + /// The encoded key for the [`UpdateClientAndMembershipProgram`]. + uc_and_membership_vkey: String, + /// The encoded public values. + public_values: String, + /// The encoded proof. + proof: String, + /// Hex-encoded `KVPair` value. + kv_pairs: String, +} + +/// Writes the proof data for the given trusted and target blocks to the given fixture path. +#[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] +pub async fn run(args: UpdateClientAndMembershipCmd) -> anyhow::Result<()> { + assert!( + args.trusted_block < args.target_block, + "The target block must be greater than the trusted block" + ); + + let tm_rpc_client = TendermintRPCClient::default(); + let uc_mem_prover = SP1ICS07TendermintProver::::default(); + + let trusted_light_block = LightBlockWrapper::new( + tm_rpc_client + .get_light_block(Some(args.trusted_block)) + .await?, + ); + let target_light_block = LightBlockWrapper::new( + tm_rpc_client + .get_light_block(Some(args.target_block)) + .await?, + ); + + let trusted_client_state = trusted_light_block.to_sol_client_state()?; + let trusted_consensus_state = trusted_light_block.to_consensus_state().into(); + let proposed_header = target_light_block.into_header(trusted_light_block.as_light_block()); + let contract_env = Env { + chain_id: trusted_light_block.chain_id()?.to_string(), + trust_threshold: trusted_client_state.trust_level.clone(), + trusting_period: trusted_client_state.trusting_period, + now: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH)? + .as_secs(), + }; + + let kv_proofs: Vec<(String, MerkleProof, Vec)> = + futures::future::try_join_all(args.key_paths.into_iter().map(|key_path| async { + let res = tm_rpc_client + .as_tm_client() + .abci_query( + Some("store/ibc/key".to_string()), + key_path.as_bytes(), + // Proof height should be the block before the target block. + Some((args.target_block - 1).into()), + true, + ) + .await?; + + assert_eq!(u32::try_from(res.height.value())? + 1, args.target_block); + assert_eq!(res.key.as_slice(), key_path.as_bytes()); + let vm_proof = convert_tm_to_ics_merkle_proof(&res.proof.unwrap())?; + let value = res.value; + if value.is_empty() { + log::info!("Verifying non-membership"); + } + assert!(!vm_proof.proofs.is_empty()); + + anyhow::Ok((key_path, vm_proof, value)) + })) + .await?; + + // Generate a header update proof for the specified blocks. + let proof_data = uc_mem_prover.generate_proof( + &trusted_consensus_state, + &proposed_header, + &contract_env, + kv_proofs, + ); + + let bytes = proof_data.public_values.as_slice(); + let output = UcAndMembershipOutput::abi_decode(bytes, false)?; + + let fixture = SP1ICS07UpdateClientAndMembershipFixture { + trusted_consensus_state: hex::encode(trusted_consensus_state.abi_encode()), + trusted_client_state: hex::encode(trusted_client_state.abi_encode()), + target_consensus_state: hex::encode( + output.update_client_output.new_consensus_state.abi_encode(), + ), + target_height: args.target_block, + update_client_vkey: UpdateClientProgram::get_vkey().bytes32(), + membership_vkey: MembershipProgram::get_vkey().bytes32(), + uc_and_membership_vkey: uc_mem_prover.vkey.bytes32(), + public_values: proof_data.public_values.bytes(), + proof: proof_data.bytes(), + kv_pairs: hex::encode(output.kv_pairs.abi_encode()), + }; + + // Save the proof data to the file path. + std::fs::write( + PathBuf::from(args.output_path), + serde_json::to_string_pretty(&fixture).unwrap(), + ) + .unwrap(); + Ok(()) +} diff --git a/operator/src/runners/fixtures/update_client.rs b/operator/src/runners/fixtures/update_client.rs index 7ac64af..5bb9e51 100644 --- a/operator/src/runners/fixtures/update_client.rs +++ b/operator/src/runners/fixtures/update_client.rs @@ -3,7 +3,9 @@ use crate::{ cli::command::fixtures::UpdateClientCmd, helpers::light_block::LightBlockWrapper, - programs::{MembershipProgram, SP1Program, UpdateClientProgram}, + programs::{ + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + }, prover::SP1ICS07TendermintProver, rpc::TendermintRPCClient, }; @@ -29,6 +31,8 @@ struct SP1ICS07UpdateClientFixture { update_client_vkey: String, /// The encoded key for the [`MembershipProgram`]. membership_vkey: String, + /// The encoded key for the [`UpdateClientAndMembershipProgram`]. + uc_and_membership_vkey: String, /// The encoded public values. public_values: String, /// The encoded proof. @@ -38,6 +42,11 @@ struct SP1ICS07UpdateClientFixture { /// Writes the proof data for the given trusted and target blocks to the given fixture path. #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] pub async fn run(args: UpdateClientCmd) -> anyhow::Result<()> { + assert!( + args.trusted_block < args.target_block, + "The target block must be greater than the trusted block" + ); + let tendermint_rpc_client = TendermintRPCClient::default(); let uc_prover = SP1ICS07TendermintProver::::default(); @@ -78,6 +87,7 @@ pub async fn run(args: UpdateClientCmd) -> anyhow::Result<()> { target_height: args.target_block, update_client_vkey: uc_prover.vkey.bytes32(), membership_vkey: MembershipProgram::get_vkey().bytes32(), + uc_and_membership_vkey: UpdateClientAndMembershipProgram::get_vkey().bytes32(), public_values: proof_data.public_values.bytes(), proof: proof_data.bytes(), }; diff --git a/operator/src/runners/genesis.rs b/operator/src/runners/genesis.rs index 39ff266..1ce186b 100644 --- a/operator/src/runners/genesis.rs +++ b/operator/src/runners/genesis.rs @@ -3,7 +3,9 @@ use crate::{ cli::command::genesis::Args, helpers::light_block::LightBlockWrapper, - programs::{MembershipProgram, SP1Program, UpdateClientProgram}, + programs::{ + MembershipProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, + }, rpc::TendermintRPCClient, }; use alloy_sol_types::SolValue; @@ -23,6 +25,8 @@ struct SP1ICS07TendermintGenesis { update_client_vkey: String, /// The encoded key for [`MembershipProgram`]. membership_vkey: String, + /// The encoded key for [`UpdateClientAndMembershipProgram`]. + uc_and_membership_vkey: String, } /// Creates the `genesis.json` file for the `SP1ICS07Tendermint` contract. @@ -56,6 +60,7 @@ pub async fn run(args: Args) -> anyhow::Result<()> { trusted_client_state: hex::encode(trusted_client_state.abi_encode()), update_client_vkey: UpdateClientProgram::get_vkey().bytes32(), membership_vkey: MembershipProgram::get_vkey().bytes32(), + uc_and_membership_vkey: UpdateClientAndMembershipProgram::get_vkey().bytes32(), }; let fixture_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(args.genesis_path); diff --git a/programs/membership/src/lib.rs b/programs/membership/src/lib.rs new file mode 100644 index 000000000..71b04ac --- /dev/null +++ b/programs/membership/src/lib.rs @@ -0,0 +1,59 @@ +//! The crate that contains the types and utilities for `sp1-ics07-tendermint-membership` program. +#![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] + +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{KVPair, MembershipOutput}; + +use ibc_core_commitment_types::{ + commitment::CommitmentRoot, + merkle::MerkleProof, + proto::{ics23::HostFunctionsManager, v1::MerklePath}, + specs::ProofSpecs, +}; + +/// The main function of the program without the zkVM wrapper. +#[allow(clippy::missing_panics_doc)] +#[must_use] +pub fn membership( + app_hash: [u8; 32], + request_iter: impl Iterator)>, +) -> MembershipOutput { + let commitment_root = CommitmentRoot::from_bytes(&app_hash); + + let kv_pairs = request_iter + .map(|(path_str, merkle_proof, value)| { + let path = MerklePath { + key_path: vec!["ibc".to_string(), path_str.clone()], + }; + + if value.is_empty() { + merkle_proof + .verify_non_membership::( + &ProofSpecs::cosmos(), + commitment_root.clone().into(), + path, + ) + .unwrap(); + } else { + merkle_proof + .verify_membership::( + &ProofSpecs::cosmos(), + commitment_root.clone().into(), + path, + value.clone(), + 0, + ) + .unwrap(); + } + + KVPair { + key: path_str, + value: value.into(), + } + }) + .collect(); + + MembershipOutput { + commitment_root: app_hash.into(), + kv_pairs, + } +} diff --git a/programs/membership/src/main.rs b/programs/membership/src/main.rs index bd7ff86..4498d60 100644 --- a/programs/membership/src/main.rs +++ b/programs/membership/src/main.rs @@ -12,14 +12,9 @@ sp1_zkvm::entrypoint!(main); use alloy_sol_types::SolValue; use ibc_proto::Protobuf; -use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{KVPair, MembershipOutput}; +use sp1_ics07_tendermint_membership::membership; -use ibc_core_commitment_types::{ - commitment::CommitmentRoot, - merkle::MerkleProof, - proto::{ics23::HostFunctionsManager, v1::MerklePath}, - specs::ProofSpecs, -}; +use ibc_core_commitment_types::merkle::MerkleProof; /// The main function of the program. /// @@ -28,57 +23,26 @@ use ibc_core_commitment_types::{ pub fn main() { let encoded_1 = sp1_zkvm::io::read_vec(); let app_hash: [u8; 32] = encoded_1.try_into().unwrap(); - let commitment_root = CommitmentRoot::from_bytes(&app_hash); // encoded_2 is the number of key-value pairs we want to verify let request_len = sp1_zkvm::io::read_vec()[0]; + assert!(request_len != 0); - let kv_pairs = (0..request_len) - .map(|_| { - let loop_encoded_1 = sp1_zkvm::io::read_vec(); - let path_str = String::from_utf8(loop_encoded_1).unwrap(); - let path = MerklePath { - key_path: vec!["ibc".to_string(), path_str.clone()], - }; + let request_iter = (0..request_len).map(|_| { + let loop_encoded_1 = sp1_zkvm::io::read_vec(); + let path_str = String::from_utf8(loop_encoded_1).unwrap(); - let loop_encoded_2 = sp1_zkvm::io::read_vec(); - let merkle_proof = MerkleProof::decode_vec(&loop_encoded_2).unwrap(); + let loop_encoded_2 = sp1_zkvm::io::read_vec(); + let merkle_proof = MerkleProof::decode_vec(&loop_encoded_2).unwrap(); - // loop_encoded_3 is the value we want to prove the membership of - // if it is empty, we are verifying non-membership - let value = sp1_zkvm::io::read_vec(); + // loop_encoded_3 is the value we want to prove the membership of + // if it is empty, we are verifying non-membership + let value = sp1_zkvm::io::read_vec(); - if value.is_empty() { - merkle_proof - .verify_non_membership::( - &ProofSpecs::cosmos(), - commitment_root.clone().into(), - path, - ) - .unwrap(); - } else { - merkle_proof - .verify_membership::( - &ProofSpecs::cosmos(), - commitment_root.clone().into(), - path, - value.clone(), - 0, - ) - .unwrap(); - } + (path_str, merkle_proof, value) + }); - KVPair { - key: path_str, - value: value.into(), - } - }) - .collect(); + let output = membership(app_hash, request_iter); - let output = MembershipOutput { - commitment_root: app_hash.into(), - kv_pairs, - } - .abi_encode(); - sp1_zkvm::io::commit_slice(&output); + sp1_zkvm::io::commit_slice(&output.abi_encode()); } diff --git a/programs/uc-and-membership/Cargo.toml b/programs/uc-and-membership/Cargo.toml new file mode 100644 index 000000000..bcc0e7a --- /dev/null +++ b/programs/uc-and-membership/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "sp1-ics07-tendermint-uc-and-membership" +description = "Update client and verify (non)membership program for sp1-ics07-tendermint" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +repository = { workspace = true } +license = { workspace = true } + +[dependencies] +sp1-zkvm = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-client-tendermint-types = { workspace = true } +alloy-sol-types = { workspace = true } +sp1-ics07-tendermint-solidity = { workspace = true } +sp1-ics07-tendermint-update-client = { workspace = true } +sp1-ics07-tendermint-membership = { workspace = true } +ibc-proto = { workspace = true } +serde_cbor = { workspace = true } +bincode = { workspace = true } diff --git a/programs/uc-and-membership/src/lib.rs b/programs/uc-and-membership/src/lib.rs new file mode 100644 index 000000000..11f50f9 --- /dev/null +++ b/programs/uc-and-membership/src/lib.rs @@ -0,0 +1,39 @@ +//! The crate that contains the types and utilities for `sp1-ics07-tendermint-membership` program. +#![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] + +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{Env, UcAndMembershipOutput}; + +use ibc_client_tendermint_types::{ConsensusState, Header}; + +use ibc_core_commitment_types::merkle::MerkleProof; + +/// The main function of the program without the zkVM wrapper. +#[allow(clippy::missing_panics_doc)] +#[must_use] +pub fn update_client_and_membership( + trusted_consensus_state: ConsensusState, + proposed_header: Header, + env: Env, + request_iter: impl Iterator)>, +) -> UcAndMembershipOutput { + let app_hash: [u8; 32] = proposed_header + .signed_header + .header() + .app_hash + .as_bytes() + .try_into() + .unwrap(); + + let uc_output = sp1_ics07_tendermint_update_client::update_client( + trusted_consensus_state, + proposed_header, + env, + ); + + let mem_output = sp1_ics07_tendermint_membership::membership(app_hash, request_iter); + + UcAndMembershipOutput { + update_client_output: uc_output, + kv_pairs: mem_output.kv_pairs, + } +} diff --git a/programs/uc-and-membership/src/main.rs b/programs/uc-and-membership/src/main.rs new file mode 100644 index 000000000..09d942b --- /dev/null +++ b/programs/uc-and-membership/src/main.rs @@ -0,0 +1,64 @@ +//! A program that verifies the membership or non-membership of a value in a commitment root. + +#![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] +#![allow(clippy::no_mangle_with_rust_abi)] +// These two lines are necessary for the program to properly compile. +// +// Under the hood, we wrap your main function with some extra code so that it behaves properly +// inside the zkVM. +#![no_main] +sp1_zkvm::entrypoint!(main); + +use alloy_sol_types::SolValue; + +use ibc_proto::Protobuf; +use sp1_ics07_tendermint_uc_and_membership::update_client_and_membership; + +use ibc_core_commitment_types::merkle::MerkleProof; + +use ibc_client_tendermint_types::Header; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ + ConsensusState as SolConsensusState, Env, +}; + +/// The main function of the program. +/// +/// # Panics +/// Panics if the verification fails. +pub fn main() { + let encoded_1 = sp1_zkvm::io::read_vec(); + let encoded_2 = sp1_zkvm::io::read_vec(); + let encoded_3 = sp1_zkvm::io::read_vec(); + // encoded_4 is the number of key-value pairs we want to verify + let request_len = sp1_zkvm::io::read_vec()[0]; + assert!(request_len != 0); + + // input 1: the trusted consensus state + let trusted_consensus_state = bincode::deserialize::(&encoded_1) + .unwrap() + .into(); + // input 2: the proposed header + let proposed_header = serde_cbor::from_slice::
(&encoded_2).unwrap(); + // input 3: environment + let env = bincode::deserialize::(&encoded_3).unwrap(); + // TODO: find an encoding that works for all the structs above. + + let request_iter = (0..request_len).map(|_| { + let loop_encoded_1 = sp1_zkvm::io::read_vec(); + let path_str = String::from_utf8(loop_encoded_1).unwrap(); + + let loop_encoded_2 = sp1_zkvm::io::read_vec(); + let merkle_proof = MerkleProof::decode_vec(&loop_encoded_2).unwrap(); + + // loop_encoded_3 is the value we want to prove the membership of + // if it is empty, we are verifying non-membership + let value = sp1_zkvm::io::read_vec(); + + (path_str, merkle_proof, value) + }); + + let output = + update_client_and_membership(trusted_consensus_state, proposed_header, env, request_iter); + + sp1_zkvm::io::commit_slice(&output.abi_encode()); +} diff --git a/programs/update-client/src/lib.rs b/programs/update-client/src/lib.rs index def9904..d235541 100644 --- a/programs/update-client/src/lib.rs +++ b/programs/update-client/src/lib.rs @@ -1,4 +1,79 @@ -//! The crate that contains the types and utilities for `sp1-ics07-tendermint-update-client-program`. +//! The crate that contains the types and utilities for `sp1-ics07-tendermint-update-client` +//! program. #![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] pub mod types; + +use std::{str::FromStr, time::Duration}; + +use ibc_client_tendermint::{ + client_state::verify_header, + types::{ConsensusState, Header, TENDERMINT_CLIENT_TYPE}, +}; +use ibc_core_host_types::identifiers::{ChainId, ClientId}; +use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{self, Env, UpdateClientOutput}; + +use tendermint_light_client_verifier::{options::Options, ProdVerifier}; + +/// The main function of the program without the zkVM wrapper. +#[allow(clippy::missing_panics_doc)] +#[must_use] +pub fn update_client( + trusted_consensus_state: ConsensusState, + proposed_header: Header, + env: Env, +) -> UpdateClientOutput { + let client_id = ClientId::new(TENDERMINT_CLIENT_TYPE, 0).unwrap(); + let chain_id = ChainId::from_str(&env.chain_id).unwrap(); + let options = Options { + trust_threshold: env.trust_threshold.clone().into(), + trusting_period: Duration::from_secs(env.trusting_period.into()), + clock_drift: Duration::default(), + }; + + let ctx = types::validation::ClientValidationCtx::new(&env, &trusted_consensus_state); + + verify_header::<_, sha2::Sha256>( + &ctx, + &proposed_header, + &client_id, + &chain_id, + &options, + &ProdVerifier::default(), + ) + .unwrap(); + + let trusted_height = sp1_ics07_tendermint::Height { + revision_number: proposed_header + .trusted_height + .revision_number() + .try_into() + .unwrap(), + revision_height: proposed_header + .trusted_height + .revision_height() + .try_into() + .unwrap(), + }; + let new_height = sp1_ics07_tendermint::Height { + revision_number: proposed_header + .height() + .revision_number() + .try_into() + .unwrap(), + revision_height: proposed_header + .height() + .revision_height() + .try_into() + .unwrap(), + }; + let new_consensus_state = ConsensusState::from(proposed_header); + + UpdateClientOutput { + trusted_consensus_state: trusted_consensus_state.into(), + new_consensus_state: new_consensus_state.into(), + env, + trusted_height, + new_height, + } +} diff --git a/programs/update-client/src/main.rs b/programs/update-client/src/main.rs index 34901c6..8f50b30 100644 --- a/programs/update-client/src/main.rs +++ b/programs/update-client/src/main.rs @@ -11,19 +11,12 @@ #![no_main] sp1_zkvm::entrypoint!(main); -use std::{str::FromStr, time::Duration}; - use alloy_sol_types::SolValue; -use ibc_client_tendermint::{ - client_state::verify_header, - types::{ConsensusState, Header, TENDERMINT_CLIENT_TYPE}, -}; -use ibc_core_host_types::identifiers::{ChainId, ClientId}; +use ibc_client_tendermint::types::Header; use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{ - self, ConsensusState as SolConsensusState, Env, UpdateClientOutput, + ConsensusState as SolConsensusState, Env, }; -use sp1_ics07_tendermint_update_client::types; -use tendermint_light_client_verifier::{options::Options, ProdVerifier}; +use sp1_ics07_tendermint_update_client::update_client; /// The main function of the program. /// @@ -44,59 +37,7 @@ pub fn main() { let env = bincode::deserialize::(&encoded_3).unwrap(); // TODO: find an encoding that works for all the structs above. - let client_id = ClientId::new(TENDERMINT_CLIENT_TYPE, 0).unwrap(); - let chain_id = ChainId::from_str(&env.chain_id).unwrap(); - let options = Options { - trust_threshold: env.trust_threshold.clone().into(), - trusting_period: Duration::from_secs(env.trusting_period.into()), - clock_drift: Duration::default(), - }; - - let ctx = types::validation::ClientValidationCtx::new(&env, &trusted_consensus_state); - - verify_header::<_, sha2::Sha256>( - &ctx, - &proposed_header, - &client_id, - &chain_id, - &options, - &ProdVerifier::default(), - ) - .unwrap(); - - let trusted_height = sp1_ics07_tendermint::Height { - revision_number: proposed_header - .trusted_height - .revision_number() - .try_into() - .unwrap(), - revision_height: proposed_header - .trusted_height - .revision_height() - .try_into() - .unwrap(), - }; - let new_height = sp1_ics07_tendermint::Height { - revision_number: proposed_header - .height() - .revision_number() - .try_into() - .unwrap(), - revision_height: proposed_header - .height() - .revision_height() - .try_into() - .unwrap(), - }; - let new_consensus_state = ConsensusState::from(proposed_header); - - let output = UpdateClientOutput { - trusted_consensus_state: trusted_consensus_state.into(), - new_consensus_state: new_consensus_state.into(), - env, - trusted_height, - new_height, - }; + let output = update_client(trusted_consensus_state, proposed_header, env); sp1_zkvm::io::commit_slice(&output.abi_encode()); }