Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Transact from eth to sub #114

Open
wants to merge 50 commits into
base: bridge-next-gen
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
d68c3d6
Fix for unit test
yrong Feb 14, 2024
307ecd6
Update for transact
yrong Feb 14, 2024
7c493bd
Penpal config for transact
yrong Feb 13, 2024
e55cfd1
Fix import
yrong Feb 14, 2024
45c3372
Fix taplo
yrong Feb 14, 2024
26df807
Fix for breaking emulated tests
yrong Feb 14, 2024
c4fe031
Remove unused
yrong Feb 14, 2024
51b76fe
Tranfer fees to BH for transact
yrong Feb 14, 2024
3ed7260
Remove the teleport config
yrong Feb 15, 2024
772fa46
Enable create agent/channel by xcm
yrong Feb 15, 2024
540a791
Refund surplus
yrong Feb 16, 2024
051b3b6
Fix format
yrong Feb 16, 2024
e523185
Replace hardcode value
yrong Feb 16, 2024
a8b8435
Leave to user to prefund sovereign account on the destination chain t…
yrong Feb 19, 2024
b10d19e
Update import path
yrong Feb 19, 2024
cbd2e19
Merge branch 'snowbridge' into transact-from-eth-to-sub
yrong Feb 20, 2024
e363918
Unit test for transact
yrong Feb 20, 2024
13217f1
DescendOrigin to inbound-queue first
yrong Feb 22, 2024
257e75d
Fix breaking test
yrong Feb 22, 2024
e03942a
First match RegisterToken or SendToken
yrong Feb 22, 2024
698a9e9
Remove deprecated
yrong Feb 22, 2024
9968a37
Use SetAppendix and refund surplus when transact fail
yrong Feb 22, 2024
40ea01a
Ignore parents which is meaningless for GlobalConsensus locations
yrong Feb 22, 2024
004afd2
Reuse weight type
yrong Feb 23, 2024
85d2c03
Update sender consistent with smoke test
yrong Feb 23, 2024
626ec76
Update Cargo.toml
yrong Feb 26, 2024
0686fcd
Fix breaking test
yrong Feb 26, 2024
7cc0d59
Improve tests
yrong Feb 26, 2024
050585c
Merge branch 'snowbridge' into transact-from-eth-to-sub
yrong Feb 28, 2024
ece8a96
Merge branch 'snowbridge' into transact-from-eth-to-sub
yrong Mar 6, 2024
7b916e5
Add TransactFeeMode
yrong Mar 6, 2024
15759a4
Improve convert logic
yrong Mar 6, 2024
04a339e
Fix UniversalLocation
yrong Mar 7, 2024
c18f771
AllowUnpaidExecutionFromSnowBridgeWithFeeChecked
yrong Mar 7, 2024
e49f077
Merge branch 'snowbridge' into transact-from-eth-to-sub
yrong Mar 19, 2024
362e414
Remove feeMode and fully charge all cost on Ethereum
yrong Mar 19, 2024
6fb78fe
Merge branch 'snowbridge' into transact-from-eth-to-sub
yrong Apr 11, 2024
9d0af91
Fix build error
yrong Apr 11, 2024
68abf04
Make network specific types as storage which can be changed
yrong Apr 11, 2024
76b01b2
Remove the fund steps unnecessary
yrong Apr 11, 2024
87ed097
Move Transact after Origin operations
yrong Apr 11, 2024
0ea24a4
Fix breaking test
yrong Apr 11, 2024
b85e362
Merge branch 'bridge-next-gen' into transact-from-eth-to-sub
yrong Apr 16, 2024
cd7a64a
Fix compile error
yrong Apr 16, 2024
966abdf
Use native token of destination chain to pay fee from a pre-funded so…
yrong Apr 17, 2024
1cab94c
Use native token or DOT based on whether its a system parachain or not
yrong Apr 22, 2024
5a22972
Make fee asset as configuration parameter of the Channel
yrong Apr 26, 2024
9829de7
Zero fee for transact
yrong Apr 28, 2024
2f30d46
Remove unused
yrong Apr 29, 2024
ee6bdc5
Deposit any left over fees back into the pre-funded account
yrong May 3, 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
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use sp_core::RuntimeDebug;

pub mod register_token;
pub mod register_token_with_insufficient_fee;
pub mod send_call_to_penpal;
pub mod send_token;
pub mod send_token_to_penpal;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
// Generated, do not edit!
// See ethereum client README.md for instructions to generate

use crate::InboundQueueFixture;
use hex_literal::hex;
use snowbridge_beacon_primitives::CompactExecutionHeader;
use snowbridge_core::inbound::{Log, Message, Proof};
use sp_std::vec;

pub fn make_send_call_to_penpal_message() -> InboundQueueFixture {
InboundQueueFixture {
execution_header: CompactExecutionHeader{
parent_hash: hex!("e0fa68ceff08e6f024c84f408540372801b209ff8f11481a9dc6bc5db3ce92d3").into(),
block_number: 831,
state_root: hex!("ccc30635f32d558620d45ead60eabbe70dbf179b475fa9cec5a3791fd5be2b78").into(),
receipts_root: hex!("6bba8f0093461e22cd265bc0de44bf7a596db58ecbf44432e6de8b3490deb077").into(),
},
message: Message {
event_log: Log {
address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(),
topics: vec![
hex!("7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f").into(),
hex!("a69fbbae90bb6096d59b1930bbcfc8a3ef23959d226b1861deb7ad8fb06c6fa3").into(),
hex!("c9ad11f6e2d2b770f52e7cbe22ba779eb8e5e000e0db4e5032488898bd3529ec").into(),
],
data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003e00a736aa00000000000290a987b944cb1dcce5564e5fdecd7a54d3de27fe0100902f5009000000000000000000000002688909017d2000071468656c6c6f0000").into(),
},
proof: Proof {
block_hash: hex!("be15f3cdf217baad8cc5c40d7e2dc1f173ab3bdaa58e5819905bb0c73f46cf78").into(),
tx_index: 0,
data: (vec![
hex!("6bba8f0093461e22cd265bc0de44bf7a596db58ecbf44432e6de8b3490deb077").to_vec(),
], vec![
hex!("f90234822080b9022e02f9022a0183016e01b9010000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000200000000000000000020000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000010000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002004000000000000000000000200000000000000f9011ff9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0a69fbbae90bb6096d59b1930bbcfc8a3ef23959d226b1861deb7ad8fb06c6fa3a0c9ad11f6e2d2b770f52e7cbe22ba779eb8e5e000e0db4e5032488898bd3529ecb8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000003e00a736aa00000000000290a987b944cb1dcce5564e5fdecd7a54d3de27fe0100902f5009000000000000000000000002688909017d2000071468656c6c6f0000").to_vec(),
]),
},
},
}
}
31 changes: 19 additions & 12 deletions bridges/snowbridge/pallets/inbound-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ use snowbridge_core::{
sibling_sovereign_account, BasicOperatingMode, Channel, ChannelId, ParaId, PricingParameters,
StaticLookup,
};
use snowbridge_router_primitives::{
inbound,
inbound::{ConvertMessage, ConvertMessageError},
use snowbridge_router_primitives::inbound::{
Command, ConvertMessage, ConvertMessageError, MessageV1, VersionedMessage,
};
use sp_runtime::{traits::Saturating, SaturatedConversion, TokenError};

Expand Down Expand Up @@ -276,12 +275,12 @@ pub mod pallet {
T::Token::transfer(&sovereign_account, &who, amount, Preservation::Preserve)?;
}

// Decode message into XCM
let (xcm, fee) =
match inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()) {
Ok(message) => Self::do_convert(envelope.message_id, message)?,
Err(_) => return Err(Error::<T>::InvalidPayload.into()),
};
// Decode payload into VersionMessage
let message = VersionedMessage::decode_all(&mut envelope.payload.as_ref())
.map_err(|_| Error::<T>::InvalidPayload)?;

// Convert VersionMessage to XCM
let (xcm, fee) = Self::do_convert(envelope.message_id, message.clone())?;

log::info!(
target: LOG_TARGET,
Expand All @@ -290,8 +289,16 @@ pub mod pallet {
fee
);

// Burning fees for teleport
Self::burn_fees(channel.para_id, fee)?;
match message {
// For RegisterToken|SendToken burning fees for teleport
VersionedMessage::V1(MessageV1 {
command: Command::RegisterToken { .. }, ..
}) |
VersionedMessage::V1(MessageV1 { command: Command::SendToken { .. }, .. }) =>
Self::burn_fees(channel.para_id, fee)?,
// For transact do nothing here and leave it to dest chain to pay for fees by sender
vgeddes marked this conversation as resolved.
Show resolved Hide resolved
VersionedMessage::V1(MessageV1 { command: Command::Transact { .. }, .. }) => (),
};

// Attempt to send XCM to a dest parachain
let message_id = Self::send_xcm(xcm, channel.para_id)?;
Expand Down Expand Up @@ -323,7 +330,7 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
pub fn do_convert(
message_id: H256,
message: inbound::VersionedMessage,
message: VersionedMessage,
) -> Result<(Xcm<()>, BalanceOf<T>), Error<T>> {
let (mut xcm, fee) =
T::MessageConverter::convert(message).map_err(|e| Error::<T>::ConvertMessage(e))?;
Expand Down
34 changes: 33 additions & 1 deletion bridges/snowbridge/pallets/inbound-queue/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
use super::*;

use frame_support::{assert_noop, assert_ok};
use frame_support::{assert_noop, assert_ok, weights::Weight};
use hex_literal::hex;
use snowbridge_core::{inbound::Proof, ChannelId};
use sp_keyring::AccountKeyring as Keyring;
use sp_runtime::DispatchError;
use sp_std::convert::From;
use xcm::prelude::{OriginKind, Transact};

use crate::{Error, Event as InboundQueueEvent};

Expand Down Expand Up @@ -251,3 +252,34 @@ fn test_submit_no_funds_to_reward_relayers_and_ed_preserved() {
assert_eq!(amount, ExistentialDeposit::get());
});
}

#[test]
fn test_convert_transact() {
new_tester().execute_with(|| {
let message_id: H256 = [1; 32].into();
let sender: H160 = hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into();
let fee: u128 = 40_000_000_000;
let weight_at_most = Weight::from_parts(40_000_000, 8_000);
let origin_kind = OriginKind::SovereignAccount;
let payload = hex!("00071468656c6c6f").to_vec();
let message = VersionedMessage::V1(MessageV1 {
chain_id: 11155111,
command: Command::Transact {
sender,
fee,
weight_at_most,
origin_kind,
payload: payload.clone(),
},
});
// Convert the message to XCM
let (xcm, dest_fee) = InboundQueue::do_convert(message_id, message).unwrap();
let instructions = xcm.into_inner();
assert_eq!(instructions.len(), 7);
assert_eq!(dest_fee, fee.into());
let transact = instructions.get(2).unwrap().clone();
let expected =
Transact { origin_kind, require_weight_at_most: weight_at_most, call: payload.into() };
assert_eq!(transact, expected);
});
}
2 changes: 1 addition & 1 deletion bridges/snowbridge/pallets/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ where
}

/// Hash the location to produce an agent id
fn agent_id_of<T: Config>(location: &Location) -> Result<H256, DispatchError> {
pub fn agent_id_of<T: Config>(location: &Location) -> Result<H256, DispatchError> {
T::AgentIdOf::convert_location(location).ok_or(Error::<T>::LocationConversionFailed.into())
}

Expand Down
51 changes: 51 additions & 0 deletions bridges/snowbridge/primitives/router/src/inbound/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ pub enum Command {
/// XCM execution fee on AssetHub
fee: u128,
},
/// call arbitrary transact on dest chain
Transact {
/// The address of the sender
sender: H160,
/// OriginKind
origin_kind: OriginKind,
/// XCM execution fee on dest chain
fee: u128,
/// The weight required at most on dest chain
weight_at_most: Weight,
/// The payload of the transact
payload: Vec<u8>,
},
}

/// Destination for bridged tokens
Expand Down Expand Up @@ -146,6 +159,17 @@ impl<CreateAssetCall, CreateAssetDeposit, InboundQueuePalletInstance, AccountId,
Ok(Self::convert_register_token(chain_id, token, fee)),
V1(MessageV1 { chain_id, command: SendToken { token, destination, amount, fee } }) =>
Ok(Self::convert_send_token(chain_id, token, destination, amount, fee)),
V1(MessageV1 {
chain_id,
command: Transact { sender, origin_kind, fee, weight_at_most, payload },
}) => Ok(Self::convert_transact(
chain_id,
sender,
origin_kind,
fee,
weight_at_most,
payload,
)),
}
}
}
Expand Down Expand Up @@ -289,6 +313,33 @@ where
[GlobalConsensus(network), AccountKey20 { network: None, key: token.into() }],
)
}

fn convert_transact(
chain_id: u64,
sender: H160,
origin_kind: OriginKind,
fee: u128,
weight_at_most: Weight,
payload: Vec<u8>,
) -> (Xcm<()>, Balance) {
let xcm_fee: Asset = (Location::parent(), fee).into();

let message = vec![
UnpaidExecution { weight_limit: Unlimited, check_origin: None },
// Actually BurnAsset does nothing on dest chain, included here only for
// the dest chain to implement a custom Barrier which inspect the fee as
// expected(i.e. can cover the transact cost to avoid spamming)
BurnAsset(xcm_fee.clone().into()),
claravanstaden marked this conversation as resolved.
Show resolved Hide resolved
Transact { origin_kind, require_weight_at_most: weight_at_most, call: payload.into() },
// Only our inbound-queue pallet is allowed to invoke `UniversalOrigin`
DescendOrigin(PalletInstance(InboundQueuePalletInstance::get()).into()),
// Change origin to the bridge.
UniversalOrigin(GlobalConsensus(Ethereum { chain_id })),
// DescendOrigin to the sender.
DescendOrigin(AccountKey20 { network: None, key: sender.into() }.into()),
];
(message.into(), fee.into())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return 0 as a fee here. The returned fee is meant to be burnt.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}

pub struct GlobalConsensusEthereumConvertsFor<AccountId>(PhantomData<AccountId>);
Expand Down
45 changes: 45 additions & 0 deletions bridges/snowbridge/templates/send_call_to_penpal.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
// Generated, do not edit!
// See ethereum client README.md for instructions to generate

use crate::InboundQueueFixture;
use hex_literal::hex;
use snowbridge_beacon_primitives::CompactExecutionHeader;
use snowbridge_core::inbound::{Log, Message, Proof};
use sp_std::vec;

pub fn make_send_call_to_penpal_message() -> InboundQueueFixture {
InboundQueueFixture {
execution_header: CompactExecutionHeader{
parent_hash: hex!("{{InboundMessageTest.ExecutionHeader.ParentHash}}").into(),
block_number: {{InboundMessageTest.ExecutionHeader.BlockNumber}},
state_root: hex!("{{InboundMessageTest.ExecutionHeader.StateRoot}}").into(),
receipts_root: hex!("{{InboundMessageTest.ExecutionHeader.ReceiptsRoot}}").into(),
},
message: Message {
event_log: Log {
address: hex!("{{InboundMessageTest.Message.EventLog.Address}}").into(),
topics: vec![
{{#InboundMessageTest.Message.EventLog.Topics}}
hex!("{{.}}").into(),
{{/InboundMessageTest.Message.EventLog.Topics}}
],
data: hex!("{{InboundMessageTest.Message.EventLog.Data}}").into(),
},
proof: Proof {
block_hash: hex!("{{InboundMessageTest.Message.Proof.BlockHash}}").into(),
tx_index: {{InboundMessageTest.Message.Proof.TxIndex}},
data: (vec![
{{#InboundMessageTest.Message.Proof.Data.Keys}}
hex!("{{.}}").to_vec(),
{{/InboundMessageTest.Message.Proof.Data.Keys}}
], vec![
{{#InboundMessageTest.Message.Proof.Data.Values}}
hex!("{{.}}").to_vec(),
{{/InboundMessageTest.Message.Proof.Data.Values}}
]),
},
},
}
}
45 changes: 45 additions & 0 deletions bridges/snowbridge/templates/send_token_to_penpal.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2023 Snowfork <[email protected]>
// Generated, do not edit!
// See ethereum client README.md for instructions to generate

use crate::InboundQueueFixture;
use hex_literal::hex;
use snowbridge_beacon_primitives::CompactExecutionHeader;
use snowbridge_core::inbound::{Log, Message, Proof};
use sp_std::vec;

pub fn make_send_token_to_penpal_message() -> InboundQueueFixture {
InboundQueueFixture {
execution_header: CompactExecutionHeader{
parent_hash: hex!("{{InboundMessageTest.ExecutionHeader.ParentHash}}").into(),
block_number: {{InboundMessageTest.ExecutionHeader.BlockNumber}},
state_root: hex!("{{InboundMessageTest.ExecutionHeader.StateRoot}}").into(),
receipts_root: hex!("{{InboundMessageTest.ExecutionHeader.ReceiptsRoot}}").into(),
},
message: Message {
event_log: Log {
address: hex!("{{InboundMessageTest.Message.EventLog.Address}}").into(),
topics: vec![
{{#InboundMessageTest.Message.EventLog.Topics}}
hex!("{{.}}").into(),
{{/InboundMessageTest.Message.EventLog.Topics}}
],
data: hex!("{{InboundMessageTest.Message.EventLog.Data}}").into(),
},
proof: Proof {
block_hash: hex!("{{InboundMessageTest.Message.Proof.BlockHash}}").into(),
tx_index: {{InboundMessageTest.Message.Proof.TxIndex}},
data: (vec![
{{#InboundMessageTest.Message.Proof.Data.Keys}}
hex!("{{.}}").to_vec(),
{{/InboundMessageTest.Message.Proof.Data.Keys}}
], vec![
{{#InboundMessageTest.Message.Proof.Data.Values}}
hex!("{{.}}").to_vec(),
{{/InboundMessageTest.Message.Proof.Data.Values}}
]),
},
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ workspace = true
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false }
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
hex-literal = "0.4.1"
hex = "0.4.3"

# Substrate
sp-core = { path = "../../../../../../../substrate/primitives/core", default-features = false }
frame-support = { path = "../../../../../../../substrate/frame/support", default-features = false }
frame-system = { path = "../../../../../../../substrate/frame/system", default-features = false }
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false }
pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false }
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false }
pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue" }
sp-runtime = { path = "../../../../../../../substrate/primitives/runtime", default-features = false }
sp-io = { path = "../../../../../../../substrate/primitives/io", default-features = false }

# Polkadot
xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false }
Expand Down
Loading
Loading