Skip to content

Commit

Permalink
feat(voyager): support wasm clients alongside native clients of the s…
Browse files Browse the repository at this point in the history
…ame chain
  • Loading branch information
benluelo committed May 20, 2024
1 parent 0b7c142 commit 3f6ed86
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 36 deletions.
44 changes: 23 additions & 21 deletions lib/chain-utils/src/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use unionlabs::{
NextConnectionSequencePath, NextSequenceRecvPath, ReceiptPath,
},
id::{ChannelId, ClientId, PortId},
option_unwrap,
iter, option_unwrap,
traits::{Chain, ClientIdOf, ClientState, FromStrExact, HeightOf},
uint::U256,
};
Expand Down Expand Up @@ -204,27 +204,29 @@ pub const ETHEREUM_REVISION_NUMBER: u64 = 0;

impl<C: ChainSpec> FromStrExact for EthereumChainType<C> {
const EXPECTING: &'static str = {
const PREFIX: [u8; 4] = *b"eth-";

const fn concat(cs: &[u8]) -> [u8; 11] {
[
PREFIX[0], PREFIX[1], PREFIX[2], PREFIX[3], cs[0], cs[1], cs[2], cs[3], cs[4],
cs[5], cs[6],
]
}

// generic_const_exprs is still incomplete :(
const CHAIN_SPEC_LEN: usize = 7;
assert!(
C::EXPECTING.len() == CHAIN_SPEC_LEN,
"ChainSpec string value is expected to be 7 bytes"
);

match core::str::from_utf8(const { &concat(C::EXPECTING.as_bytes()) }) {
Ok(ok) => ok,
Err(_) => {
panic!()
match core::str::from_utf8(
const {
let mut buf = [0_u8; 32];

iter! {
for (i, b) in enumerate(b"eth-") {
buf[i] = b;
}
}

iter! {
for (i, b) in enumerate(C::EXPECTING.as_bytes()) {
buf[4 + i] = b;
}
}

buf
}
.split_at(4 + C::EXPECTING.len())
.0,
) {
Ok(ok) => ok,
Err(_) => panic!("called `Result::unwrap()` on an `Err` value"),
}
};
}
Expand Down
45 changes: 42 additions & 3 deletions lib/chain-utils/src/wasm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
use std::num::NonZeroU64;
use std::{marker::PhantomData, num::NonZeroU64};

use frame_support_procedural::DefaultNoBound;
use futures::Future;
use unionlabs::{encoding::Proto, google::protobuf::any::Any, hash::H256, traits::Chain};
use unionlabs::{
encoding::Proto,
google::protobuf::any::Any,
hash::H256,
iter,
traits::{Chain, FromStrExact},
};

use crate::cosmos_sdk::CosmosSdkChain;

Expand Down Expand Up @@ -49,8 +56,40 @@ where
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, DefaultNoBound)]
pub struct WasmChainType<Hc: Chain>(PhantomData<fn() -> Hc>);

impl<Hc: Chain> FromStrExact for WasmChainType<Hc> {
const EXPECTING: &'static str = {
match core::str::from_utf8(
const {
let mut buf = [0_u8; 32];

iter! {
for (i, b) in enumerate(b"wasm-") {
buf[i] = b;
}
}

iter! {
for (i, b) in enumerate(Hc::ChainType::EXPECTING.as_bytes()) {
buf[5 + i] = b;
}
}

buf
}
.split_at(5 + Hc::ChainType::EXPECTING.len())
.0,
) {
Ok(ok) => ok,
Err(_) => panic!("called `Result::unwrap()` on an `Err` value"),
}
};
}

impl<Hc: CosmosSdkChain> Chain for Wasm<Hc> {
type ChainType = Hc::ChainType;
type ChainType = WasmChainType<Hc>;

type SelfClientState = Hc::SelfClientState;
type SelfConsensusState = Hc::SelfConsensusState;
Expand Down
53 changes: 44 additions & 9 deletions lib/relay-message/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,15 @@ pub enum AnyLightClientIdentified<T: AnyLightClient> {
/// The solidity client on Arbitrum tracking the state of Wasm<Union>.
UnionOnArbitrum(lc!(Wasm<Union> => Arbitrum)),

/// The 08-wasm client tracking the state of Cosmos.
CosmosOnUnion(lc!(Wasm<Cosmos> => Union)),
/// The solidity client on Cosmos tracking the state of Wasm<Union>.
UnionOnCosmos(lc!(Union => Wasm<Cosmos>)),
/// The native tendermint client on Union tracking the state of Wasm<Cosmos>.
WasmCosmosOnUnion(lc!(Wasm<Cosmos> => Union)),
/// The 08-wasm client on Cosmos tracking the state of Union.
UnionOnWasmCosmos(lc!(Union => Wasm<Cosmos>)),

/// The native tendermint client on Union tracking the state of Cosmos.
CosmosOnUnion(lc!(Cosmos => Union)),
/// The native cometbls client on Cosmos tracking the state of Union.
UnionOnCosmos(lc!(Union => Cosmos)),

/// The 08-wasm client tracking the state of Cosmos.
CosmosOnCosmos(lc!(Cosmos => Cosmos)),
Expand Down Expand Up @@ -278,8 +283,12 @@ enum AnyLightClientIdentifiedSerde<T: AnyLightClient> {
ArbitrumOnUnion(Inner<Wasm<Union>, Arbitrum, lc!(Arbitrum => Wasm<Union>)>),
UnionOnArbitrum(Inner<Arbitrum, Wasm<Union>, lc!(Wasm<Union> => Arbitrum)>),

CosmosOnUnion(Inner<Union, Wasm<Cosmos>, lc!(Wasm<Cosmos> => Union)>),
UnionOnCosmos(Inner<Wasm<Cosmos>, Union, lc!(Union => Wasm<Cosmos>)>),
WasmCosmosOnUnion(Inner<Union, Wasm<Cosmos>, lc!(Wasm<Cosmos> => Union)>),
UnionOnWasmCosmos(Inner<Wasm<Cosmos>, Union, lc!(Union => Wasm<Cosmos>)>),

CosmosOnUnion(Inner<Union, Cosmos, lc!(Cosmos => Union)>),
UnionOnCosmos(Inner<Cosmos, Union, lc!(Union => Cosmos)>),

CosmosOnCosmos(Inner<Cosmos, Cosmos, lc!(Cosmos => Cosmos)>),
}

Expand All @@ -302,6 +311,12 @@ impl<T: AnyLightClient> From<AnyLightClientIdentified<T>> for AnyLightClientIden
AnyLightClientIdentified::UnionOnScroll(t) => Self::UnionOnScroll(Inner::new(t)),
AnyLightClientIdentified::ArbitrumOnUnion(t) => Self::ArbitrumOnUnion(Inner::new(t)),
AnyLightClientIdentified::UnionOnArbitrum(t) => Self::UnionOnArbitrum(Inner::new(t)),
AnyLightClientIdentified::WasmCosmosOnUnion(t) => {
Self::WasmCosmosOnUnion(Inner::new(t))
}
AnyLightClientIdentified::UnionOnWasmCosmos(t) => {
Self::UnionOnWasmCosmos(Inner::new(t))
}
AnyLightClientIdentified::CosmosOnUnion(t) => Self::CosmosOnUnion(Inner::new(t)),
AnyLightClientIdentified::UnionOnCosmos(t) => Self::UnionOnCosmos(Inner::new(t)),
AnyLightClientIdentified::CosmosOnCosmos(t) => Self::CosmosOnCosmos(Inner::new(t)),
Expand All @@ -328,9 +343,11 @@ impl<T: AnyLightClient> From<AnyLightClientIdentifiedSerde<T>> for AnyLightClien
AnyLightClientIdentifiedSerde::UnionOnScroll(t) => Self::UnionOnScroll(t.inner),
AnyLightClientIdentifiedSerde::ArbitrumOnUnion(t) => Self::ArbitrumOnUnion(t.inner),
AnyLightClientIdentifiedSerde::UnionOnArbitrum(t) => Self::UnionOnArbitrum(t.inner),
AnyLightClientIdentifiedSerde::WasmCosmosOnUnion(t) => Self::WasmCosmosOnUnion(t.inner),
AnyLightClientIdentifiedSerde::UnionOnWasmCosmos(t) => Self::UnionOnWasmCosmos(t.inner),
AnyLightClientIdentifiedSerde::CosmosOnCosmos(t) => Self::CosmosOnCosmos(t.inner),
AnyLightClientIdentifiedSerde::CosmosOnUnion(t) => Self::CosmosOnUnion(t.inner),
AnyLightClientIdentifiedSerde::UnionOnCosmos(t) => Self::UnionOnCosmos(t.inner),
AnyLightClientIdentifiedSerde::CosmosOnCosmos(t) => Self::CosmosOnCosmos(t.inner),
}
}
}
Expand Down Expand Up @@ -533,22 +550,40 @@ macro_rules! any_lc {
$expr
}

AnyLightClientIdentified::CosmosOnUnion($msg) => {
AnyLightClientIdentified::WasmCosmosOnUnion($msg) => {
#[allow(dead_code)]
type Hc = chain_utils::union::Union;
#[allow(dead_code)]
type Tr = chain_utils::wasm::Wasm<chain_utils::cosmos::Cosmos>;

$expr
}
AnyLightClientIdentified::UnionOnCosmos($msg) => {
AnyLightClientIdentified::UnionOnWasmCosmos($msg) => {
#[allow(dead_code)]
type Hc = chain_utils::wasm::Wasm<chain_utils::cosmos::Cosmos>;
#[allow(dead_code)]
type Tr = chain_utils::union::Union;

$expr
}

AnyLightClientIdentified::CosmosOnUnion($msg) => {
#[allow(dead_code)]
type Hc = chain_utils::union::Union;
#[allow(dead_code)]
type Tr = chain_utils::cosmos::Cosmos;

$expr
}
AnyLightClientIdentified::UnionOnCosmos($msg) => {
#[allow(dead_code)]
type Hc = chain_utils::cosmos::Cosmos;
#[allow(dead_code)]
type Tr = chain_utils::union::Union;

$expr
}

AnyLightClientIdentified::CosmosOnCosmos($msg) => {
#[allow(dead_code)]
type Hc = chain_utils::cosmos::Cosmos;
Expand Down
18 changes: 18 additions & 0 deletions lib/unionlabs/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,21 @@ macro_rules! option_unwrap {
}
}};
}

/// Minimal version of <https://github.com/benluelo/advent-of-code/blob/18684af90a06eb594b07dee9b99593ce3f872641/rust/src/const_helpers.rs#L299-L369>. Check there if any other features are required.
#[macro_export]
macro_rules! iter {
($($label:lifetime:)? for ($i:ident, $item:pat) in enumerate($slice:expr)
$body:block
) => {{
let __slice = $slice;
let mut __i = 0;
$($label:)? while __i < __slice.len() {
#[allow(clippy::toplevel_ref_arg)]
let $item = __slice[__i];
__i += 1;
let $i = __i - 1;
$body;
}
}};
}
2 changes: 1 addition & 1 deletion lib/unionlabs/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub trait Member = Debug

/// Represents a chain.
pub trait Chain: Sized + Send + Sync + 'static {
/// Expected to be unique across all implementations. Note that Wasm<_> implements this by passing through to the host chain, as `Wasm<A> <-> Wasm<B>` and `A <-> B` simultaneously is not currently supported.
/// Expected to be unique across all implementations.
type ChainType: FromStrExact;

/// The client state of this chain.
Expand Down
4 changes: 2 additions & 2 deletions ucli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ async fn handle_transfer<C: ChainSpec>(
.get_denom_address(channel_id.clone(), denom)
.await
.unwrap();
println!("Address is: {}", denom);
println!("Address is: {:?}", denom);

let erc_contract = erc20::ERC20::new(denom, signer_middleware.clone());

Expand Down Expand Up @@ -245,7 +245,7 @@ async fn handle_transfer<C: ChainSpec>(
.into(),
Height {
revision_number: 0,
revision_height: u64::MAX,
revision_height: 0,
}
.into(),
u64::MAX,
Expand Down

0 comments on commit 3f6ed86

Please sign in to comment.