diff --git a/Cargo.lock b/Cargo.lock index 7bec098..fa8ce82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1475,6 +1475,17 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cosmos-sdk-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d1a42d9ef55bb4e84b48ce29860f55859e52e0088ebdb1371cedd62f2b78cc" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto 0.37.0", +] + [[package]] name = "cpufeatures" version = "0.2.12" @@ -2882,7 +2893,7 @@ dependencies = [ "serde", "tendermint", "tendermint-light-client-verifier", - "tendermint-proto", + "tendermint-proto 0.36.0", ] [[package]] @@ -3083,7 +3094,7 @@ dependencies = [ "prost", "serde", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.36.0", ] [[package]] @@ -5603,6 +5614,7 @@ dependencies = [ "async-trait", "bincode", "clap", + "cosmos-sdk-proto", "dotenv", "futures", "hex", @@ -6141,7 +6153,7 @@ dependencies = [ "signature", "subtle", "subtle-encoding", - "tendermint-proto", + "tendermint-proto 0.36.0", "time", "zeroize", ] @@ -6189,6 +6201,22 @@ dependencies = [ "time", ] +[[package]] +name = "tendermint-proto" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc87024548c7f3da479885201e3da20ef29e85a3b13d04606b380ac4c7120d87" +dependencies = [ + "bytes", + "flex-error", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + [[package]] name = "tendermint-rpc" version = "0.36.0" @@ -6212,7 +6240,7 @@ dependencies = [ "subtle-encoding", "tendermint", "tendermint-config", - "tendermint-proto", + "tendermint-proto 0.36.0", "thiserror", "time", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 4983481..7bb3c82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ sp1-ics07-tendermint-utils = { path = "./packages/utils/" } tendermint = { version = "0.36.0", default-features = false } tendermint-rpc = { version = "0.36.0", features = ["http-client"] } ibc-core-client-types = { version = "0.53.0", default-features = false } +cosmos-sdk-proto = { version = "0.22.0", default-features = false } reqwest = { version = "0.11", features = ["json"] } tokio = { version = "1", features = ["full"] } diff --git a/e2e/interchaintestv8/sp1_ics07_test.go b/e2e/interchaintestv8/sp1_ics07_test.go index c5fb1a2..cbc0281 100644 --- a/e2e/interchaintestv8/sp1_ics07_test.go +++ b/e2e/interchaintestv8/sp1_ics07_test.go @@ -107,11 +107,14 @@ func (s *SP1ICS07TendermintTestSuite) TestDeploy() { clientState, err := s.contract.GetClientState(nil) s.Require().NoError(err) + stakingParams, err := simd.StakingQueryParams(ctx) + s.Require().NoError(err) + s.Require().Equal(simd.Config().ChainID, clientState.ChainId) s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator) s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator) - s.Require().Equal(uint32(1_209_600), clientState.TrustingPeriod) - s.Require().Equal(uint32(1_209_600), clientState.UnbondingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.TrustingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.UnbondingPeriod) s.Require().False(clientState.IsFrozen) s.Require().Equal(uint32(1), clientState.LatestHeight.RevisionNumber) s.Require().Greater(clientState.LatestHeight.RevisionHeight, uint32(0)) @@ -134,11 +137,14 @@ func (s *SP1ICS07TendermintTestSuite) TestUpdateClient() { clientState, err := s.contract.GetClientState(nil) s.Require().NoError(err) + stakingParams, err := simd.StakingQueryParams(ctx) + s.Require().NoError(err) + s.Require().Equal(simd.Config().ChainID, clientState.ChainId) s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Numerator), clientState.TrustLevel.Numerator) s.Require().Equal(uint8(testvalues.DefaultTrustLevel.Denominator), clientState.TrustLevel.Denominator) - s.Require().Equal(uint32(1_209_600), clientState.TrustingPeriod) - s.Require().Equal(uint32(1_209_600), clientState.UnbondingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.TrustingPeriod) + s.Require().Equal(uint32(stakingParams.UnbondingTime.Seconds()), clientState.UnbondingPeriod) s.Require().False(clientState.IsFrozen) s.Require().Equal(uint32(1), clientState.LatestHeight.RevisionNumber) s.Require().Greater(clientState.LatestHeight.RevisionHeight, s.latestHeight) diff --git a/operator/Cargo.toml b/operator/Cargo.toml index c26bf8d..c289078 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -8,21 +8,30 @@ license = { workspace = true } [dependencies] sp1-sdk = { workspace = true } -reqwest = { workspace = true } -tokio = { workspace = true } -futures = { workspace = true } -serde_json = { workspace = true } -serde = { workspace = true } + tendermint = { workspace = true } tendermint-rpc = { workspace = true } tendermint-light-client-verifier = { workspace = true } +cosmos-sdk-proto = { workspace = true } ibc-client-tendermint = { workspace = true } ibc-core-client-types = { workspace = true } ibc-core-commitment-types = { workspace = true } ibc-core-host-types = { workspace = true, features = ["std"] } +ibc-proto = { workspace = true } + +sp1-ics07-tendermint-update-client = { workspace = true } +sp1-ics07-tendermint-solidity = { workspace = true, features = ["rpc"] } +sp1-ics07-tendermint-utils = { workspace = true } + alloy-sol-types = { workspace = true } alloy-primitives = { workspace = true } alloy = { workspace = true, features = ["full", "node-bindings"] } + +reqwest = { workspace = true } +tokio = { workspace = true } +futures = { workspace = true } +serde_json = { workspace = true } +serde = { workspace = true } bincode = { workspace = true } serde_cbor = { workspace = true } sha2 = { workspace = true } @@ -33,7 +42,3 @@ clap = { workspace = true } log = { workspace = true } async-trait = { workspace = true } hex = { workspace = true } -sp1-ics07-tendermint-update-client = { workspace = true } -sp1-ics07-tendermint-solidity = { workspace = true, features = ["rpc"] } -sp1-ics07-tendermint-utils = { workspace = true } -ibc-proto = { workspace = true } diff --git a/operator/src/helpers/light_block.rs b/operator/src/helpers/light_block.rs index 31895d1..ca5a980 100644 --- a/operator/src/helpers/light_block.rs +++ b/operator/src/helpers/light_block.rs @@ -16,7 +16,11 @@ pub trait LightBlockExt { /// /// # Errors /// Returns an error if the chain identifier or height cannot be parsed. - fn to_sol_client_state(&self, trust_level: TrustThreshold) -> anyhow::Result; + fn to_sol_client_state( + &self, + trust_level: TrustThreshold, + unbonding_period: u32, + ) -> anyhow::Result; /// Convert the [`LightBlock`] to a new [`ConsensusState`]. #[must_use] fn to_consensus_state(&self) -> ConsensusState; @@ -34,9 +38,12 @@ pub trait LightBlockExt { } impl LightBlockExt for LightBlock { - fn to_sol_client_state(&self, trust_level: TrustThreshold) -> anyhow::Result { + fn to_sol_client_state( + &self, + trust_level: TrustThreshold, + unbonding_period: u32, + ) -> anyhow::Result { let chain_id = ChainId::from_str(self.signed_header.header.chain_id.as_str())?; - let two_weeks_in_seconds = 14 * 24 * 60 * 60; Ok(ClientState { chain_id: chain_id.to_string(), trust_level, @@ -45,8 +52,8 @@ impl LightBlockExt for LightBlock { revision_height: self.height().value().try_into()?, }, is_frozen: false, - trusting_period: two_weeks_in_seconds, - unbonding_period: two_weeks_in_seconds, + unbonding_period, + trusting_period: unbonding_period, }) } diff --git a/operator/src/rpc.rs b/operator/src/rpc.rs index d48e99b..d3cb927 100644 --- a/operator/src/rpc.rs +++ b/operator/src/rpc.rs @@ -5,6 +5,11 @@ use std::{collections::HashMap, env}; use anyhow::Result; +use cosmos_sdk_proto::{ + cosmos::staking::v1beta1::{Params, QueryParamsRequest, QueryParamsResponse}, + prost::Message, + traits::MessageExt, +}; use tendermint::{block::signed_header::SignedHeader, validator::Set}; use tendermint_light_client_verifier::types::{LightBlock, ValidatorSet}; use tendermint_rpc::{Client, HttpClient, Paging, Url}; @@ -25,11 +30,13 @@ pub trait TendermintRpcExt { /// # Errors /// Returns an error if the RPC request fails or if the response cannot be parsed. async fn get_light_block(&self, block_height: Option) -> Result; + /// Queries the Cosmos SDK for staking parameters. + async fn sdk_staking_params(&self) -> Result; } impl TendermintRpcExt for HttpClient { fn from_env() -> Self { - Self::new::( + Self::new( Url::from_str(&env::var("TENDERMINT_RPC_URL").expect("TENDERMINT_RPC_URL not set")) .expect("Failed to parse URL"), ) @@ -68,6 +75,20 @@ impl TendermintRpcExt for HttpClient { peer_id, )) } + + async fn sdk_staking_params(&self) -> Result { + let abci_resp = self + .abci_query( + Some("/cosmos.staking.v1beta1.Query/Params".to_string()), + QueryParamsRequest::default().to_bytes()?, + None, + false, + ) + .await?; + QueryParamsResponse::decode(abci_resp.value.as_slice())? + .params + .ok_or_else(|| anyhow::anyhow!("No staking params found")) + } } /// Sorts the signatures in the signed header based on the descending order of validators' power. diff --git a/operator/src/runners/fixtures/membership.rs b/operator/src/runners/fixtures/membership.rs index 21e5e0e..756b218 100644 --- a/operator/src/runners/fixtures/membership.rs +++ b/operator/src/runners/fixtures/membership.rs @@ -58,8 +58,16 @@ pub async fn run(args: MembershipCmd) -> anyhow::Result<()> { .get_light_block(Some(args.trusted_block)) .await?; + let unbonding_period = tm_rpc_client + .sdk_staking_params() + .await? + .unbonding_time + .ok_or_else(|| anyhow::anyhow!("No unbonding time found"))? + .seconds + .try_into()?; + let trusted_client_state = - trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?; + trusted_light_block.to_sol_client_state(args.trust_level.try_into()?, unbonding_period)?; let trusted_consensus_state = trusted_light_block.to_consensus_state(); let commitment_root_bytes = trusted_consensus_state.root.as_bytes().to_vec(); diff --git a/operator/src/runners/fixtures/uc_and_mem.rs b/operator/src/runners/fixtures/uc_and_mem.rs index 67b07aa..c61cc1a 100644 --- a/operator/src/runners/fixtures/uc_and_mem.rs +++ b/operator/src/runners/fixtures/uc_and_mem.rs @@ -62,8 +62,16 @@ pub async fn run(args: UpdateClientAndMembershipCmd) -> anyhow::Result<()> { .get_light_block(Some(args.target_block)) .await?; + let unbonding_period = tm_rpc_client + .sdk_staking_params() + .await? + .unbonding_time + .ok_or_else(|| anyhow::anyhow!("No unbonding time found"))? + .seconds + .try_into()?; + let trusted_client_state = - trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?; + trusted_light_block.to_sol_client_state(args.trust_level.try_into()?, unbonding_period)?; let trusted_consensus_state = trusted_light_block.to_consensus_state().into(); let proposed_header = target_light_block.into_header(&trusted_light_block); let contract_env = Env { diff --git a/operator/src/runners/fixtures/update_client.rs b/operator/src/runners/fixtures/update_client.rs index f3fa977..048166f 100644 --- a/operator/src/runners/fixtures/update_client.rs +++ b/operator/src/runners/fixtures/update_client.rs @@ -48,18 +48,26 @@ pub async fn run(args: UpdateClientCmd) -> anyhow::Result<()> { "The target block must be greater than the trusted block" ); - let tendermint_rpc_client = HttpClient::from_env(); + let tm_rpc_client = HttpClient::from_env(); let uc_prover = SP1ICS07TendermintProver::::default(); - let trusted_light_block = tendermint_rpc_client + let trusted_light_block = tm_rpc_client .get_light_block(Some(args.trusted_block)) .await?; - let target_light_block = tendermint_rpc_client + let target_light_block = tm_rpc_client .get_light_block(Some(args.target_block)) .await?; + let unbonding_period = tm_rpc_client + .sdk_staking_params() + .await? + .unbonding_time + .ok_or_else(|| anyhow::anyhow!("No unbonding time found"))? + .seconds + .try_into()?; + let trusted_client_state = - trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?; + trusted_light_block.to_sol_client_state(args.trust_level.try_into()?, unbonding_period)?; let trusted_consensus_state = trusted_light_block.to_consensus_state().into(); let proposed_header = target_light_block.into_header(&trusted_light_block); let contract_env = Env { diff --git a/operator/src/runners/genesis.rs b/operator/src/runners/genesis.rs index 64ccb85..549fdf1 100644 --- a/operator/src/runners/genesis.rs +++ b/operator/src/runners/genesis.rs @@ -38,11 +38,9 @@ pub async fn run(args: Args) -> anyhow::Result<()> { log::warn!("No .env file found"); } - let tendermint_rpc_client = HttpClient::from_env(); + let tm_rpc_client = HttpClient::from_env(); - let trusted_light_block = tendermint_rpc_client - .get_light_block(args.trusted_block) - .await?; + let trusted_light_block = tm_rpc_client.get_light_block(args.trusted_block).await?; if args.trusted_block.is_none() { log::info!( "Latest block height: {}", @@ -50,8 +48,16 @@ pub async fn run(args: Args) -> anyhow::Result<()> { ); } + let unbonding_period = tm_rpc_client + .sdk_staking_params() + .await? + .unbonding_time + .ok_or_else(|| anyhow::anyhow!("No unbonding time found"))? + .seconds + .try_into()?; + let trusted_client_state = - trusted_light_block.to_sol_client_state(args.trust_level.try_into()?)?; + trusted_light_block.to_sol_client_state(args.trust_level.try_into()?, unbonding_period)?; let trusted_consensus_state = trusted_light_block.to_consensus_state(); let genesis = SP1ICS07TendermintGenesis { trusted_consensus_state: hex::encode(