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

Implement fees in outbound router since it is not supported #941

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 7 additions & 8 deletions parachain/primitives/router/src/outbound/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,6 @@ where
SendError::Unroutable
})?;

if max_target_fee.is_some() {
log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due not supporting max target fee.");
return Err(SendError::Unroutable)
}

// local_sub is relative to the relaychain. No conversion needed.
let local_sub_location: MultiLocation = local_sub.into();
let agent_id = match AgentHashedDescription::convert_location(&local_sub_location) {
Expand All @@ -135,9 +130,13 @@ where

log::info!(target: "xcm::ethereum_blob_exporter", "message validated: location = {local_sub_location:?}, agent_id = '{agent_id:?}'");

// TODO (SNO-581): Make sure we charge fees for message delivery. Currently this is set to
// zero.
Ok((ticket.encode(), MultiAssets::default()))
let mut fees = MultiAssets::new();
if max_target_fee.is_some() {
let fee = max_target_fee.unwrap();
fees.push((*fee).clone());
}

Ok((ticket.encode(), fees))
}

fn deliver(blob: Vec<u8>) -> Result<XcmHash, SendError> {
Expand Down
2 changes: 2 additions & 0 deletions smoketest/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub const ETHEREUM_API: &str = "ws://localhost:8546";
pub const ETHEREUM_HTTP_API: &str = "http://localhost:8545";
pub const BRIDGE_HUB_WS_URL: &str = "ws://127.0.0.1:11144";
pub const BRIDGE_HUB_PARA_ID: u32 = 1013;
pub const ASSET_HUB_WS_URL: &str = "ws://127.0.0.1:12144";

pub const TEMPLATE_NODE_WS_URL: &str = "ws://127.0.0.1:13144";

Expand All @@ -17,6 +18,7 @@ pub const ETHEREUM_ADDRESS: [u8; 20] = hex!("90A987B944Cb1dCcE5564e5FDeCD7a54D3d

// GatewayProxy in local setup
pub const GATEWAY_PROXY_CONTRACT: [u8; 20] = hex!("EDa338E4dC46038493b885327842fD3E301CaB39");
pub const WETH_CONTRACT: [u8; 20] = hex!("87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d");

// Agent for sibling parachain 1001
pub const SIBLING_AGENT_ID: [u8; 32] =
Expand Down
16 changes: 15 additions & 1 deletion smoketest/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::time::Duration;
use subxt::blocks::ExtrinsicEvents;
use subxt::events::StaticEvent;
use subxt::tx::{PairSigner, TxPayload};
use subxt::{Config, OnlineClient, PolkadotConfig};
use subxt::{Config, OnlineClient, PolkadotConfig, SubstrateConfig};
use templateXcm::{
v3::{junction::Junction, junctions::Junctions, multilocation::MultiLocation},
VersionedMultiLocation, VersionedXcm,
Expand All @@ -36,6 +36,20 @@ impl Config for TemplateConfig {
type ExtrinsicParams = <PolkadotConfig as Config>::ExtrinsicParams;
}

/// Custom config that works with Statemint
pub enum AssetHubConfig {}

impl Config for AssetHubConfig {
type Index = <PolkadotConfig as Config>::Index;
type Hash = <PolkadotConfig as Config>::Hash;
type AccountId = <PolkadotConfig as Config>::AccountId;
type Address = <PolkadotConfig as Config>::Address;
type Signature = <PolkadotConfig as Config>::Signature;
type Hasher = <PolkadotConfig as Config>::Hasher;
type Header = <PolkadotConfig as Config>::Header;
type ExtrinsicParams = <SubstrateConfig as Config>::ExtrinsicParams;
}

pub struct TestClients {
pub bridge_hub_client: Box<OnlineClient<PolkadotConfig>>,
pub template_client: Box<OnlineClient<TemplateConfig>>,
Expand Down
114 changes: 114 additions & 0 deletions smoketest/tests/transfer_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use ethers::{
providers::{Provider, Ws},
types::Address,
};
use std::{sync::Arc, time::Duration};
use ethers::prelude::Middleware;
use snowbridge_smoketest::contracts::weth9::WETH9;
use subxt::{
tx::{PairSigner},
OnlineClient, PolkadotConfig,
};
use snowbridge_smoketest::constants::{ASSET_HUB_WS_URL, ETHEREUM_API, GATEWAY_PROXY_CONTRACT, WETH_CONTRACT};
use sp_core::{sr25519::Pair, Pair as PairT};
use snowbridge_smoketest::{
contracts::weth9::{TransferFilter},
parachains::{
assethub::api::runtime_types::xcm::{
v3::{
junction::{Junction, NetworkId},
junctions::Junctions,
multiasset::{AssetId, Fungibility, MultiAsset, MultiAssets},
multilocation::MultiLocation,
},
VersionedMultiAssets, VersionedMultiLocation,
},
assethub::{self},
},
};
use hex_literal::hex;
use sp_core::bytes::to_hex;
use subxt::tx::TxPayload;
use assethub::api::bridge_transfer::calls::TransactionApi;
use futures::StreamExt;
use snowbridge_smoketest::helper::{AssetHubConfig, TemplateConfig};

const DESTINATION_ADDRESS: [u8; 20] = hex!("44a57ee2f2FCcb85FDa2B0B18EBD0D8D2333700e");

#[tokio::test]
async fn transfer_token() {
let ethereum_provider = Provider::<Ws>::connect(ETHEREUM_API)
.await
.unwrap()
.interval(Duration::from_millis(10u64));


let ethereum_client = Arc::new(ethereum_provider);

let weth_addr: Address = WETH_CONTRACT.into();
let weth = WETH9::new(weth_addr, ethereum_client.clone());

let assethub: OnlineClient<AssetHubConfig> =
OnlineClient::from_url(ASSET_HUB_WS_URL).await.unwrap();

let keypair: Pair = Pair::from_string("//Ferdie", None).expect("cannot create keypair");

let signer: PairSigner<AssetHubConfig, _> = PairSigner::new(keypair);

let amount: u128 = 1_000_000_000;
let assets = VersionedMultiAssets::V3(MultiAssets(vec![MultiAsset {
id: AssetId::Concrete(MultiLocation {
parents: 2,
interior: Junctions::X3(
Junction::GlobalConsensus(NetworkId::Ethereum { chain_id: 15 }),
Junction::AccountKey20 { network: None, key: GATEWAY_PROXY_CONTRACT.into() },
Junction::AccountKey20 { network: None, key: WETH_CONTRACT.into() },
),
}),
fun: Fungibility::Fungible(amount),
}]));

let destination = VersionedMultiLocation::V3(MultiLocation {
parents: 2,
interior: Junctions::X2(
Junction::GlobalConsensus(NetworkId::Ethereum { chain_id: 15 }),
Junction::AccountKey20 { network: None, key: DESTINATION_ADDRESS.into() },
),
});

let bridge_transfer_call = TransactionApi.transfer_asset_via_bridge(assets, destination);

let result = assethub
.tx()
.sign_and_submit_then_watch_default(&bridge_transfer_call, &signer)
.await
.expect("send through call.")
.wait_for_finalized_success()
.await
.expect("call success");

println!("bridge_transfer call issued at assethub block hash {:?}", result.block_hash());

let wait_for_blocks = 50;
let mut stream = ethereum_client.subscribe_blocks().await.unwrap().take(wait_for_blocks);

let mut transfer_event_found = false;
while let Some(block) = stream.next().await {
println!("Polling ethereum block {:?} for transfer event", block.number.unwrap());
if let Ok(transfers) =
weth.event::<TransferFilter>().at_block_hash(block.hash.unwrap()).query().await
{
for transfer in transfers {
println!("Transfer event found at ethereum block {:?}", block.number.unwrap());
assert_eq!(transfer.src, DESTINATION_ADDRESS.into());
assert_eq!(transfer.dst, DESTINATION_ADDRESS.into());
assert_eq!(transfer.wad, amount.into());
transfer_event_found = true;
}
}
if transfer_event_found {
break;
}
}
assert!(transfer_event_found);
}