Skip to content
This repository has been archived by the owner on Nov 29, 2024. It is now read-only.

Commit

Permalink
feat: allow proving arbitrary paths under ibc-key
Browse files Browse the repository at this point in the history
  • Loading branch information
srdtrk committed Aug 13, 2024
1 parent 37d3608 commit a2da671
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 35 deletions.
16 changes: 8 additions & 8 deletions operator/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,18 @@ impl SP1ICS07TendermintProver<MembershipProgram> {
pub fn generate_proof(
&self,
commitment_root: &[u8],
kv_proofs: Vec<(String, MerkleProof, Vec<u8>)>,
kv_proofs: Vec<(Vec<u8>, Vec<u8>, MerkleProof)>,
) -> SP1ProofWithPublicValues {
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");

let mut stdin = SP1Stdin::new();
stdin.write_slice(commitment_root);
stdin.write_vec(vec![len]);
for (path, proof, value) in kv_proofs {
stdin.write_slice(path.as_bytes());
stdin.write_vec(proof.encode_vec());
for (path, value, proof) in kv_proofs {
stdin.write_vec(path);
stdin.write_vec(value);
stdin.write_vec(proof.encode_vec());
}

// Generate the proof. Depending on SP1_PROVER env variable, this may be a mock, local or
Expand Down Expand Up @@ -148,7 +148,7 @@ impl SP1ICS07TendermintProver<UpdateClientAndMembershipProgram> {
trusted_consensus_state: &SolConsensusState,
proposed_header: &Header,
contract_env: &Env,
kv_proofs: Vec<(String, MerkleProof, Vec<u8>)>,
kv_proofs: Vec<(Vec<u8>, Vec<u8>, MerkleProof)>,
) -> SP1ProofWithPublicValues {
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");
Expand All @@ -167,10 +167,10 @@ impl SP1ICS07TendermintProver<UpdateClientAndMembershipProgram> {
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());
for (path, value, proof) in kv_proofs {
stdin.write_vec(path);
stdin.write_vec(value);
stdin.write_vec(proof.encode_vec());
}

// Generate the proof. Depending on SP1_PROVER env variable, this may be a mock, local or network proof.
Expand Down
4 changes: 2 additions & 2 deletions operator/src/runners/fixtures/membership.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub async fn run(args: MembershipCmd) -> anyhow::Result<()> {
.as_bytes()
.to_vec();

let kv_proofs: Vec<(String, MerkleProof, Vec<u8>)> =
let kv_proofs: Vec<(Vec<u8>, Vec<u8>, MerkleProof)> =
futures::future::try_join_all(args.key_paths.into_iter().map(|key_path| async {
let res = tm_rpc_client
.abci_query(
Expand All @@ -85,7 +85,7 @@ pub async fn run(args: MembershipCmd) -> anyhow::Result<()> {
}
assert!(!vm_proof.proofs.is_empty());

anyhow::Ok((key_path, vm_proof, value))
anyhow::Ok((key_path.into(), value, vm_proof))
}))
.await?;

Expand Down
4 changes: 2 additions & 2 deletions operator/src/runners/fixtures/uc_and_mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub async fn run(args: UpdateClientAndMembershipCmd) -> anyhow::Result<()> {
.as_secs(),
};

let kv_proofs: Vec<(String, MerkleProof, Vec<u8>)> =
let kv_proofs: Vec<(Vec<u8>, Vec<u8>, MerkleProof)> =
futures::future::try_join_all(args.key_paths.into_iter().map(|key_path| async {
let res = tm_rpc_client
.abci_query(
Expand All @@ -81,7 +81,7 @@ pub async fn run(args: UpdateClientAndMembershipCmd) -> anyhow::Result<()> {
}
assert!(!vm_proof.proofs.is_empty());

anyhow::Ok((key_path, vm_proof, value))
anyhow::Ok((key_path.into(), value, vm_proof))
}))
.await?;

Expand Down
16 changes: 8 additions & 8 deletions programs/membership/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use sp1_ics07_tendermint_solidity::sp1_ics07_tendermint::{KVPair, MembershipOutp

use ibc_core_commitment_types::{
commitment::CommitmentRoot,
merkle::MerkleProof,
proto::{ics23::HostFunctionsManager, v1::MerklePath},
merkle::{MerklePath, MerkleProof},
proto::ics23::HostFunctionsManager,
specs::ProofSpecs,
};

Expand All @@ -15,38 +15,38 @@ use ibc_core_commitment_types::{
#[must_use]
pub fn membership(
app_hash: [u8; 32],
request_iter: impl Iterator<Item = (String, MerkleProof, Vec<u8>)>,
request_iter: impl Iterator<Item = (Vec<u8>, Vec<u8>, MerkleProof)>,
) -> MembershipOutput {
let commitment_root = CommitmentRoot::from_bytes(&app_hash);

let kv_pairs = request_iter
.map(|(path_str, merkle_proof, value)| {
.map(|(path_bz, value, merkle_proof)| {
let path = MerklePath {
key_path: vec!["ibc".to_string(), path_str.clone()],
key_path: vec![b"ibc".to_vec().into(), path_bz.clone().into()],
};

if value.is_empty() {
merkle_proof
.verify_non_membership::<HostFunctionsManager>(
&ProofSpecs::cosmos(),
commitment_root.clone().into(),
path.into(),
path,
)
.unwrap();
} else {
merkle_proof
.verify_membership::<HostFunctionsManager>(
&ProofSpecs::cosmos(),
commitment_root.clone().into(),
path.into(),
path,
value.clone(),
0,
)
.unwrap();
}

KVPair {
path: path_str.into(),
path: path_bz.into(),
value: value.into(),
}
})
Expand Down
15 changes: 8 additions & 7 deletions programs/membership/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ pub fn main() {
assert!(request_len != 0);

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();
// loop_encoded_1 is the path we want to verify the membership of
// usually a utf-8 string under the "ibc" store key
let path_bz = sp1_zkvm::io::read_vec();

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
// loop_encoded_2 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 loop_encoded_3 = sp1_zkvm::io::read_vec();
let merkle_proof = MerkleProof::decode_vec(&loop_encoded_3).unwrap();

(path_bz, value, merkle_proof)
});

let output = membership(app_hash, request_iter);
Expand Down
2 changes: 1 addition & 1 deletion programs/uc-and-membership/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn update_client_and_membership(
trusted_consensus_state: ConsensusState,
proposed_header: Header,
env: Env,
request_iter: impl Iterator<Item = (String, MerkleProof, Vec<u8>)>,
request_iter: impl Iterator<Item = (Vec<u8>, Vec<u8>, MerkleProof)>,
) -> UcAndMembershipOutput {
let app_hash: [u8; 32] = proposed_header
.signed_header
Expand Down
15 changes: 8 additions & 7 deletions programs/uc-and-membership/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,18 @@ pub fn main() {
// 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();
// loop_encoded_1 is the path we want to verify the membership of
// usually a utf-8 string under the "ibc" store key
let path_bz = sp1_zkvm::io::read_vec();

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
// loop_encoded_2 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 loop_encoded_3 = sp1_zkvm::io::read_vec();
let merkle_proof = MerkleProof::decode_vec(&loop_encoded_3).unwrap();

(path_bz, value, merkle_proof)
});

let output =
Expand Down

0 comments on commit a2da671

Please sign in to comment.