Skip to content

Commit

Permalink
converter
Browse files Browse the repository at this point in the history
  • Loading branch information
claravanstaden committed Nov 5, 2024
1 parent 2250d9b commit d81affc
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 25 deletions.
33 changes: 12 additions & 21 deletions bridges/snowbridge/pallets/inbound-queue-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ pub mod pallet {
type GatewayAddress: Get<H160>;

type WeightInfo: WeightInfo;

/// AssetHub parachain ID
type AssetHubParaId: Get<u32>;
#[cfg(feature = "runtime-benchmarks")]
type Helper: BenchmarkHelper<Self>;
}
Expand Down Expand Up @@ -139,6 +140,8 @@ pub mod pallet {
Verification(VerificationError),
/// XCMP send failure
Send(SendError),
/// Message conversion error
ConvertMessage(ConvertMessageError),
}

#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo, PalletError)]
Expand Down Expand Up @@ -204,25 +207,7 @@ pub mod pallet {
let message = MessageV2::decode_all(&mut envelope.payload.as_ref())
.map_err(|_| Error::<T>::InvalidPayload)?;

// Decode xcm
let versioned_xcm = VersionedXcm::<()>::decode_with_depth_limit(
MAX_XCM_DECODE_DEPTH,
&mut message.xcm.as_ref(),
)
.map_err(|_| Error::<T>::InvalidPayload)?;
let xcm: Xcm<()> = versioned_xcm.try_into().map_err(|_| <Error<T>>::InvalidPayload)?;

log::info!(
target: LOG_TARGET,
"💫 xcm decoded as {:?}",
xcm,
);

// Set nonce flag to true
<Nonce<T>>::try_mutate(envelope.nonce, |done| -> DispatchResult {
*done = true;
Ok(())
})?;
let xcm = convert_message(message)?;

// Todo: Deposit fee(in Ether) to RewardLeger which should cover all of:
// T::RewardLeger::deposit(who, envelope.fee.into())?;
Expand All @@ -233,11 +218,17 @@ pub mod pallet {
// e. The reward

// Attempt to forward XCM to AH
let dest = Location::new(1, [Parachain(1000)]);
let dest = Location::new(1, [Parachain(T::AssetHubParaId)]);
let (message_id, _) = send_xcm::<T::XcmSender>(dest, xcm).map_err(Error::<T>::from)?;

Self::deposit_event(Event::MessageReceived { nonce: envelope.nonce, message_id });

// Set nonce flag to true
<Nonce<T>>::try_mutate(envelope.nonce, |done| -> DispatchResult {
*done = true;
Ok(())
})?;

Ok(())
}

Expand Down
74 changes: 70 additions & 4 deletions bridges/snowbridge/primitives/router/src/inbound/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
use codec::{Decode, Encode};
use core::marker::PhantomData;
use frame_support::{traits::tokens::Balance as BalanceT, PalletError};
use frame_support::PalletError;
use scale_info::TypeInfo;
use snowbridge_core::TokenId;
use sp_core::{Get, RuntimeDebug, H160, H256};
use sp_io::hashing::blake2_256;
use sp_runtime::{traits::MaybeEquivalence, MultiAddress};
use sp_runtime::MultiAddress;
use sp_std::prelude::*;
use xcm::prelude::{Junction::AccountKey20, *};
use xcm_executor::traits::ConvertLocation;
use xcm::MAX_XCM_DECODE_DEPTH;
use codec::DecodeLimit;

const MINIMUM_DEPOSIT: u128 = 1;
const LOG_TARGET: &str = "snowbridge-router-primitives";

/// Messages from Ethereum are versioned. This is because in future,
/// we may want to evolve the protocol so that the ethereum side sends XCM messages directly.
Expand Down Expand Up @@ -54,6 +55,71 @@ pub enum Asset {
}
}

/// Reason why a message conversion failed.
#[derive(Copy, Clone, TypeInfo, PalletError, Encode, Decode, RuntimeDebug)]
pub enum ConvertMessageError {
/// The XCM provided with the message could not be decoded into XCM.
InvalidXCM,
/// Invalid claimer MultiAddress provided in payload.
InvalidClaimer,
}

pub trait ConvertMessage {
fn convert(
message: Message,
) -> Result<Xcm<()>, ConvertMessageError>;
}

pub struct MessageToXcm<
EthereumUniversalLocation,
AssetHubLocation,
> where
EthereumUniversalLocation: Get<InteriorLocation>,
AssetHubLocation: Get<InteriorLocation>,
{
_phantom: PhantomData<(
EthereumUniversalLocation,
AssetHubLocation,
)>,
}

impl<
EthereumUniversalLocation,
AssetHubLocation,
> ConvertMessage
for MessageToXcm<
EthereumUniversalLocation,
AssetHubLocation,
>
where
EthereumUniversalLocation: Get<InteriorLocation>,
AssetHubLocation: Get<InteriorLocation>,
{
fn convert(message: Message) -> Result<Xcm<()>, ConvertMessageError> {
// Decode xcm
let versioned_xcm = VersionedXcm::<()>::decode_with_depth_limit(
MAX_XCM_DECODE_DEPTH,
&mut message.xcm.as_ref(),
).map_err(|_| ConvertMessageError::InvalidXCM)?;
let message_xcm: Xcm<()> = versioned_xcm.try_into().map_err(|_| ConvertMessageError::InvalidXCM)?;

log::debug!(target: LOG_TARGET,"xcm decoded as {:?}", message_xcm);

let origin_location: Location = Location::new(2, [EthereumUniversalLocation::get().into(), Junction::AccountKey20{ key: message.origin.into(), network: None}.into()]);
let instructions = vec![
AliasOrigin(origin_location),
];

if let Some(claimer) = message.claimer {
let claimer = MultiAddress::decode(&mut claimer.as_ref()).map_err(|_| ConvertMessageError::InvalidClaimer)?;
let claimer_location: Location = Location::new(1, [AssetHubLocation::get().into(), claimer.into()]);
instructions.push(SetAssetClaimer { location: claimer_location });
}

Ok(instructions.into())
}
}

#[cfg(test)]
mod tests {
use crate::inbound::{CallIndex, GlobalConsensusEthereumConvertsFor};
Expand Down

0 comments on commit d81affc

Please sign in to comment.