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

refactor(voyager): ensure_ibc_interface supports multiple interfaces #3578

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
8 changes: 5 additions & 3 deletions cosmwasm/ucs00-pingpong/src/ibc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
attr, entry_point, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg,
IbcChannelConnectMsg, IbcChannelOpenMsg, IbcOrder, IbcPacket, IbcPacketAckMsg,
IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, StdError,
attr, DepsMut, Env, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg,
IbcChannelOpenMsg, IbcOrder, IbcPacket, IbcPacketAckMsg, IbcPacketReceiveMsg,
IbcPacketTimeoutMsg, IbcReceiveResponse, Reply, Response, StdError,
kayandra marked this conversation as resolved.
Show resolved Hide resolved
};

use crate::{msg::UCS00PingPong, state::CONFIG, ContractError};
Expand Down
55 changes: 24 additions & 31 deletions lib/voyager-message/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use crate::{
ChainId, ClientInfo, ClientStateMeta, ClientType, ConsensusStateMeta, IbcInterface, IbcSpec,
},
data::Data,
rpc::ProofType,
RawClientId, VoyagerMessage,
};

Expand Down Expand Up @@ -82,10 +81,10 @@ pub struct ConsensusModuleInfo {
pub chain_id: ChainId,
#[arg(value_parser(|s: &str| ok(ConsensusType::new(s.to_owned()))))]
pub consensus_type: ConsensusType,
// REVIEW: Maybe we need this? Do different client types for a single consensus necessarily
// have the same client and consensus state types? /// The type of client this consensus
// module provides state for. #[arg(value_parser(|s: &str|
// ok(ClientType::new(s.to_owned()))))] pub client_type: ClientType,
// REVIEW: Maybe we need this? Do different client types for a single consensus necessarily have the same client and consensus state types?
// /// The type of client this consensus module provides state for.
// #[arg(value_parser(|s: &str| ok(ClientType::new(s.to_owned()))))]
// pub client_type: ClientType,
}

impl ConsensusModuleInfo {
Expand Down Expand Up @@ -177,12 +176,20 @@ impl ClientModuleInfo {

pub fn ensure_ibc_interface(
&self,
ibc_interface: impl AsRef<str>,
expected_interfaces: impl IntoIterator<Item = &'static str>,
) -> Result<(), UnexpectedIbcInterfaceError> {
if ibc_interface.as_ref() != self.ibc_interface.as_str() {
let expected_interfaces: Vec<IbcInterface> = expected_interfaces
.into_iter()
.map(IbcInterface::new)
.collect();

if !expected_interfaces
.iter()
.any(|e| e.as_str() == self.ibc_interface.as_str())
{
Err(UnexpectedIbcInterfaceError {
expected: self.ibc_interface.clone(),
found: ibc_interface.as_ref().to_owned(),
expected: expected_interfaces,
found: self.ibc_interface.to_string(),
})
} else {
Ok(())
Expand Down Expand Up @@ -256,36 +263,28 @@ pub struct UnexpectedChainIdError {
}

#[derive(Debug, Clone, thiserror::Error)]
#[error(
"invalid consensus type: this module provides functionality for consensus type `{expected}`, but the config specifies `{found}`"
)]
#[error("invalid consensus type: this module provides functionality for consensus type `{expected}`, but the config specifies `{found}`")]
pub struct UnexpectedConsensusTypeError {
pub expected: ConsensusType,
pub found: String,
}

#[derive(Debug, Clone, thiserror::Error)]
#[error(
"invalid client type: this module provides functionality for client type `{expected}`, but the config specifies `{found}`"
)]
#[error("invalid client type: this module provides functionality for client type `{expected}`, but the config specifies `{found}`")]
pub struct UnexpectedClientTypeError {
pub expected: ClientType,
pub found: String,
}

#[derive(Debug, Clone, thiserror::Error)]
#[error(
"invalid IBC interface: this module provides functionality for IBC interface `{expected}`, but the config specifies `{found}`"
)]
#[error("invalid IBC interface: this module provides functionality for IBC interfaces `{expected}`, but the config specifies `{found}`", expected = expected.iter().map(|x| x.as_str()).collect::<Vec<_>>().join(","))]
pub struct UnexpectedIbcInterfaceError {
pub expected: IbcInterface,
pub expected: Vec<IbcInterface>,
pub found: String,
}

#[derive(Debug, Clone, thiserror::Error)]
#[error(
"invalid IBC version: this module provides functionality for IBC version `{expected}`, but the config specifies `{found}`"
)]
#[error("invalid IBC version: this module provides functionality for IBC version `{expected}`, but the config specifies `{found}`")]
pub struct UnexpectedIbcVersionIdError {
pub expected: IbcSpecId,
pub found: String,
Expand Down Expand Up @@ -359,18 +358,14 @@ pub trait ProofModule<V: IbcSpec> {
/// Query a proof of IBC state on this chain, at the specified [`Height`],
/// returning the state as a JSON [`Value`].
#[method(name = "queryIbcProof", with_extensions)]
async fn query_ibc_proof(
&self,
at: Height,
path: V::StorePath,
) -> RpcResult<(Value, ProofType)>;
async fn query_ibc_proof(&self, at: Height, path: V::StorePath) -> RpcResult<Value>;
}

/// Type-erased version of [`ProofModuleClient`].
#[rpc(client, namespace = "proof")]
pub trait RawProofModule {
#[method(name = "queryIbcProof")]
async fn query_ibc_proof_raw(&self, at: Height, path: Value) -> RpcResult<(Value, ProofType)>;
async fn query_ibc_proof_raw(&self, at: Height, path: Value) -> RpcResult<Value>;
}

/// Client modules provide functionality to interact with a single light client
Expand Down Expand Up @@ -431,9 +426,7 @@ pub trait ConsensusModule {
async fn query_latest_timestamp(&self, finalized: bool) -> RpcResult<Timestamp>;
}

/// Client bootstrap modules provide the initial client and consensus states for a client. This is
/// notably separate from the [`ConsensusModule`], since it is possible for different client types
/// (with different state types) to track the same consensus.
/// Client bootstrap modules provide the initial client and consensus states for a client. This is notably separate from the [`ConsensusModule`], since it is possible for different client types (with different state types) to track the same consensus.
#[rpc(client, server, namespace = "clientBootstrap")]
pub trait ClientBootstrapModule {
/// The client state of this chain at the specified [`Height`].
Expand Down
2 changes: 1 addition & 1 deletion voyager/modules/client/ethereum/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl ClientModule for Module {
async fn new(config: Self::Config, info: ClientModuleInfo) -> Result<Self, BoxDynError> {
info.ensure_client_type(ClientType::ETHEREUM)?;
info.ensure_consensus_type(ConsensusType::ETHEREUM)?;
info.ensure_ibc_interface(IbcInterface::IBC_COSMWASM)?;
info.ensure_ibc_interface([IbcInterface::IBC_COSMWASM])?;

Ok(Self {
chain_spec: config.chain_spec,
Expand Down
2 changes: 1 addition & 1 deletion voyager/modules/client/movement/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl ClientModule for Module {
async fn new(Config {}: Self::Config, info: ClientModuleInfo) -> Result<Self, BoxDynError> {
info.ensure_client_type(ClientType::MOVEMENT)?;
info.ensure_consensus_type(ConsensusType::MOVEMENT)?;
info.ensure_ibc_interface(IbcInterface::IBC_COSMWASM)?;
info.ensure_ibc_interface([IbcInterface::IBC_COSMWASM])?;

Ok(Module {})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl ClientModule for Module {
async fn new(_: Self::Config, info: ClientModuleInfo) -> Result<Self, BoxDynError> {
info.ensure_client_type(ClientType::STATE_LENS_ICS23_ICS23)?;
info.ensure_consensus_type(ConsensusType::TENDERMINT)?;
info.ensure_ibc_interface(IbcInterface::IBC_SOLIDITY)?;
info.ensure_ibc_interface([IbcInterface::IBC_COSMWASM])?;
Ok(Self {})
}
}
Expand Down
8 changes: 5 additions & 3 deletions voyager/modules/client/state-lens/ics23-mpt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ impl ClientModule for Module {
async fn new(_: Self::Config, info: ClientModuleInfo) -> Result<Self, BoxDynError> {
info.ensure_client_type(ClientType::STATE_LENS_ICS23_MPT)?;
info.ensure_consensus_type(ConsensusType::ETHEREUM)?;
info.ensure_ibc_interface(IbcInterface::IBC_SOLIDITY)
.or(info.ensure_ibc_interface(IbcInterface::IBC_COSMWASM))
.or(info.ensure_ibc_interface(IbcInterface::IBC_MOVE_APTOS))?;
info.ensure_ibc_interface([
IbcInterface::IBC_SOLIDITY,
IbcInterface::IBC_COSMWASM,
IbcInterface::IBC_MOVE_APTOS,
])?;

Ok(Self {
ibc_interface: SupportedIbcInterface::try_from(info.ibc_interface.to_string())?,
Expand Down
3 changes: 1 addition & 2 deletions voyager/modules/client/state-lens/ics23-smt/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ impl ClientModule for Module {
async fn new(_: Self::Config, info: ClientModuleInfo) -> Result<Self, BoxDynError> {
info.ensure_client_type(ClientType::STATE_LENS_ICS23_SMT)?;
info.ensure_consensus_type(ConsensusType::MOVEMENT)?;
info.ensure_ibc_interface(IbcInterface::IBC_SOLIDITY)
.or(info.ensure_ibc_interface(IbcInterface::IBC_COSMWASM))?;
info.ensure_ibc_interface([IbcInterface::IBC_SOLIDITY, IbcInterface::IBC_COSMWASM])?;

Ok(Self {
ibc_interface: SupportedIbcInterface::try_from(info.ibc_interface.to_string())?,
Expand Down