Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ChainHandle dependency from build_create_client_payload #478

Merged
merged 18 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b8e1d3f
Implement CanQueryStakingParams component
ljoss17 Nov 22, 2024
2a87260
Replace CanQueryStakingParams with CanQueryUnbondingPeriod
ljoss17 Nov 22, 2024
0a6789b
Remove dependency from ChainHandle for build_create_client_payload
ljoss17 Nov 25, 2024
9141081
Use CosmosCreateClientPayloadV2 in BuildCreateClientPayload
ljoss17 Nov 25, 2024
8eb670e
Remove trusted light block verification from Cosmos build_create_clie…
ljoss17 Nov 25, 2024
22ac8b6
Use ibc-rs Height and ChainID instead of ibc-relayer-types in BuildCr…
ljoss17 Nov 25, 2024
671aab5
Merge branch 'main' into luca_joss/add-query-stacking-params-component
ljoss17 Nov 27, 2024
672afeb
Use CometLightClient to fetch light block in build_create_client_payload
ljoss17 Nov 27, 2024
a59542b
Use ibc-relayer-types for CreateClientPayloadBuilder impl without Cha…
ljoss17 Nov 28, 2024
e46f3f2
Improve StakingParamsUnbondingPeriod and wire UnbondingPeriodQuerier …
ljoss17 Nov 28, 2024
9799856
Wire up new payload builder
soareschen Nov 28, 2024
f0cadc7
Rename and cleanup BuildCosmosCreateClientPayload
ljoss17 Nov 28, 2024
8770505
Default trusting period to 2/3 of unbonding period if it is missing f…
ljoss17 Nov 28, 2024
f30a44c
Use CosmosCreateClientOptions instead of ibc-relayer Settings
ljoss17 Nov 28, 2024
e1413aa
Merge branch 'main' into luca_joss/add-query-stacking-params-component
ljoss17 Nov 28, 2024
42bde6a
Use 14 days as default trusting_period in CosmosCreateClientOptions
ljoss17 Nov 28, 2024
b3b79de
Use default create client options in tests
soareschen Nov 29, 2024
ab7b846
Fix default max_clock_drift
soareschen Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![recursion_limit = "256"]

use core::time::Duration;
use std::sync::Arc;

use hermes_cosmos_chain_components::types::config::gas::dynamic_gas_config::DynamicGasConfig;
Expand All @@ -11,8 +10,6 @@ use hermes_cosmos_relayer::contexts::build::CosmosBuilder;
use hermes_error::types::Error;
use hermes_ibc_test_suite::tests::transfer::TestIbcTransfer;
use hermes_test_components::setup::traits::run_test::CanRunTest;
use ibc_relayer::chain::cosmos::client::Settings;
use ibc_relayer_types::core::ics02_client::trust_threshold::TrustThreshold;
use ibc_relayer_types::core::ics24_host::identifier::PortId;

// FIXME: Celestia currently can only be bootstrapped using CosmosBootstrap.
Expand Down Expand Up @@ -53,16 +50,10 @@ fn celestia_integration_tests() -> Result<(), Error> {
dynamic_gas: Some(DynamicGasConfig::default()),
});

let create_client_settings = Settings {
max_clock_drift: Duration::from_secs(40),
trusting_period: Some(Duration::from_secs(60 * 60)),
trust_threshold: TrustThreshold::ONE_THIRD,
};

let setup = CosmosBinaryChannelSetup {
bootstrap_a: celestia_bootstrap,
bootstrap_b: cosmos_bootstrap,
create_client_settings,
create_client_settings: Default::default(),
init_connection_options: Default::default(),
init_channel_options: Default::default(),
port_id: PortId::transfer(),
Expand Down
26 changes: 19 additions & 7 deletions crates/cli/cli/src/contexts/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use hermes_cli_components::traits::output::{
use hermes_cli_components::traits::parse::ArgParserComponent;
use hermes_cli_components::traits::types::config::ConfigTypeComponent;
use hermes_cli_framework::output::Output;
use hermes_cosmos_chain_components::types::payloads::client::CosmosCreateClientOptions;
use hermes_cosmos_integration_tests::contexts::bootstrap::CosmosBootstrap;
use hermes_cosmos_relayer::contexts::build::CosmosBuilder;
use hermes_cosmos_relayer::contexts::chain::CosmosChain;
Expand All @@ -56,7 +57,6 @@ use hermes_runtime::types::runtime::HermesRuntime;
use hermes_runtime_components::traits::runtime::{
ProvideDefaultRuntimeField, RuntimeGetterComponent, RuntimeTypeComponent,
};
use ibc_relayer::chain::cosmos::client::Settings;
use ibc_relayer::config::Config;
use ibc_relayer::foreign_client::CreateOptions;
use ibc_relayer_types::core::ics24_host::identifier::{ChainId, ClientId};
Expand Down Expand Up @@ -192,18 +192,30 @@ impl CreateClientOptionsParser<HermesApp, CreateClientArgs, 0, 1> for HermesAppC
args: &CreateClientArgs,
target_chain: &CosmosChain,
counterparty_chain: &CosmosChain,
) -> Result<((), Settings), Error> {
) -> Result<((), CosmosCreateClientOptions), Error> {
let options = CreateOptions {
max_clock_drift: args.clock_drift.map(|d| d.into()),
trusting_period: args.trusting_period.map(|d| d.into()),
trust_threshold: args.trust_threshold,
};

let settings = Settings::for_create_command(
options,
&target_chain.chain_config.clone(),
&counterparty_chain.chain_config.clone(),
);
let max_clock_drift = match options.max_clock_drift {
Some(input) => input,
None => {
target_chain.chain_config.clock_drift
+ counterparty_chain.chain_config.clock_drift
+ counterparty_chain.chain_config.max_block_time
}
};

let settings = CosmosCreateClientOptions {
max_clock_drift,
trusting_period: options.trusting_period.unwrap_or_default(),
trust_threshold: options
.trust_threshold
.map(|threshold| threshold.into())
.unwrap_or_default(),
};

Ok(((), settings))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ use crate::impls::types::chain::ProvideCosmosChainTypes;
use crate::impls::types::client_state::ProvideAnyRawClientState;
use crate::impls::types::consensus_state::ProvideAnyRawConsensusState;
use crate::impls::types::payload::ProvideCosmosPayloadTypes;
use crate::impls::unbonding_period::StakingParamsUnbondingPeriod;
pub use crate::traits::abci_query::AbciQuerierComponent;
pub use crate::traits::unbonding_period::UnbondingPeriodQuerierComponent;

define_components! {
CosmosClientComponents {
Expand Down Expand Up @@ -318,6 +320,8 @@ define_components! {
QueryCometBlock,
AbciQuerierComponent:
QueryAbci,
UnbondingPeriodQuerierComponent:
StakingParamsUnbondingPeriod,
[
ConnectionEndQuerierComponent,
ConnectionEndWithProofsQuerierComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use hermes_relayer_components::chain::traits::types::update_client::UpdateClient

use crate::impls::channel::channel_handshake_message::BuildCosmosChannelHandshakeMessage;
use crate::impls::client::create_client_message::BuildAnyCreateClientMessage;
use crate::impls::client::create_client_payload::BuildCreateClientPayloadWithChainHandle;
use crate::impls::client::create_client_payload::BuildCosmosCreateClientPayload;
use crate::impls::client::update_client_message::BuildCosmosUpdateClientMessage;
use crate::impls::client::update_client_payload::BuildTendermintUpdateClientPayload;
use crate::impls::connection::connection_handshake_message::BuildCosmosConnectionHandshakeMessage;
Expand Down Expand Up @@ -86,7 +86,7 @@ define_components! {
UpdateClientMessageBuilderComponent:
BuildCosmosUpdateClientMessage,
CreateClientPayloadBuilderComponent:
BuildCreateClientPayloadWithChainHandle,
BuildCosmosCreateClientPayload,
UpdateClientPayloadBuilderComponent:
BuildTendermintUpdateClientPayload,
[
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,125 @@
use cgp::core::error::CanRaiseError;

use hermes_chain_type_components::traits::fields::chain_id::HasChainId;
use hermes_comet_light_client_components::traits::fetch_light_block::CanFetchLightBlock;
use hermes_comet_light_client_context::contexts::light_client::CometLightClient;
use hermes_error::types::HermesError;
use hermes_relayer_components::chain::traits::payload_builders::create_client::CreateClientPayloadBuilder;
use hermes_relayer_components::chain::traits::queries::chain_status::{
CanQueryChainHeight, CanQueryChainStatus,
};
use hermes_relayer_components::chain::traits::types::create_client::{
HasCreateClientPayloadOptionsType, HasCreateClientPayloadType,
};
use ibc_relayer::chain::client::ClientSettings;
use ibc_relayer::chain::cosmos::client::Settings;
use ibc_relayer::chain::handle::ChainHandle;
use ibc_relayer::client_state::AnyClientState;
use ibc_relayer::consensus_state::AnyConsensusState;

use crate::traits::chain_handle::HasBlockingChainHandle;
use crate::types::payloads::client::CosmosCreateClientPayload;
use ibc_relayer_types::clients::ics07_tendermint::client_state::{AllowUpdate, ClientState};
use ibc_relayer_types::clients::ics07_tendermint::consensus_state::ConsensusState;
use ibc_relayer_types::clients::ics07_tendermint::error::Error as TendermintClientError;
use ibc_relayer_types::core::ics23_commitment::commitment::CommitmentRoot;
use ibc_relayer_types::core::ics24_host::identifier::ChainId;
use ibc_relayer_types::Height;

use tendermint::block::Height as TendermintHeight;
use tendermint::error::Error as TendermintError;
use tendermint_rpc::Client;
use tendermint_rpc::Error as TendermintRpcError;

use crate::traits::rpc_client::HasRpcClient;
use crate::traits::unbonding_period::CanQueryUnbondingPeriod;
use crate::types::payloads::client::{CosmosCreateClientOptions, CosmosCreateClientPayload};
use crate::types::status::ChainStatus;
use crate::types::tendermint::TendermintClientState;

pub struct BuildCreateClientPayloadWithChainHandle;
pub struct BuildCosmosCreateClientPayload;

impl<Chain, Counterparty> CreateClientPayloadBuilder<Chain, Counterparty>
for BuildCreateClientPayloadWithChainHandle
for BuildCosmosCreateClientPayload
where
Chain: HasCreateClientPayloadOptionsType<Counterparty, CreateClientPayloadOptions = Settings>
+ HasCreateClientPayloadType<Counterparty, CreateClientPayload = CosmosCreateClientPayload>
+ HasBlockingChainHandle
+ CanRaiseError<eyre::Report>,
Chain: HasRpcClient
+ HasCreateClientPayloadOptionsType<
Counterparty,
CreateClientPayloadOptions = CosmosCreateClientOptions,
> + HasCreateClientPayloadType<Counterparty, CreateClientPayload = CosmosCreateClientPayload>
+ CanQueryUnbondingPeriod
+ HasChainId<ChainId = ChainId>
+ CanQueryChainHeight<Height = Height>
+ CanQueryChainStatus<ChainStatus = ChainStatus>
+ CanRaiseError<TendermintClientError>
+ CanRaiseError<TendermintError>
+ CanRaiseError<TendermintRpcError>
+ CanRaiseError<String>
+ CanRaiseError<HermesError>,
{
async fn build_create_client_payload(
chain: &Chain,
create_client_options: &Settings,
create_client_options: &Chain::CreateClientPayloadOptions,
) -> Result<CosmosCreateClientPayload, Chain::Error> {
let client_settings = create_client_options.clone();

chain
.with_blocking_chain_handle(move |chain_handle| {
let height = chain_handle
.query_latest_height()
.map_err(Chain::raise_error)?;

let any_client_state = chain_handle
.build_client_state(height, ClientSettings::Tendermint(client_settings))
.map_err(Chain::raise_error)?;

let client_state = match &any_client_state {
AnyClientState::Tendermint(client_state) => client_state.clone(),
};

let any_consensus_state = chain_handle
.build_consensus_state(
any_client_state.latest_height(),
height,
any_client_state,
)
.map_err(Chain::raise_error)?;

let AnyConsensusState::Tendermint(consensus_state) = any_consensus_state;

Ok(CosmosCreateClientPayload {
client_state,
consensus_state,
})
})
let latest_height = chain.query_chain_height().await?;

let unbonding_period = chain.query_unbonding_period().await?;

let trusting_period = create_client_options.trusting_period;
let trust_threshold = create_client_options
.trust_threshold
.try_into()
.map_err(|e| {
Chain::raise_error(format!(
"failed to convert `Fraction` to `TrustThreshold` for trust_threshold: {e}"
))
})?;

#[allow(deprecated)]
let client_state = ClientState::new(
chain.chain_id().clone(),
trust_threshold,
trusting_period,
unbonding_period,
create_client_options.max_clock_drift,
latest_height,
Default::default(),
vec!["upgrade".to_string(), "upgradedIBCState".to_string()],
AllowUpdate {
after_expiry: true,
after_misbehaviour: true,
},
)
.map_err(Chain::raise_error)?;

let rpc_client = chain.rpc_client().clone();

let tendermint_latest_height = TendermintHeight::try_from(latest_height.revision_height())
.map_err(Chain::raise_error)?;

let status = rpc_client.status().await.map_err(Chain::raise_error)?;

let current_time = status.sync_info.latest_block_time;
let peer_id = status.node_info.id;

let light_client_options =
TendermintClientState::from(client_state.clone()).as_light_client_options();

let light_client = CometLightClient::new(
current_time,
peer_id,
rpc_client.clone(),
light_client_options,
);

let trusted_block = light_client
.fetch_light_block(&tendermint_latest_height)
.await
.map_err(Chain::raise_error)?;

let consensus_state = ConsensusState {
root: CommitmentRoot::from_bytes(trusted_block.signed_header.header.app_hash.as_ref()),
timestamp: trusted_block.signed_header.header.time,
next_validators_hash: trusted_block.signed_header.header.next_validators_hash,
};

// Create client payload
Ok(CosmosCreateClientPayload {
client_state,
consensus_state,
})
}
}
1 change: 1 addition & 0 deletions crates/cosmos/cosmos-chain-components/src/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ pub mod packet;
pub mod queries;
pub mod transaction;
pub mod types;
pub mod unbonding_period;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use cgp::prelude::Async;
use hermes_relayer_components::chain::traits::types::create_client::{
ProvideCreateClientMessageOptionsType, ProvideCreateClientPayloadOptionsType,
};
use ibc_relayer::chain::cosmos::client::Settings;

use crate::types::payloads::client::CosmosCreateClientOptions;

pub struct ProvideCosmosCreateClientSettings;

Expand All @@ -11,7 +12,7 @@ impl<Chain, Counterparty> ProvideCreateClientPayloadOptionsType<Chain, Counterpa
where
Chain: Async,
{
type CreateClientPayloadOptions = Settings;
type CreateClientPayloadOptions = CosmosCreateClientOptions;
}

pub struct ProvideNoCreateClientMessageOptionsType;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use cgp::prelude::*;
use core::time::Duration;
use prost::{DecodeError, Message};

use hermes_relayer_components::chain::traits::queries::chain_status::CanQueryChainHeight;
use hermes_relayer_components::chain::traits::types::height::HasHeightType;

use ibc_proto::cosmos::staking::v1beta1::QueryParamsResponse;
use ibc_relayer_types::Height;

use crate::traits::abci_query::CanQueryAbci;
use crate::traits::unbonding_period::UnbondingPeriodQuerier;

pub struct StakingParamsUnbondingPeriod;

impl<Chain> UnbondingPeriodQuerier<Chain> for StakingParamsUnbondingPeriod
where
Chain: CanQueryChainHeight
+ CanQueryAbci
+ HasHeightType<Height = Height>
+ CanRaiseError<&'static str>
+ CanRaiseError<DecodeError>,
{
async fn query_unbonding_period(chain: &Chain) -> Result<Duration, Chain::Error> {
let latest_height = chain.query_chain_height().await?;

let query_staking_params_bytes = chain
.query_abci(
"/cosmos.staking.v1beta1.Query/Params",
&"".to_owned().into_bytes(),
&latest_height,
)
.await?;

let query_staking_params: QueryParamsResponse =
QueryParamsResponse::decode(query_staking_params_bytes.as_ref())
.map_err(Chain::raise_error)?;

let staking_params = query_staking_params
.params
.ok_or_else(|| Chain::raise_error("staking params is empty"))?;

let unbonding_time = staking_params
.unbonding_time
.ok_or_else(|| Chain::raise_error("unbonding time in staking params is empty"))?;

Ok(Duration::new(
unbonding_time.seconds as u64,
unbonding_time.nanos as u32,
))
}
}
1 change: 1 addition & 0 deletions crates/cosmos/cosmos-chain-components/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod grpc_address;
pub mod message;
pub mod rpc_client;
pub mod tx_extension_options;
pub mod unbonding_period;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use core::time::Duration;

use cgp::prelude::*;

#[derive_component(UnbondingPeriodQuerierComponent, UnbondingPeriodQuerier<Chain>)]
#[async_trait]
pub trait CanQueryUnbondingPeriod: HasErrorType + Async {
async fn query_unbonding_period(&self) -> Result<Duration, Self::Error>;
}
Loading
Loading