mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 18:41:03 +00:00
Integrate token swap pallet into Millau runtime (#1099)
* integrate token swap pallet into Millau runtime * set OnDeliveryConfirmed callback in Millau runtime
This commit is contained in:
committed by
Bastian Köcher
parent
71080f94df
commit
24bd2d6c51
@@ -23,6 +23,7 @@ bridge-runtime-common = { path = "../../runtime-common", default-features = fals
|
||||
pallet-bridge-dispatch = { path = "../../../modules/dispatch", default-features = false }
|
||||
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
|
||||
pallet-bridge-messages = { path = "../../../modules/messages", default-features = false }
|
||||
pallet-bridge-token-swap = { path = "../../../modules/token-swap", default-features = false }
|
||||
pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false }
|
||||
|
||||
# Substrate Dependencies
|
||||
@@ -77,6 +78,7 @@ std = [
|
||||
"pallet-bridge-dispatch/std",
|
||||
"pallet-bridge-grandpa/std",
|
||||
"pallet-bridge-messages/std",
|
||||
"pallet-bridge-token-swap/std",
|
||||
"pallet-grandpa/std",
|
||||
"pallet-randomness-collective-flip/std",
|
||||
"pallet-session/std",
|
||||
|
||||
@@ -362,7 +362,7 @@ parameter_types! {
|
||||
pub const GetDeliveryConfirmationTransactionFee: Balance =
|
||||
bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT as _;
|
||||
pub const RootAccountForPayments: Option<AccountId> = None;
|
||||
pub const BridgedChainId: bp_runtime::ChainId = bp_runtime::RIALTO_CHAIN_ID;
|
||||
pub const RialtoChainId: bp_runtime::ChainId = bp_runtime::RIALTO_CHAIN_ID;
|
||||
}
|
||||
|
||||
/// Instance of the messages pallet used to relay messages to/from Rialto chain.
|
||||
@@ -394,11 +394,31 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
|
||||
GetDeliveryConfirmationTransactionFee,
|
||||
RootAccountForPayments,
|
||||
>;
|
||||
type OnDeliveryConfirmed = ();
|
||||
type OnDeliveryConfirmed = pallet_bridge_token_swap::Pallet<Runtime, WithRialtoTokenSwapInstance>;
|
||||
|
||||
type SourceHeaderChain = crate::rialto_messages::Rialto;
|
||||
type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
|
||||
type BridgedChainId = BridgedChainId;
|
||||
type BridgedChainId = RialtoChainId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const TokenSwapMessagesLane: bp_messages::LaneId = *b"swap";
|
||||
}
|
||||
|
||||
/// Instance of the with-Rialto token swap pallet.
|
||||
pub type WithRialtoTokenSwapInstance = ();
|
||||
|
||||
impl pallet_bridge_token_swap::Config<WithRialtoTokenSwapInstance> for Runtime {
|
||||
type Event = Event;
|
||||
|
||||
type BridgedChainId = RialtoChainId;
|
||||
type OutboundMessageLaneId = TokenSwapMessagesLane;
|
||||
type MessagesBridge = pallet_bridge_messages::Pallet<Runtime, WithRialtoMessagesInstance>;
|
||||
type ThisCurrency = pallet_balances::Pallet<Runtime>;
|
||||
type FromSwapToThisAccountIdConverter = bp_rialto::AccountIdConverter;
|
||||
|
||||
type BridgedChain = bp_rialto::Rialto;
|
||||
type FromBridgedToThisAccountIdConverter = bp_millau::AccountIdConverter;
|
||||
}
|
||||
|
||||
construct_runtime!(
|
||||
@@ -407,20 +427,30 @@ construct_runtime!(
|
||||
NodeBlock = opaque::Block,
|
||||
UncheckedExtrinsic = UncheckedExtrinsic
|
||||
{
|
||||
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
|
||||
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event<T>},
|
||||
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
|
||||
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},
|
||||
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage},
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
||||
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||
|
||||
// Must be before session.
|
||||
Aura: pallet_aura::{Pallet, Config<T>},
|
||||
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event},
|
||||
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
|
||||
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||
|
||||
// Consensus support.
|
||||
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
||||
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event},
|
||||
ShiftSessionManager: pallet_shift_session_manager::{Pallet},
|
||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage},
|
||||
|
||||
// Rialto bridge modules.
|
||||
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
|
||||
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event<T>},
|
||||
BridgeRialtoMessages: pallet_bridge_messages::{Pallet, Call, Storage, Event<T>, Config<T>},
|
||||
BridgeRialtoTokenSwap: pallet_bridge_token_swap::{Pallet, Call, Storage, Event<T>},
|
||||
|
||||
// Westend bridge modules.
|
||||
BridgeWestendGrandpa: pallet_bridge_grandpa::<Instance1>::{Pallet, Call, Config<T>, Storage},
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ impl messages::ThisChainWithMessages for Millau {
|
||||
type Call = crate::Call;
|
||||
|
||||
fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
|
||||
*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1]
|
||||
*lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1] || *lane == crate::TokenSwapMessagesLane::get()
|
||||
}
|
||||
|
||||
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
|
||||
|
||||
@@ -56,7 +56,11 @@ use bp_messages::{
|
||||
};
|
||||
use bp_runtime::{ChainId, Size};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{fail, traits::Get, weights::PostDispatchInfo};
|
||||
use frame_support::{
|
||||
fail,
|
||||
traits::Get,
|
||||
weights::{Pays, PostDispatchInfo},
|
||||
};
|
||||
use frame_system::RawOrigin;
|
||||
use num_traits::{SaturatingAdd, Zero};
|
||||
use sp_runtime::traits::BadOrigin;
|
||||
@@ -241,94 +245,13 @@ pub mod pallet {
|
||||
payload: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
ensure_normal_operating_mode::<T, I>()?;
|
||||
let submitter = origin.into().map_err(|_| BadOrigin)?;
|
||||
|
||||
// initially, actual (post-dispatch) weight is equal to pre-dispatch weight
|
||||
let mut actual_weight = T::WeightInfo::send_message_weight(&payload);
|
||||
|
||||
// let's first check if message can be delivered to target chain
|
||||
T::TargetHeaderChain::verify_message(&payload).map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected by target chain: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::MessageRejectedByChainVerifier
|
||||
})?;
|
||||
|
||||
// now let's enforce any additional lane rules
|
||||
let mut lane = outbound_lane::<T, I>(lane_id);
|
||||
T::LaneMessageVerifier::verify_message(
|
||||
&submitter,
|
||||
&delivery_and_dispatch_fee,
|
||||
&lane_id,
|
||||
&lane.data(),
|
||||
&payload,
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected by lane verifier: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::MessageRejectedByLaneVerifier
|
||||
})?;
|
||||
|
||||
// let's withdraw delivery and dispatch fee from submitter
|
||||
T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee(
|
||||
&submitter,
|
||||
&delivery_and_dispatch_fee,
|
||||
&Self::relayer_fund_account_id(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected because submitter {:?} is unable to pay fee {:?}: {:?}",
|
||||
lane_id,
|
||||
submitter,
|
||||
delivery_and_dispatch_fee,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::FailedToWithdrawMessageFee
|
||||
})?;
|
||||
|
||||
// finally, save message in outbound storage and emit event
|
||||
let encoded_payload = payload.encode();
|
||||
let encoded_payload_len = encoded_payload.len();
|
||||
let nonce = lane.send_message(MessageData {
|
||||
payload: encoded_payload,
|
||||
fee: delivery_and_dispatch_fee,
|
||||
});
|
||||
|
||||
// message sender pays for pruning at most `MaxMessagesToPruneAtOnce` messages
|
||||
// the cost of pruning every message is roughly single db write
|
||||
// => lets refund sender if less than `MaxMessagesToPruneAtOnce` messages pruned
|
||||
let max_messages_to_prune = T::MaxMessagesToPruneAtOnce::get();
|
||||
let pruned_messages = lane.prune_messages(max_messages_to_prune);
|
||||
if let Some(extra_messages) = max_messages_to_prune.checked_sub(pruned_messages) {
|
||||
actual_weight = actual_weight.saturating_sub(T::DbWeight::get().writes(extra_messages));
|
||||
}
|
||||
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Accepted message {} to lane {:?}. Message size: {:?}",
|
||||
nonce,
|
||||
crate::send_message::<T, I>(
|
||||
origin.into().map_err(|_| BadOrigin)?,
|
||||
lane_id,
|
||||
encoded_payload_len,
|
||||
);
|
||||
|
||||
Self::deposit_event(Event::MessageAccepted(lane_id, nonce));
|
||||
|
||||
Ok(PostDispatchInfo {
|
||||
actual_weight: Some(actual_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
})
|
||||
payload,
|
||||
delivery_and_dispatch_fee,
|
||||
)
|
||||
.map(|sent_message| sent_message.post_dispatch_info)
|
||||
}
|
||||
|
||||
/// Pay additional fee for the message.
|
||||
@@ -899,6 +822,126 @@ pub mod storage_keys {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I> bp_messages::source_chain::MessagesBridge<T::AccountId, T::OutboundMessageFee, T::OutboundPayload>
|
||||
for Pallet<T, I>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
{
|
||||
type Error = sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>;
|
||||
|
||||
fn send_message(
|
||||
sender: bp_messages::source_chain::Sender<T::AccountId>,
|
||||
lane: LaneId,
|
||||
message: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> Result<MessageNonce, Self::Error> {
|
||||
crate::send_message::<T, I>(sender, lane, message, delivery_and_dispatch_fee)
|
||||
.map(|sent_message| sent_message.nonce)
|
||||
}
|
||||
}
|
||||
|
||||
/// Message that has been sent.
|
||||
struct SentMessage {
|
||||
/// Nonce of the message.
|
||||
pub nonce: MessageNonce,
|
||||
/// Post-dispatch call info.
|
||||
pub post_dispatch_info: PostDispatchInfo,
|
||||
}
|
||||
|
||||
/// Function that actually sends message.
|
||||
fn send_message<T: Config<I>, I: 'static>(
|
||||
submitter: bp_messages::source_chain::Sender<T::AccountId>,
|
||||
lane_id: LaneId,
|
||||
payload: T::OutboundPayload,
|
||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||
) -> sp_std::result::Result<SentMessage, sp_runtime::DispatchErrorWithPostInfo<PostDispatchInfo>> {
|
||||
ensure_normal_operating_mode::<T, I>()?;
|
||||
|
||||
// initially, actual (post-dispatch) weight is equal to pre-dispatch weight
|
||||
let mut actual_weight = T::WeightInfo::send_message_weight(&payload);
|
||||
|
||||
// let's first check if message can be delivered to target chain
|
||||
T::TargetHeaderChain::verify_message(&payload).map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected by target chain: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::MessageRejectedByChainVerifier
|
||||
})?;
|
||||
|
||||
// now let's enforce any additional lane rules
|
||||
let mut lane = outbound_lane::<T, I>(lane_id);
|
||||
T::LaneMessageVerifier::verify_message(&submitter, &delivery_and_dispatch_fee, &lane_id, &lane.data(), &payload)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected by lane verifier: {:?}",
|
||||
lane_id,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::MessageRejectedByLaneVerifier
|
||||
})?;
|
||||
|
||||
// let's withdraw delivery and dispatch fee from submitter
|
||||
T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee(
|
||||
&submitter,
|
||||
&delivery_and_dispatch_fee,
|
||||
&Pallet::<T, I>::relayer_fund_account_id(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Message to lane {:?} is rejected because submitter {:?} is unable to pay fee {:?}: {:?}",
|
||||
lane_id,
|
||||
submitter,
|
||||
delivery_and_dispatch_fee,
|
||||
err,
|
||||
);
|
||||
|
||||
Error::<T, I>::FailedToWithdrawMessageFee
|
||||
})?;
|
||||
|
||||
// finally, save message in outbound storage and emit event
|
||||
let encoded_payload = payload.encode();
|
||||
let encoded_payload_len = encoded_payload.len();
|
||||
let nonce = lane.send_message(MessageData {
|
||||
payload: encoded_payload,
|
||||
fee: delivery_and_dispatch_fee,
|
||||
});
|
||||
|
||||
// message sender pays for pruning at most `MaxMessagesToPruneAtOnce` messages
|
||||
// the cost of pruning every message is roughly single db write
|
||||
// => lets refund sender if less than `MaxMessagesToPruneAtOnce` messages pruned
|
||||
let max_messages_to_prune = T::MaxMessagesToPruneAtOnce::get();
|
||||
let pruned_messages = lane.prune_messages(max_messages_to_prune);
|
||||
if let Some(extra_messages) = max_messages_to_prune.checked_sub(pruned_messages) {
|
||||
actual_weight = actual_weight.saturating_sub(T::DbWeight::get().writes(extra_messages));
|
||||
}
|
||||
|
||||
log::trace!(
|
||||
target: "runtime::bridge-messages",
|
||||
"Accepted message {} to lane {:?}. Message size: {:?}",
|
||||
nonce,
|
||||
lane_id,
|
||||
encoded_payload_len,
|
||||
);
|
||||
|
||||
Pallet::<T, I>::deposit_event(Event::MessageAccepted(lane_id, nonce));
|
||||
|
||||
Ok(SentMessage {
|
||||
nonce,
|
||||
post_dispatch_info: PostDispatchInfo {
|
||||
actual_weight: Some(actual_weight),
|
||||
pays_fee: Pays::Yes,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/// Ensure that the origin is either root, or `PalletOwner`.
|
||||
fn ensure_owner_or_root<T: Config<I>, I: 'static>(origin: T::Origin) -> Result<(), BadOrigin> {
|
||||
match origin.into() {
|
||||
|
||||
@@ -26,7 +26,7 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "mast
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
//! While swap is pending, the `source_balance_at_this_chain` tokens are owned by the special
|
||||
//! temporary `swap_account_at_this_chain` account. It is destroyed upon swap completion.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use bp_messages::{
|
||||
source_chain::{MessagesBridge, OnDeliveryConfirmed},
|
||||
DeliveredMessages, LaneId, MessageNonce,
|
||||
@@ -64,6 +66,7 @@ use frame_support::{
|
||||
use sp_core::H256;
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_runtime::traits::{Convert, Saturating};
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
@@ -98,7 +101,7 @@ pub mod pallet {
|
||||
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
|
||||
|
||||
/// Id of the bridge with the Bridged chain.
|
||||
type BridgeChainId: Get<ChainId>;
|
||||
type BridgedChainId: Get<ChainId>;
|
||||
/// The identifier of outbound message lane on This chain used to send token transfer
|
||||
/// messages to the Bridged chain.
|
||||
///
|
||||
@@ -114,8 +117,6 @@ pub mod pallet {
|
||||
<Self::ThisCurrency as Currency<Self::AccountId>>::Balance,
|
||||
MessagePayloadOf<Self, I>,
|
||||
>;
|
||||
/// Message delivery and dispatch fee for the tokens transfer message heading to the Bridged chain.
|
||||
type MessageDeliveryAndDispatchFee: Get<<Self::ThisCurrency as Currency<Self::AccountId>>::Balance>;
|
||||
|
||||
/// This chain Currency used in the tokens swap.
|
||||
type ThisCurrency: Currency<Self::AccountId>;
|
||||
@@ -128,6 +129,10 @@ pub mod pallet {
|
||||
type FromBridgedToThisAccountIdConverter: Convert<H256, Self::AccountId>;
|
||||
}
|
||||
|
||||
/// Tokens balance at This chain.
|
||||
pub type ThisChainBalance<T, I> =
|
||||
<<T as Config<I>>::ThisCurrency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
/// Type of the Bridged chain.
|
||||
pub type BridgedChainOf<T, I> = <T as Config<I>>::BridgedChain;
|
||||
/// Tokens balance type at the Bridged chain.
|
||||
@@ -151,7 +156,7 @@ pub mod pallet {
|
||||
/// Type of `TokenSwap` used by the pallet.
|
||||
pub type TokenSwapOf<T, I> = TokenSwap<
|
||||
BlockNumberFor<T>,
|
||||
<<T as Config<I>>::ThisCurrency as Currency<<T as frame_system::Config>::AccountId>>::Balance,
|
||||
ThisChainBalance<T, I>,
|
||||
<T as frame_system::Config>::AccountId,
|
||||
BridgedBalanceOf<T, I>,
|
||||
BridgedAccountIdOf<T, I>,
|
||||
@@ -203,6 +208,7 @@ pub mod pallet {
|
||||
origin: OriginFor<T>,
|
||||
swap: TokenSwapOf<T, I>,
|
||||
target_public_at_bridged_chain: BridgedAccountPublicOf<T, I>,
|
||||
swap_delivery_and_dispatch_fee: ThisChainBalance<T, I>,
|
||||
bridged_chain_spec_version: u32,
|
||||
bridged_currency_transfer: RawBridgedTransferCall,
|
||||
bridged_currency_transfer_weight: Weight,
|
||||
@@ -239,13 +245,12 @@ pub mod pallet {
|
||||
let swap_account = swap_account_id::<T, I>(&swap);
|
||||
frame_support::storage::with_transaction(|| {
|
||||
// funds are transferred from This account to the temporary Swap account
|
||||
let message_delivery_and_dispatch_fee = T::MessageDeliveryAndDispatchFee::get();
|
||||
let transfer_result = T::ThisCurrency::transfer(
|
||||
&swap.source_account_at_this_chain,
|
||||
&swap_account,
|
||||
// saturating_add is ok, or we have the chain where single holder owns all tokens
|
||||
swap.source_balance_at_this_chain
|
||||
.saturating_add(message_delivery_and_dispatch_fee),
|
||||
.saturating_add(swap_delivery_and_dispatch_fee),
|
||||
// if we'll allow account to die, then he'll be unable to `cancel_claim`
|
||||
// if something won't work
|
||||
ExistenceRequirement::KeepAlive,
|
||||
@@ -268,7 +273,7 @@ pub mod pallet {
|
||||
// `Currency::transfer` call on the bridged chain, but no checks are made - it is
|
||||
// the transaction submitter to ensure it is valid.
|
||||
let send_message_result = T::MessagesBridge::send_message(
|
||||
swap_account.clone(),
|
||||
bp_messages::source_chain::Sender::from(Some(swap_account.clone())),
|
||||
T::OutboundMessageLaneId::get(),
|
||||
bp_message_dispatch::MessagePayload {
|
||||
spec_version: bridged_chain_spec_version,
|
||||
@@ -281,7 +286,7 @@ pub mod pallet {
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
call: bridged_currency_transfer,
|
||||
},
|
||||
message_delivery_and_dispatch_fee,
|
||||
swap_delivery_and_dispatch_fee,
|
||||
);
|
||||
let transfer_message_nonce = match send_message_result {
|
||||
Ok(transfer_message_nonce) => transfer_message_nonce,
|
||||
@@ -493,7 +498,7 @@ pub mod pallet {
|
||||
/// Expected target account representation on This chain (aka `target_account_at_this_chain`).
|
||||
pub(crate) fn target_account_at_this_chain<T: Config<I>, I: 'static>(swap: &TokenSwapOf<T, I>) -> T::AccountId {
|
||||
T::FromBridgedToThisAccountIdConverter::convert(bp_runtime::derive_account_id(
|
||||
T::BridgeChainId::get(),
|
||||
T::BridgedChainId::get(),
|
||||
bp_runtime::SourceAccount::Account(swap.target_account_at_bridged_chain.clone()),
|
||||
))
|
||||
}
|
||||
@@ -584,6 +589,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -606,6 +612,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT + 1),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -626,6 +633,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
swap,
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -646,6 +654,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
swap,
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -666,6 +675,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
transfer,
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -683,6 +693,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -694,6 +705,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -713,6 +725,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -731,6 +744,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -749,6 +763,7 @@ mod tests {
|
||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||
test_swap(),
|
||||
bridged_chain_account_public(),
|
||||
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
BRIDGED_CHAIN_SPEC_VERSION,
|
||||
test_transfer(),
|
||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||
@@ -763,7 +778,7 @@ mod tests {
|
||||
assert_eq!(PendingMessages::<TestRuntime>::get(MESSAGE_NONCE), Some(swap_hash));
|
||||
assert_eq!(
|
||||
pallet_balances::Pallet::<TestRuntime>::free_balance(&swap_account_id::<TestRuntime, ()>(&test_swap())),
|
||||
test_swap().source_balance_at_this_chain + MessageDeliveryAndDispatchFee::get(),
|
||||
test_swap().source_balance_at_this_chain + SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
);
|
||||
assert!(
|
||||
frame_system::Pallet::<TestRuntime>::events()
|
||||
@@ -989,7 +1004,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
pallet_balances::Pallet::<TestRuntime>::free_balance(&THIS_CHAIN_ACCOUNT),
|
||||
THIS_CHAIN_ACCOUNT_BALANCE - MessageDeliveryAndDispatchFee::get(),
|
||||
THIS_CHAIN_ACCOUNT_BALANCE - SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||
);
|
||||
assert!(
|
||||
frame_system::Pallet::<TestRuntime>::events()
|
||||
|
||||
@@ -43,6 +43,8 @@ pub const MESSAGE_NONCE: MessageNonce = 3;
|
||||
pub const THIS_CHAIN_ACCOUNT: AccountId = 1;
|
||||
pub const THIS_CHAIN_ACCOUNT_BALANCE: Balance = 100_000;
|
||||
|
||||
pub const SWAP_DELIVERY_AND_DISPATCH_FEE: Balance = 1;
|
||||
|
||||
frame_support::construct_runtime! {
|
||||
pub enum TestRuntime where
|
||||
Block = Block,
|
||||
@@ -106,18 +108,16 @@ impl pallet_balances::Config for TestRuntime {
|
||||
}
|
||||
|
||||
frame_support::parameter_types! {
|
||||
pub const BridgeChainId: ChainId = *b"inst";
|
||||
pub const BridgedChainId: ChainId = *b"inst";
|
||||
pub const OutboundMessageLaneId: LaneId = *b"lane";
|
||||
pub const MessageDeliveryAndDispatchFee: Balance = 1;
|
||||
}
|
||||
|
||||
impl pallet_bridge_token_swap::Config for TestRuntime {
|
||||
type Event = Event;
|
||||
|
||||
type BridgeChainId = BridgeChainId;
|
||||
type BridgedChainId = BridgedChainId;
|
||||
type OutboundMessageLaneId = OutboundMessageLaneId;
|
||||
type MessagesBridge = TestMessagesBridge;
|
||||
type MessageDeliveryAndDispatchFee = MessageDeliveryAndDispatchFee;
|
||||
|
||||
type ThisCurrency = pallet_balances::Pallet<TestRuntime>;
|
||||
type FromSwapToThisAccountIdConverter = TestAccountConverter;
|
||||
@@ -146,14 +146,14 @@ impl MessagesBridge<AccountId, Balance, MessagePayloadOf<TestRuntime, ()>> for T
|
||||
type Error = ();
|
||||
|
||||
fn send_message(
|
||||
sender: AccountId,
|
||||
sender: frame_system::RawOrigin<AccountId>,
|
||||
lane: LaneId,
|
||||
message: MessagePayloadOf<TestRuntime, ()>,
|
||||
delivery_and_dispatch_fee: Balance,
|
||||
) -> Result<MessageNonce, Self::Error> {
|
||||
assert_ne!(sender, THIS_CHAIN_ACCOUNT);
|
||||
assert_ne!(sender, frame_system::RawOrigin::Signed(THIS_CHAIN_ACCOUNT));
|
||||
assert_eq!(lane, OutboundMessageLaneId::get());
|
||||
assert_eq!(delivery_and_dispatch_fee, MessageDeliveryAndDispatchFee::get());
|
||||
assert_eq!(delivery_and_dispatch_fee, SWAP_DELIVERY_AND_DISPATCH_FEE);
|
||||
match message.call[0] {
|
||||
OK_TRANSFER_CALL => Ok(MESSAGE_NONCE),
|
||||
BAD_TRANSFER_CALL => Err(()),
|
||||
|
||||
@@ -136,7 +136,7 @@ pub trait MessagesBridge<AccountId, Balance, Payload> {
|
||||
///
|
||||
/// Returns unique message nonce or error if send has failed.
|
||||
fn send_message(
|
||||
sender: AccountId,
|
||||
sender: Sender<AccountId>,
|
||||
lane: LaneId,
|
||||
message: Payload,
|
||||
delivery_and_dispatch_fee: Balance,
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::RuntimeDebug;
|
||||
use sp_core::U256;
|
||||
|
||||
@@ -102,6 +102,6 @@ mod tests {
|
||||
let hex = encode_message.encode().unwrap();
|
||||
|
||||
// then
|
||||
assert_eq!(format!("{:?}", hex), "0x01000000b0d60f000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c040130000000000000000000000000");
|
||||
assert_eq!(format!("{:?}", hex), "0x01000000b0d60f000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c000130000000000000000000000000");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ mod tests {
|
||||
weight: 1038000,
|
||||
origin: CallOrigin::SourceAccount(sp_keyring::AccountKeyring::Alice.to_account_id()),
|
||||
dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtSourceChain,
|
||||
call: hex!("0401081234").to_vec(),
|
||||
call: hex!("0001081234").to_vec(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user