Skip to content

Commit

Permalink
minimal failing case
Browse files Browse the repository at this point in the history
  • Loading branch information
zbuc committed Aug 19, 2024
1 parent 7944fed commit d25da3e
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 19 deletions.
5 changes: 0 additions & 5 deletions crates/cnidarium/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,11 @@ impl Snapshot {
db: db.clone(),
};

println!("HERE_");
let (substore_value, substore_commitment_proof) = tokio::task::spawn_blocking({
let span = span.clone();
move || span.in_scope(|| substore.get_with_proof(substore_key_bytes))
})
.await??;
println!("HERE2");

proofs.push(substore_commitment_proof);

Expand All @@ -105,18 +103,15 @@ impl Snapshot {
db,
};

println!("HERE3");
let (_, main_commitment_proof) = tokio::task::spawn_blocking({
let span = span.clone();
move || span.in_scope(|| mainstore.get_with_proof(key_to_substore_root.into()))
})
.await??;
println!("HERE4");

proofs.push(main_commitment_proof);
}

println!("HERE5, substore_value: {:?}", substore_value);
Ok((
substore_value,
MerkleProof {
Expand Down
12 changes: 7 additions & 5 deletions crates/core/app/tests/common/ibc_tests/relayer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ impl MockRelayer {

// TODO: copypaste not important to fix rn
pub async fn _build_and_send_update_client_b(&mut self) -> Result<()> {
self._sync_chains().await?;
tracing::info!(
"send update client for chain {} to chain {}",
self.chain_a_ibc.chain_id,
Expand Down Expand Up @@ -465,7 +464,6 @@ impl MockRelayer {

// helper function to build UpdateClient to send to chain A
pub async fn _build_and_send_update_client_a(&mut self) -> Result<()> {
self._sync_chains().await?;
tracing::info!(
"send update client for chain {} to chain {}",
self.chain_b_ibc.chain_id,
Expand Down Expand Up @@ -706,10 +704,11 @@ impl MockRelayer {
// Make sure chain B has a client state for this height
println!("UPDATE1");
self._build_and_send_update_client_b().await?;
self._sync_chains().await?;
// self._sync_chains().await?;

// the height chain b's client for chain a should have state for
let chain_b_client_a_target_height = self.chain_a_ibc.get_latest_height().await?;
let chain_b_client_a_target_height =
self.chain_a_ibc.get_latest_height().await?.increment();

let client_state_of_b_on_a_response = self
.chain_a_ibc
Expand Down Expand Up @@ -857,6 +856,9 @@ impl MockRelayer {
"proof height: {:?}",
connection_of_b_on_a_response.proof_height
);

// d01e8818de18fb050c7aff28a59d430db07802f91c14c4370cf8be785381d4c7 is trusted (for height 6)
// but the proof comes in for ae0565596d0d8fb9019815400868ecf002b3aa48f4e0134e116f3184cfa49c4a (height 7)
println!(
"chain b latest height: {:?}",
self.chain_b_ibc.get_latest_height().await?
Expand Down Expand Up @@ -884,7 +886,7 @@ impl MockRelayer {
proof_conn_end_on_a,
proof_client_state_of_b_on_a,
proof_consensus_state_of_b_on_a,
proofs_height_on_a: client_state_of_b_on_a_response
proofs_height_on_a: connection_of_b_on_a_response
.proof_height
.expect("proof height")
.try_into()?,
Expand Down
89 changes: 82 additions & 7 deletions crates/core/app/tests/ibc_handshake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use {
ibc_proto::{
google::protobuf::Any,
ibc::core::{
client::v1::{QueryClientStateRequest, QueryConsensusStateRequest},
client::v1::{
query_client::QueryClient as IbcClientQueryClient, QueryClientStateRequest,
QueryConsensusStateRequest,
},
connection::v1::QueryConnectionRequest,
},
},
Expand All @@ -22,7 +25,9 @@ use {
connection::ConnectionEnd,
},
lightclients::tendermint::{
client_state::{AllowUpdate, ClientState as TendermintClientState},
client_state::{
AllowUpdate, ClientState as TendermintClientState, TENDERMINT_CLIENT_STATE_TYPE_URL,
},
consensus_state::ConsensusState as TendermintConsensusState,
TrustThreshold,
},
Expand Down Expand Up @@ -137,6 +142,7 @@ async fn verify_storage_proof_simple() -> anyhow::Result<()> {

let start_time = tendermint::Time::parse_from_rfc3339("2022-02-11T17:30:50.425417198Z")?;

let proxy = penumbra_mock_tendermint_proxy::TestNodeProxy::new::<Consensus>();
let mut node = {
let app_state = AppState::Content(
genesis::Content::default().with_chain_id(TestNode::<()>::CHAIN_ID.to_string()),
Expand All @@ -146,6 +152,7 @@ async fn verify_storage_proof_simple() -> anyhow::Result<()> {
TestNode::builder()
.single_validator()
.with_penumbra_auto_app_state(app_state)?
.on_block(proxy.on_block_callback())
.init_chain(consensus)
.await
.tap_ok(|e| tracing::info!(hash = %e.last_app_hash_hex(), "finished init chain"))?
Expand Down Expand Up @@ -280,7 +287,6 @@ async fn verify_storage_proof_simple() -> anyhow::Result<()> {
let grpc_url = "http://127.0.0.1:8081" // see #4517
.parse::<url::Url>()?
.tap(|url| tracing::debug!(%url, "parsed grpc url"));
let proxy = penumbra_mock_tendermint_proxy::TestNodeProxy::new::<Consensus>();
// Spawn the node's RPC server.
let _rpc_server = {
let make_svc =
Expand All @@ -305,7 +311,9 @@ async fn verify_storage_proof_simple() -> anyhow::Result<()> {
.await
.with_context(|| "could not connect to grpc server")
.tap_err(|error| tracing::error!(?error, "could not connect to grpc server"))?;
let mut cnidarium_client = CnidariumQueryServiceClient::new(channel);
let mut cnidarium_client = CnidariumQueryServiceClient::new(channel.clone());
let mut ibc_client_query_client = IbcClientQueryClient::new(channel.clone());
let mut tendermint_proxy_service_client = TendermintProxyServiceClient::new(channel.clone());
let kvr = cnidarium_client
.key_value(tonic::Request::new(KeyValueRequest {
key: String::from_utf8(key.clone()).unwrap(),
Expand All @@ -323,7 +331,74 @@ async fn verify_storage_proof_simple() -> anyhow::Result<()> {
// Same for the values.
assert_eq!(value, conn);

proof.verify_membership(&proof_specs, root.clone(), merkle_path, value, 0)?;
proof.verify_membership(
&proof_specs,
root.clone(),
merkle_path.clone(),
value.clone(),
0,
)?;

// Try fetching the client state via the IBC API
let ibc_client_state_response = ibc_client_query_client
.client_state(QueryClientStateRequest {
client_id: "07-tendermint-0".to_string(),
})
.await?
.into_inner();

let ibc_proof = MerkleProof::decode(ibc_client_state_response.clone().proof.as_slice())?;
let ibc_value = ibc_client_state_response.client_state.unwrap();

let cs = ibc_types::lightclients::tendermint::client_state::ClientState::try_from(
ibc_value.clone(),
)?;
println!("client state: {:?}", cs);
// let cs2 = ibc_types::lightclients::tendermint::client_state::ClientState::try_from(Any {
// type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(),
// value: value.clone().into(),
// })?;
let client_state = ibc_proto::google::protobuf::Any::decode(value.as_ref())?;
let cs2 = ibc_proto::ibc::lightclients::tendermint::v1::ClientState::decode(
&*client_state.value.clone(),
)?;
let cs3 =
ibc_types::lightclients::tendermint::client_state::ClientState::try_from(client_state)?;
println!("client state2: {:?}", cs2);
println!("client state3: {:?}", cs3);

// let client_state = ibc_proto::google::protobuf::Any::decode(value.as_ref())?;
// let cs1 = ibc_proto::ibc::lightclients::tendermint::v1::ClientState::decode(&*client.value)?;
// let client_state1 = TendermintClientState::try_from(cs1.clone())?;

assert_eq!(ibc_value.encode_to_vec(), value);

// We should be able to get the block from the proof_height associated with
// the proof and use the app_hash as the jmt root and succeed in proving:
let proof_block: penumbra_proto::util::tendermint_proxy::v1::GetBlockByHeightResponse =
tendermint_proxy_service_client
.get_block_by_height(GetBlockByHeightRequest {
height: ibc_client_state_response
.proof_height
.unwrap()
.revision_height
.try_into()?,
})
.await?
.into_inner();

let proof_block_root = MerkleRoot {
hash: proof_block.block.unwrap().header.unwrap().app_hash,
};
ibc_proof
.verify_membership(
&proof_specs,
proof_block_root,
merkle_path,
ibc_value.encode_to_vec(),
0,
)
.expect("the ibc proof should validate against the root of the proof_height's block");

Ok(())
.tap(|_| drop(node))
Expand Down Expand Up @@ -675,12 +750,12 @@ async fn real_cometbft_tests() -> Result<()> {
let mut tendermint_proxy_service_client = TendermintProxyServiceClient::new(channel.clone());

let b = tendermint_proxy_service_client
.get_block_by_height(GetBlockByHeightRequest { height: 1 })
.get_block_by_height(GetBlockByHeightRequest { height: 333 })
.await?
.into_inner();

println!(
"block 1 app_hash: {}, last_block_id: {:?}, height: {} last_commit_hash: {}",
"block 333 app_hash: {}, last_block_id: {:?}, height: {} last_commit_hash: {}",
hex::encode(b.clone().block.unwrap().header.unwrap().app_hash),
b.clone().block.unwrap().header.unwrap().last_block_id,
b.clone().block.unwrap().header.unwrap().height,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ impl MsgHandler for MsgConnectionOpenTry {
let trusted_consensus_state = state
.get_verified_consensus_state(&self.proofs_height_on_a, &self.client_id_on_b)
.await?;
println!(
"trusted consensus state for height {} -- root: {}",
self.proofs_height_on_a,
hex::encode(trusted_consensus_state.clone().root.hash)
);

// PROOF VERIFICATION
// 1. verify that the counterparty chain committed the expected_conn to its state
Expand Down Expand Up @@ -143,7 +148,7 @@ impl MsgHandler for MsgConnectionOpenTry {
);
println!(
"trusted_consensus_state.root.hash: {}",
hex::encode(trusted_consensus_state.root.hash.clone())
hex::encode(trusted_consensus_state.clone().root.hash.clone())
);
// assert_eq!(
// hex::encode(trusted_consensus_state.root.hash.clone()),
Expand All @@ -163,7 +168,7 @@ impl MsgHandler for MsgConnectionOpenTry {
self.proofs_height_on_a,
&self.counterparty.prefix,
&proof_conn_end_on_a,
&trusted_consensus_state.root,
&trusted_consensus_state.root.clone(),
&ConnectionPath::new(
self.counterparty
.connection_id
Expand Down

0 comments on commit d25da3e

Please sign in to comment.