From f64e2a911c5a9ad05d58a51cf193991aebc6395a Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 2 Nov 2024 15:58:46 +0800 Subject: [PATCH 1/3] imp: populated utils package --- Cargo.lock | 12 +- Cargo.toml | 1 + operator/src/runners/fixtures/membership.rs | 2 +- operator/src/runners/fixtures/uc_and_mem.rs | 2 +- packages/utils/Cargo.toml | 17 ++- packages/utils/src/eth.rs | 21 ++++ packages/utils/src/lib.rs | 27 +---- packages/utils/src/light_block.rs | 90 +++++++++++++++ packages/utils/src/merkle.rs | 22 ++++ packages/utils/src/rpc.rs | 118 ++++++++++++++++++++ packages/utils/src/union.rs | 32 ++++++ 11 files changed, 313 insertions(+), 31 deletions(-) create mode 100644 packages/utils/src/eth.rs create mode 100644 packages/utils/src/light_block.rs create mode 100644 packages/utils/src/merkle.rs create mode 100644 packages/utils/src/rpc.rs create mode 100644 packages/utils/src/union.rs diff --git a/Cargo.lock b/Cargo.lock index 234d8d3..087ac7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7120,14 +7120,22 @@ dependencies = [ name = "sp1-ics07-tendermint-utils" version = "0.1.0" dependencies = [ - "hex", + "alloy 0.5.4", + "anyhow", + "async-trait", + "cosmos-sdk-proto", "ibc-client-tendermint-types", + "ibc-core-client-types", "ibc-core-commitment-types", + "ibc-core-host-types", "prost 0.13.3", + "protos", "serde", + "sp1-ics07-tendermint-solidity", "tendermint", "tendermint-light-client-verifier", - "time", + "tendermint-rpc", + "unionlabs", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0b66a47..30ee23b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,6 +71,7 @@ union-protos = { package = "protos", git = "https://github.com/unionlabs/union", # Other dependencies reqwest = { version = "0.12", features = ["json"] } tokio = { version = "1", features = ["full"] } +async-trait = "0.1" time = { version = "0.3", default-features = false, features = ["macros", "parsing"] } alloy-primitives = "0.8" alloy-contract = "0.5" diff --git a/operator/src/runners/fixtures/membership.rs b/operator/src/runners/fixtures/membership.rs index 9b1093f..18ed00b 100644 --- a/operator/src/runners/fixtures/membership.rs +++ b/operator/src/runners/fixtures/membership.rs @@ -19,7 +19,7 @@ use sp1_ics07_tendermint_solidity::{ }, ISP1Msgs::SP1Proof, }; -use sp1_ics07_tendermint_utils::convert_tm_to_ics_merkle_proof; +use sp1_ics07_tendermint_utils::merkle::convert_tm_to_ics_merkle_proof; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::{Client, HttpClient}; diff --git a/operator/src/runners/fixtures/uc_and_mem.rs b/operator/src/runners/fixtures/uc_and_mem.rs index cb48f0e..358007e 100644 --- a/operator/src/runners/fixtures/uc_and_mem.rs +++ b/operator/src/runners/fixtures/uc_and_mem.rs @@ -21,7 +21,7 @@ use sp1_ics07_tendermint_solidity::{ ISP1Msgs::SP1Proof, IUpdateClientAndMembershipMsgs::UcAndMembershipOutput, }; -use sp1_ics07_tendermint_utils::convert_tm_to_ics_merkle_proof; +use sp1_ics07_tendermint_utils::merkle::convert_tm_to_ics_merkle_proof; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::{Client, HttpClient}; diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 3456925..92eb0aa 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -7,13 +7,20 @@ repository = { workspace = true } license = { workspace = true } [dependencies] -tendermint-light-client-verifier = { workspace = true } +anyhow = { workspace = true } +async-trait = { workspace = true } serde = { workspace = true } +prost = { workspace = true } +cosmos-sdk-proto = { workspace = true } +tendermint-rpc = { workspace = true } +sp1-ics07-tendermint-solidity = { workspace = true } +tendermint-light-client-verifier = { workspace = true } ibc-client-tendermint-types = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-host-types = { workspace = true } tendermint = { workspace = true } ibc-core-commitment-types = { workspace = true } -time = { workspace = true } -prost = { workspace = true } +alloy = { workspace = true } -[dev-dependencies] -hex = { workspace = true } +union-protos = { workspace = true } +unionlabs = { workspace = true } diff --git a/packages/utils/src/eth.rs b/packages/utils/src/eth.rs new file mode 100644 index 000000000..1027ccc --- /dev/null +++ b/packages/utils/src/eth.rs @@ -0,0 +1,21 @@ +//! Helpers for interacting with EVM. + +use std::env; + +use alloy::{network::EthereumWallet, signers::local::PrivateKeySigner}; + +/// Create an Ethereum wallet from the `PRIVATE_KEY` environment variable. +/// +/// # Panics +/// Panics if the `PRIVATE_KEY` environment variable is not set. +/// Panics if the `PRIVATE_KEY` environment variable is not a valid private key. +#[must_use] +pub fn wallet_from_env() -> EthereumWallet { + let mut private_key = env::var("PRIVATE_KEY").expect("PRIVATE_KEY not set"); + if let Some(stripped) = private_key.strip_prefix("0x") { + private_key = stripped.to_string(); + } + + let signer: PrivateKeySigner = private_key.parse().unwrap(); + EthereumWallet::from(signer) +} diff --git a/packages/utils/src/lib.rs b/packages/utils/src/lib.rs index 32be559..710c17b 100644 --- a/packages/utils/src/lib.rs +++ b/packages/utils/src/lib.rs @@ -1,25 +1,8 @@ #![doc = include_str!("../README.md")] #![deny(clippy::nursery, clippy::pedantic, warnings, missing_docs)] -use ibc_core_commitment_types::{merkle::MerkleProof, proto::ics23::CommitmentProof}; -use tendermint::merkle::proof::ProofOps; - -/// Convert a Tendermint proof to an ICS Merkle proof. -/// -/// # Errors -/// Returns a decoding error if the prost merge. -pub fn convert_tm_to_ics_merkle_proof( - tm_proof: &ProofOps, -) -> Result { - let mut proofs = Vec::with_capacity(tm_proof.ops.len()); - - for op in &tm_proof.ops { - let mut parsed = CommitmentProof { proof: None }; - - prost::Message::merge(&mut parsed, op.data.as_slice())?; - - proofs.push(parsed); - } - - Ok(MerkleProof { proofs }) -} +pub mod eth; +pub mod light_block; +pub mod merkle; +pub mod rpc; +pub mod union; diff --git a/packages/utils/src/light_block.rs b/packages/utils/src/light_block.rs new file mode 100644 index 000000000..56ddb18 --- /dev/null +++ b/packages/utils/src/light_block.rs @@ -0,0 +1,90 @@ +//! Provides helpers for deriving other types from `LightBlock`. + +use ibc_client_tendermint_types::{ConsensusState, Header}; +use ibc_core_client_types::Height as IbcHeight; +use ibc_core_commitment_types::commitment::CommitmentRoot; +use ibc_core_host_types::{error::IdentifierError, identifiers::ChainId}; +use sp1_ics07_tendermint_solidity::{ + IICS02ClientMsgs::Height, + IICS07TendermintMsgs::{ClientState, TrustThreshold}, +}; +use std::str::FromStr; +use tendermint_light_client_verifier::types::LightBlock; + +/// Extension trait for [`LightBlock`] that provides additional methods for converting to other +/// types. +#[allow(clippy::module_name_repetitions)] +pub trait LightBlockExt { + /// Convert the [`LightBlock`] to a new solidity [`ClientState`]. + /// + /// # Errors + /// Returns an error if the chain identifier or height cannot be parsed. + fn to_sol_client_state( + &self, + trust_level: TrustThreshold, + unbonding_period: u32, + trusting_period: u32, + ) -> anyhow::Result; + /// Convert the [`LightBlock`] to a new [`ConsensusState`]. + #[must_use] + fn to_consensus_state(&self) -> ConsensusState; + /// Convert the [`LightBlock`] to a new [`Header`]. + /// + /// # Panics + /// Panics if the `trusted_height` is zero. + #[must_use] + fn into_header(self, trusted_light_block: &LightBlock) -> Header; + /// Get the chain identifier from the [`LightBlock`]. + /// + /// # Errors + /// Returns an error if the chain identifier cannot be parsed. + fn chain_id(&self) -> Result; +} + +impl LightBlockExt for LightBlock { + fn to_sol_client_state( + &self, + trust_level: TrustThreshold, + unbonding_period: u32, + trusting_period: u32, + ) -> anyhow::Result { + let chain_id = ChainId::from_str(self.signed_header.header.chain_id.as_str())?; + Ok(ClientState { + chainId: chain_id.to_string(), + trustLevel: trust_level, + latestHeight: Height { + revisionNumber: chain_id.revision_number().try_into()?, + revisionHeight: self.height().value().try_into()?, + }, + isFrozen: false, + unbondingPeriod: unbonding_period, + trustingPeriod: trusting_period, + }) + } + + fn to_consensus_state(&self) -> ConsensusState { + ConsensusState { + timestamp: self.signed_header.header.time, + root: CommitmentRoot::from_bytes(self.signed_header.header.app_hash.as_bytes()), + next_validators_hash: self.signed_header.header.next_validators_hash, + } + } + + fn into_header(self, trusted_light_block: &LightBlock) -> Header { + let trusted_revision_number = + ChainId::from_str(trusted_light_block.signed_header.header.chain_id.as_str()) + .unwrap() + .revision_number(); + let trusted_block_height = trusted_light_block.height().value(); + Header { + signed_header: self.signed_header, + validator_set: self.validators, + trusted_height: IbcHeight::new(trusted_revision_number, trusted_block_height).unwrap(), + trusted_next_validator_set: trusted_light_block.next_validators.clone(), + } + } + + fn chain_id(&self) -> Result { + ChainId::from_str(self.signed_header.header.chain_id.as_str()) + } +} diff --git a/packages/utils/src/merkle.rs b/packages/utils/src/merkle.rs new file mode 100644 index 000000000..37976df --- /dev/null +++ b/packages/utils/src/merkle.rs @@ -0,0 +1,22 @@ +//! This module defines the conversion functions between Tendermint and ICS Merkle proofs. + +use ibc_core_commitment_types::{merkle::MerkleProof, proto::ics23::CommitmentProof}; +use tendermint::merkle::proof::ProofOps; + +/// Convert a Tendermint proof to an ICS Merkle proof. +/// +/// # Errors +/// Returns a decoding error if the prost merge. +pub fn convert_tm_to_ics_merkle_proof( + tm_proof: &ProofOps, +) -> Result { + let mut proofs = Vec::with_capacity(tm_proof.ops.len()); + + for op in &tm_proof.ops { + let mut parsed = CommitmentProof { proof: None }; + prost::Message::merge(&mut parsed, op.data.as_slice())?; + proofs.push(parsed); + } + + Ok(MerkleProof { proofs }) +} diff --git a/packages/utils/src/rpc.rs b/packages/utils/src/rpc.rs new file mode 100644 index 000000000..f690818 --- /dev/null +++ b/packages/utils/src/rpc.rs @@ -0,0 +1,118 @@ +//! RPC client for interacting with a Tendermint node. + +use core::str::FromStr; +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}; + +/// An extension trait for [`HttpClient`] that provides additional methods for +/// obtaining light blocks. +#[async_trait::async_trait] +pub trait TendermintRpcExt { + /// Creates a new instance of the Tendermint RPC client from the environment variables. + /// + /// # Panics + /// Panics if the `TENDERMINT_RPC_URL` environment variable is not set or if the URL is + /// invalid. + #[must_use] + fn from_env() -> Self; + /// Gets a light block for a specific block height. + /// If `block_height` is `None`, the latest block is fetched. + /// + /// # 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; +} + +#[async_trait::async_trait] +impl TendermintRpcExt for HttpClient { + fn from_env() -> Self { + Self::new( + Url::from_str(&env::var("TENDERMINT_RPC_URL").expect("TENDERMINT_RPC_URL not set")) + .expect("Failed to parse URL"), + ) + .expect("Failed to create HTTP client") + } + + async fn get_light_block(&self, block_height: Option) -> Result { + let peer_id = self.status().await?.node_info.id; + let commit_response; + let height; + if let Some(block_height) = block_height { + commit_response = self.commit(block_height).await?; + height = block_height; + } else { + commit_response = self.latest_commit().await?; + height = commit_response + .signed_header + .header + .height + .value() + .try_into()?; + } + let mut signed_header = commit_response.signed_header; + + let validator_response = self.validators(height, Paging::All).await?; + let validators = Set::new(validator_response.validators, None); + + let next_validator_response = self.validators(height + 1, Paging::All).await?; + let next_validators = Set::new(next_validator_response.validators, None); + + sort_signatures_by_validators_power_desc(&mut signed_header, &validators); + Ok(LightBlock::new( + signed_header, + validators, + next_validators, + 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. +fn sort_signatures_by_validators_power_desc( + signed_header: &mut SignedHeader, + validators_set: &ValidatorSet, +) { + let validator_powers: HashMap<_, _> = validators_set + .validators() + .iter() + .map(|v| (v.address, v.power())) + .collect(); + + signed_header.commit.signatures.sort_by(|a, b| { + let power_a = a + .validator_address() + .and_then(|addr| validator_powers.get(&addr)) + .unwrap_or(&0); + let power_b = b + .validator_address() + .and_then(|addr| validator_powers.get(&addr)) + .unwrap_or(&0); + power_b.cmp(power_a) + }); +} diff --git a/packages/utils/src/union.rs b/packages/utils/src/union.rs new file mode 100644 index 000000000..a0a24d5 --- /dev/null +++ b/packages/utils/src/union.rs @@ -0,0 +1,32 @@ +//! Helpers for interacting with union's ics23 library. + +use tendermint::merkle::proof::ProofOps; +use union_protos::{ + cosmos::ics23::v1::CommitmentProof as ProtoCommitmentProof, + ibc::core::commitment::v1::MerkleProof as ProtoMerkleProof, +}; +use unionlabs::{ + cosmos::ics23::commitment_proof::CommitmentProof, + encoding::{DecodeAs, Proto}, + union::ics23::merkle_proof::MerkleProof, +}; + +/// Converts the rpc proof ops to a union proof. +/// +/// # Errors +/// Fails if the proof ops cannot be converted to a union proof. +pub fn convert_to_union_proof(proof_ops: ProofOps) -> anyhow::Result { + let commitment_proofs = proof_ops + .ops + .into_iter() + .map(|op| { + Ok(ProtoCommitmentProof::from(CommitmentProof::decode_as::< + Proto, + >(&op.data)?)) + }) + .collect::>()?; + + Ok(MerkleProof::try_from(ProtoMerkleProof { + proofs: commitment_proofs, + })?) +} From 7374577c5f69a8775525df281b8327349914c677 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 2 Nov 2024 16:15:05 +0800 Subject: [PATCH 2/3] imp: migrated code to utils package --- Cargo.lock | 131 +----------------- operator/Cargo.toml | 6 +- operator/src/helpers/eth.rs | 21 --- operator/src/helpers/light_block.rs | 90 ------------ operator/src/helpers/mod.rs | 5 - operator/src/helpers/union.rs | 32 ----- operator/src/lib.rs | 2 - operator/src/rpc.rs | 116 ---------------- operator/src/runners/fixtures/membership.rs | 8 +- operator/src/runners/fixtures/misbehaviour.rs | 5 +- operator/src/runners/fixtures/uc_and_mem.rs | 5 +- .../src/runners/fixtures/update_client.rs | 3 +- operator/src/runners/genesis.rs | 7 +- operator/src/runners/operator.rs | 9 +- packages/utils/Cargo.toml | 2 +- 15 files changed, 17 insertions(+), 425 deletions(-) delete mode 100644 operator/src/helpers/eth.rs delete mode 100644 operator/src/helpers/light_block.rs delete mode 100644 operator/src/helpers/mod.rs delete mode 100644 operator/src/helpers/union.rs delete mode 100644 operator/src/rpc.rs diff --git a/Cargo.lock b/Cargo.lock index 087ac7d..e4091c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3676,20 +3676,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ibc-app-transfer-types" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "631d60b8c1dbd74ba2609d5a7787ff73925fb4c444fe29ef62dbc7fa9b1bde94" -dependencies = [ - "derive_more 0.99.18", - "displaydoc", - "ibc-core", - "ibc-proto", - "primitive-types 0.12.2", - "uint 0.9.5", -] - [[package]] name = "ibc-client-tendermint" version = "0.54.0" @@ -3726,39 +3712,6 @@ dependencies = [ "tendermint-proto", ] -[[package]] -name = "ibc-core" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cddf3c01d56ca1ee49b9ffd8c5e8e6f8c650711fb93c88dcabae4b726f07a43" -dependencies = [ - "ibc-core-channel", - "ibc-core-client", - "ibc-core-commitment-types", - "ibc-core-connection", - "ibc-core-handler", - "ibc-core-host", - "ibc-core-router", - "ibc-derive", - "ibc-primitives", -] - -[[package]] -name = "ibc-core-channel" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93dd27559decbcc30ea4a7d37870a2d819e0c701ce789d4a99419a289eacc6d" -dependencies = [ - "ibc-core-channel-types", - "ibc-core-client", - "ibc-core-commitment-types", - "ibc-core-connection", - "ibc-core-handler-types", - "ibc-core-host", - "ibc-core-router", - "ibc-primitives", -] - [[package]] name = "ibc-core-channel-types" version = "0.54.0" @@ -3843,19 +3796,6 @@ dependencies = [ "subtle-encoding", ] -[[package]] -name = "ibc-core-connection" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26abf3cc801896860728d1780c9895994f6ff5ab7bb2af3e5686963c0901654e" -dependencies = [ - "ibc-core-client", - "ibc-core-connection-types", - "ibc-core-handler-types", - "ibc-core-host", - "ibc-primitives", -] - [[package]] name = "ibc-core-connection-types" version = "0.54.0" @@ -3874,22 +3814,6 @@ dependencies = [ "tendermint", ] -[[package]] -name = "ibc-core-handler" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658069f1a43790c6dc1288a980a30e1a1667bf0af53fb3f836d56b7ab7ec728c" -dependencies = [ - "ibc-core-channel", - "ibc-core-client", - "ibc-core-commitment-types", - "ibc-core-connection", - "ibc-core-handler-types", - "ibc-core-host", - "ibc-core-router", - "ibc-primitives", -] - [[package]] name = "ibc-core-handler-types" version = "0.54.0" @@ -3930,29 +3854,6 @@ dependencies = [ "subtle-encoding", ] -[[package]] -name = "ibc-core-host-cosmos" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34b203c12236140e627270c4d7d469ab2e776a94c22da9051b020303bc6b21f" -dependencies = [ - "derive_more 0.99.18", - "displaydoc", - "ibc-app-transfer-types", - "ibc-client-tendermint", - "ibc-core-client-context", - "ibc-core-client-types", - "ibc-core-commitment-types", - "ibc-core-connection-types", - "ibc-core-handler-types", - "ibc-core-host-types", - "ibc-primitives", - "ibc-proto", - "sha2 0.10.8", - "subtle-encoding", - "tendermint", -] - [[package]] name = "ibc-core-host-types" version = "0.54.0" @@ -3965,21 +3866,6 @@ dependencies = [ "serde", ] -[[package]] -name = "ibc-core-router" -version = "0.54.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195c93f19d8c9c6e36e518656ca381cd4f86131515ad4e99f7e6d2a1836b7b7e" -dependencies = [ - "derive_more 0.99.18", - "displaydoc", - "ibc-core-channel-types", - "ibc-core-host-types", - "ibc-core-router-types", - "ibc-primitives", - "subtle-encoding", -] - [[package]] name = "ibc-core-router-types" version = "0.54.0" @@ -3996,17 +3882,6 @@ dependencies = [ "tendermint", ] -[[package]] -name = "ibc-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0eb1d08a424a2d714652aca4c2738a016c90f4eb78f6f64913f9fe2c77fe34" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.86", -] - [[package]] name = "ibc-primitives" version = "0.54.0" @@ -7025,11 +6900,9 @@ dependencies = [ "dotenv", "futures", "hex", - "ibc-client-tendermint", + "ibc-client-tendermint-types", "ibc-core-client-types", "ibc-core-commitment-types", - "ibc-core-host-cosmos", - "ibc-core-host-types", "ibc-proto", "log", "protos", @@ -7037,10 +6910,8 @@ dependencies = [ "serde", "serde_json", "serde_with", - "sha2 0.10.8", "sp1-ics07-tendermint-prover", "sp1-ics07-tendermint-solidity", - "sp1-ics07-tendermint-update-client", "sp1-ics07-tendermint-utils", "sp1-sdk", "subtle-encoding", diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 0ac1f47..538d7db 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -17,13 +17,10 @@ tendermint = { workspace = true } tendermint-rpc = { workspace = true } tendermint-light-client-verifier = { workspace = true } -ibc-client-tendermint = { workspace = true } +ibc-client-tendermint-types = { workspace = true } ibc-core-client-types = { workspace = true } ibc-core-commitment-types = { workspace = true } -ibc-core-host-types = { workspace = true, features = ["std"] } -ibc-core-host-cosmos = { workspace = true } -sp1-ics07-tendermint-update-client = { workspace = true } sp1-ics07-tendermint-solidity = { workspace = true, features = ["rpc"] } sp1-ics07-tendermint-utils = { workspace = true } sp1-ics07-tendermint-prover = { workspace = true } @@ -41,7 +38,6 @@ futures = { workspace = true } serde_json = { workspace = true } serde = { workspace = true } serde_with = { workspace = true } -sha2 = { workspace = true } dotenv = { workspace = true } subtle-encoding = { workspace = true } anyhow = { workspace = true } diff --git a/operator/src/helpers/eth.rs b/operator/src/helpers/eth.rs deleted file mode 100644 index 1027ccc..000000000 --- a/operator/src/helpers/eth.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Helpers for interacting with EVM. - -use std::env; - -use alloy::{network::EthereumWallet, signers::local::PrivateKeySigner}; - -/// Create an Ethereum wallet from the `PRIVATE_KEY` environment variable. -/// -/// # Panics -/// Panics if the `PRIVATE_KEY` environment variable is not set. -/// Panics if the `PRIVATE_KEY` environment variable is not a valid private key. -#[must_use] -pub fn wallet_from_env() -> EthereumWallet { - let mut private_key = env::var("PRIVATE_KEY").expect("PRIVATE_KEY not set"); - if let Some(stripped) = private_key.strip_prefix("0x") { - private_key = stripped.to_string(); - } - - let signer: PrivateKeySigner = private_key.parse().unwrap(); - EthereumWallet::from(signer) -} diff --git a/operator/src/helpers/light_block.rs b/operator/src/helpers/light_block.rs deleted file mode 100644 index 8b627bd..000000000 --- a/operator/src/helpers/light_block.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! Provides helpers for deriving other types from `LightBlock`. - -use ibc_client_tendermint::types::{ConsensusState, Header}; -use ibc_core_client_types::Height as IbcHeight; -use ibc_core_commitment_types::commitment::CommitmentRoot; -use ibc_core_host_types::{error::IdentifierError, identifiers::ChainId}; -use sp1_ics07_tendermint_solidity::{ - IICS02ClientMsgs::Height, - IICS07TendermintMsgs::{ClientState, TrustThreshold}, -}; -use std::str::FromStr; -use tendermint_light_client_verifier::types::LightBlock; - -/// Extension trait for [`LightBlock`] that provides additional methods for converting to other -/// types. -#[allow(clippy::module_name_repetitions)] -pub trait LightBlockExt { - /// Convert the [`LightBlock`] to a new solidity [`ClientState`]. - /// - /// # Errors - /// Returns an error if the chain identifier or height cannot be parsed. - fn to_sol_client_state( - &self, - trust_level: TrustThreshold, - unbonding_period: u32, - trusting_period: u32, - ) -> anyhow::Result; - /// Convert the [`LightBlock`] to a new [`ConsensusState`]. - #[must_use] - fn to_consensus_state(&self) -> ConsensusState; - /// Convert the [`LightBlock`] to a new [`Header`]. - /// - /// # Panics - /// Panics if the `trusted_height` is zero. - #[must_use] - fn into_header(self, trusted_light_block: &LightBlock) -> Header; - /// Get the chain identifier from the [`LightBlock`]. - /// - /// # Errors - /// Returns an error if the chain identifier cannot be parsed. - fn chain_id(&self) -> Result; -} - -impl LightBlockExt for LightBlock { - fn to_sol_client_state( - &self, - trust_level: TrustThreshold, - unbonding_period: u32, - trusting_period: u32, - ) -> anyhow::Result { - let chain_id = ChainId::from_str(self.signed_header.header.chain_id.as_str())?; - Ok(ClientState { - chainId: chain_id.to_string(), - trustLevel: trust_level, - latestHeight: Height { - revisionNumber: chain_id.revision_number().try_into()?, - revisionHeight: self.height().value().try_into()?, - }, - isFrozen: false, - unbondingPeriod: unbonding_period, - trustingPeriod: trusting_period, - }) - } - - fn to_consensus_state(&self) -> ConsensusState { - ConsensusState { - timestamp: self.signed_header.header.time, - root: CommitmentRoot::from_bytes(self.signed_header.header.app_hash.as_bytes()), - next_validators_hash: self.signed_header.header.next_validators_hash, - } - } - - fn into_header(self, trusted_light_block: &LightBlock) -> Header { - let trusted_revision_number = - ChainId::from_str(trusted_light_block.signed_header.header.chain_id.as_str()) - .unwrap() - .revision_number(); - let trusted_block_height = trusted_light_block.height().value(); - Header { - signed_header: self.signed_header, - validator_set: self.validators, - trusted_height: IbcHeight::new(trusted_revision_number, trusted_block_height).unwrap(), - trusted_next_validator_set: trusted_light_block.next_validators.clone(), - } - } - - fn chain_id(&self) -> Result { - ChainId::from_str(self.signed_header.header.chain_id.as_str()) - } -} diff --git a/operator/src/helpers/mod.rs b/operator/src/helpers/mod.rs deleted file mode 100644 index 9866b2d..000000000 --- a/operator/src/helpers/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! Provides helpers for `sp1-ics07-tendermint-operator`. - -pub mod eth; -pub mod light_block; -pub mod union; diff --git a/operator/src/helpers/union.rs b/operator/src/helpers/union.rs deleted file mode 100644 index a0a24d5..000000000 --- a/operator/src/helpers/union.rs +++ /dev/null @@ -1,32 +0,0 @@ -//! Helpers for interacting with union's ics23 library. - -use tendermint::merkle::proof::ProofOps; -use union_protos::{ - cosmos::ics23::v1::CommitmentProof as ProtoCommitmentProof, - ibc::core::commitment::v1::MerkleProof as ProtoMerkleProof, -}; -use unionlabs::{ - cosmos::ics23::commitment_proof::CommitmentProof, - encoding::{DecodeAs, Proto}, - union::ics23::merkle_proof::MerkleProof, -}; - -/// Converts the rpc proof ops to a union proof. -/// -/// # Errors -/// Fails if the proof ops cannot be converted to a union proof. -pub fn convert_to_union_proof(proof_ops: ProofOps) -> anyhow::Result { - let commitment_proofs = proof_ops - .ops - .into_iter() - .map(|op| { - Ok(ProtoCommitmentProof::from(CommitmentProof::decode_as::< - Proto, - >(&op.data)?)) - }) - .collect::>()?; - - Ok(MerkleProof::try_from(ProtoMerkleProof { - proofs: commitment_proofs, - })?) -} diff --git a/operator/src/lib.rs b/operator/src/lib.rs index 781481c..ffa7b0e 100644 --- a/operator/src/lib.rs +++ b/operator/src/lib.rs @@ -2,6 +2,4 @@ #![deny(missing_docs, clippy::nursery, clippy::pedantic, warnings)] pub mod cli; -pub mod helpers; -pub(crate) mod rpc; pub mod runners; diff --git a/operator/src/rpc.rs b/operator/src/rpc.rs deleted file mode 100644 index d3cb927..000000000 --- a/operator/src/rpc.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! RPC client for interacting with a Tendermint node. - -use core::str::FromStr; -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}; - -/// An extension trait for [`HttpClient`] that provides additional methods for -/// obtaining light blocks. -pub trait TendermintRpcExt { - /// Creates a new instance of the Tendermint RPC client from the environment variables. - /// - /// # Panics - /// Panics if the `TENDERMINT_RPC_URL` environment variable is not set or if the URL is - /// invalid. - #[must_use] - fn from_env() -> Self; - /// Gets a light block for a specific block height. - /// If `block_height` is `None`, the latest block is fetched. - /// - /// # 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( - Url::from_str(&env::var("TENDERMINT_RPC_URL").expect("TENDERMINT_RPC_URL not set")) - .expect("Failed to parse URL"), - ) - .expect("Failed to create HTTP client") - } - - async fn get_light_block(&self, block_height: Option) -> Result { - let peer_id = self.status().await?.node_info.id; - let commit_response; - let height; - if let Some(block_height) = block_height { - commit_response = self.commit(block_height).await?; - height = block_height; - } else { - commit_response = self.latest_commit().await?; - height = commit_response - .signed_header - .header - .height - .value() - .try_into()?; - } - let mut signed_header = commit_response.signed_header; - - let validator_response = self.validators(height, Paging::All).await?; - let validators = Set::new(validator_response.validators, None); - - let next_validator_response = self.validators(height + 1, Paging::All).await?; - let next_validators = Set::new(next_validator_response.validators, None); - - sort_signatures_by_validators_power_desc(&mut signed_header, &validators); - Ok(LightBlock::new( - signed_header, - validators, - next_validators, - 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. -fn sort_signatures_by_validators_power_desc( - signed_header: &mut SignedHeader, - validators_set: &ValidatorSet, -) { - let validator_powers: HashMap<_, _> = validators_set - .validators() - .iter() - .map(|v| (v.address, v.power())) - .collect(); - - signed_header.commit.signatures.sort_by(|a, b| { - let power_a = a - .validator_address() - .and_then(|addr| validator_powers.get(&addr)) - .unwrap_or(&0); - let power_b = b - .validator_address() - .and_then(|addr| validator_powers.get(&addr)) - .unwrap_or(&0); - power_b.cmp(power_a) - }); -} diff --git a/operator/src/runners/fixtures/membership.rs b/operator/src/runners/fixtures/membership.rs index 18ed00b..ac94772 100644 --- a/operator/src/runners/fixtures/membership.rs +++ b/operator/src/runners/fixtures/membership.rs @@ -2,13 +2,11 @@ use crate::{ cli::command::{fixtures::MembershipCmd, OutputPath}, - helpers::union::convert_to_union_proof, - rpc::TendermintRpcExt, runners::genesis::SP1ICS07TendermintGenesis, }; use alloy_sol_types::SolValue; use core::str; -use ibc_client_tendermint::types::ConsensusState; +use ibc_client_tendermint_types::ConsensusState; use ibc_core_commitment_types::merkle::MerkleProof; use serde::{Deserialize, Serialize}; use sp1_ics07_tendermint_prover::{programs::MembershipProgram, prover::SP1ICS07TendermintProver}; @@ -19,7 +17,9 @@ use sp1_ics07_tendermint_solidity::{ }, ISP1Msgs::SP1Proof, }; -use sp1_ics07_tendermint_utils::merkle::convert_tm_to_ics_merkle_proof; +use sp1_ics07_tendermint_utils::{ + merkle::convert_tm_to_ics_merkle_proof, rpc::TendermintRpcExt, union::convert_to_union_proof, +}; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::{Client, HttpClient}; diff --git a/operator/src/runners/fixtures/misbehaviour.rs b/operator/src/runners/fixtures/misbehaviour.rs index 338185e..158d05d 100644 --- a/operator/src/runners/fixtures/misbehaviour.rs +++ b/operator/src/runners/fixtures/misbehaviour.rs @@ -2,12 +2,10 @@ use crate::{ cli::command::{fixtures::MisbehaviourCmd, OutputPath}, - helpers::light_block::LightBlockExt, - rpc::TendermintRpcExt, runners::genesis::SP1ICS07TendermintGenesis, }; use alloy_sol_types::SolValue; -use ibc_client_tendermint::types::Misbehaviour; +use ibc_client_tendermint_types::Misbehaviour; use ibc_proto::ibc::lightclients::tendermint::v1::Misbehaviour as RawMisbehaviour; use serde::{Deserialize, Serialize}; use sp1_ics07_tendermint_prover::{ @@ -18,6 +16,7 @@ use sp1_ics07_tendermint_solidity::{ IMisbehaviourMsgs::MsgSubmitMisbehaviour, ISP1Msgs::SP1Proof, }; +use sp1_ics07_tendermint_utils::{light_block::LightBlockExt, rpc::TendermintRpcExt}; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::HttpClient; diff --git a/operator/src/runners/fixtures/uc_and_mem.rs b/operator/src/runners/fixtures/uc_and_mem.rs index 358007e..4c29b35 100644 --- a/operator/src/runners/fixtures/uc_and_mem.rs +++ b/operator/src/runners/fixtures/uc_and_mem.rs @@ -2,15 +2,13 @@ use crate::{ cli::command::{fixtures::UpdateClientAndMembershipCmd, OutputPath}, - helpers::light_block::LightBlockExt, - rpc::TendermintRpcExt, runners::{ fixtures::membership::SP1ICS07MembershipFixture, genesis::SP1ICS07TendermintGenesis, }, }; use alloy_sol_types::SolValue; use core::str; -use ibc_client_tendermint::types::ConsensusState; +use ibc_client_tendermint_types::ConsensusState; use ibc_core_commitment_types::merkle::MerkleProof; use sp1_ics07_tendermint_prover::{ programs::UpdateClientAndMembershipProgram, prover::SP1ICS07TendermintProver, @@ -22,6 +20,7 @@ use sp1_ics07_tendermint_solidity::{ IUpdateClientAndMembershipMsgs::UcAndMembershipOutput, }; use sp1_ics07_tendermint_utils::merkle::convert_tm_to_ics_merkle_proof; +use sp1_ics07_tendermint_utils::{light_block::LightBlockExt, rpc::TendermintRpcExt}; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::{Client, HttpClient}; diff --git a/operator/src/runners/fixtures/update_client.rs b/operator/src/runners/fixtures/update_client.rs index e7d7065..cecca19 100644 --- a/operator/src/runners/fixtures/update_client.rs +++ b/operator/src/runners/fixtures/update_client.rs @@ -2,8 +2,6 @@ use crate::{ cli::command::{fixtures::UpdateClientCmd, OutputPath}, - helpers::light_block::LightBlockExt, - rpc::TendermintRpcExt, runners::genesis::SP1ICS07TendermintGenesis, }; use alloy_sol_types::SolValue; @@ -16,6 +14,7 @@ use sp1_ics07_tendermint_solidity::{ ISP1Msgs::SP1Proof, IUpdateClientMsgs::{MsgUpdateClient, UpdateClientOutput}, }; +use sp1_ics07_tendermint_utils::{light_block::LightBlockExt, rpc::TendermintRpcExt}; use sp1_sdk::HashableKey; use std::path::PathBuf; use tendermint_rpc::HttpClient; diff --git a/operator/src/runners/genesis.rs b/operator/src/runners/genesis.rs index 6970b8f..d4d4a10 100644 --- a/operator/src/runners/genesis.rs +++ b/operator/src/runners/genesis.rs @@ -1,16 +1,13 @@ //! Contains the runner for the genesis command. -use crate::{ - cli::command::{genesis::Args, OutputPath}, - helpers::light_block::LightBlockExt, - rpc::TendermintRpcExt, -}; +use crate::cli::command::{genesis::Args, OutputPath}; use alloy_sol_types::SolValue; use sp1_ics07_tendermint_prover::programs::{ MembershipProgram, MisbehaviourProgram, SP1Program, UpdateClientAndMembershipProgram, UpdateClientProgram, }; use sp1_ics07_tendermint_solidity::IICS07TendermintMsgs::ConsensusState as SolConsensusState; +use sp1_ics07_tendermint_utils::{light_block::LightBlockExt, rpc::TendermintRpcExt}; use sp1_sdk::{utils::setup_logger, HashableKey}; use std::path::PathBuf; use tendermint_light_client_verifier::types::{LightBlock, TrustThreshold}; diff --git a/operator/src/runners/operator.rs b/operator/src/runners/operator.rs index 50e267e..f466264 100644 --- a/operator/src/runners/operator.rs +++ b/operator/src/runners/operator.rs @@ -2,11 +2,7 @@ use std::env; -use crate::{ - cli::command::operator::Args, - helpers::{self, light_block::LightBlockExt}, - rpc::TendermintRpcExt, -}; +use crate::cli::command::operator::Args; use alloy::providers::ProviderBuilder; use alloy_sol_types::SolValue; use log::{debug, info}; @@ -18,6 +14,7 @@ use sp1_ics07_tendermint_solidity::{ sp1_ics07_tendermint, IICS07TendermintMsgs::Env, ISP1Msgs::SP1Proof, IUpdateClientMsgs::MsgUpdateClient, }; +use sp1_ics07_tendermint_utils::{eth, light_block::LightBlockExt, rpc::TendermintRpcExt}; use sp1_sdk::{utils::setup_logger, HashableKey}; use tendermint_rpc::HttpClient; @@ -34,7 +31,7 @@ pub async fn run(args: Args) -> anyhow::Result<()> { let contract_address = env::var("CONTRACT_ADDRESS").expect("CONTRACT_ADDRESS not set"); // Instantiate a Tendermint prover based on the environment variable. - let wallet = helpers::eth::wallet_from_env(); + let wallet = eth::wallet_from_env(); let provider = ProviderBuilder::new() .with_recommended_fillers() .wallet(wallet) diff --git a/packages/utils/Cargo.toml b/packages/utils/Cargo.toml index 92eb0aa..e784967 100644 --- a/packages/utils/Cargo.toml +++ b/packages/utils/Cargo.toml @@ -17,7 +17,7 @@ sp1-ics07-tendermint-solidity = { workspace = true } tendermint-light-client-verifier = { workspace = true } ibc-client-tendermint-types = { workspace = true } ibc-core-client-types = { workspace = true } -ibc-core-host-types = { workspace = true } +ibc-core-host-types = { workspace = true, features = ["std"] } tendermint = { workspace = true } ibc-core-commitment-types = { workspace = true } alloy = { workspace = true } From 3379b0befbd0d7d3f744956ef5492ead939c0752 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 2 Nov 2024 16:33:43 +0800 Subject: [PATCH 3/3] fix: build --- packages/prover/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/prover/Cargo.toml b/packages/prover/Cargo.toml index 2e58178..d550a1d 100644 --- a/packages/prover/Cargo.toml +++ b/packages/prover/Cargo.toml @@ -8,7 +8,7 @@ license = { workspace = true } [dependencies] sp1-sdk = { workspace = true } -ibc-client-tendermint-types = { workspace = true } +ibc-client-tendermint-types = { workspace = true, features = ["serde"] } ibc-core-commitment-types = { workspace = true } ibc-proto = { workspace = true } sp1-ics07-tendermint-solidity = { workspace = true }