mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +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-dispatch = { path = "../../../modules/dispatch", default-features = false }
|
||||||
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
|
pallet-bridge-grandpa = { path = "../../../modules/grandpa", default-features = false }
|
||||||
pallet-bridge-messages = { path = "../../../modules/messages", 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 }
|
pallet-shift-session-manager = { path = "../../../modules/shift-session-manager", default-features = false }
|
||||||
|
|
||||||
# Substrate Dependencies
|
# Substrate Dependencies
|
||||||
@@ -77,6 +78,7 @@ std = [
|
|||||||
"pallet-bridge-dispatch/std",
|
"pallet-bridge-dispatch/std",
|
||||||
"pallet-bridge-grandpa/std",
|
"pallet-bridge-grandpa/std",
|
||||||
"pallet-bridge-messages/std",
|
"pallet-bridge-messages/std",
|
||||||
|
"pallet-bridge-token-swap/std",
|
||||||
"pallet-grandpa/std",
|
"pallet-grandpa/std",
|
||||||
"pallet-randomness-collective-flip/std",
|
"pallet-randomness-collective-flip/std",
|
||||||
"pallet-session/std",
|
"pallet-session/std",
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ parameter_types! {
|
|||||||
pub const GetDeliveryConfirmationTransactionFee: Balance =
|
pub const GetDeliveryConfirmationTransactionFee: Balance =
|
||||||
bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT as _;
|
bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT as _;
|
||||||
pub const RootAccountForPayments: Option<AccountId> = None;
|
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.
|
/// 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,
|
GetDeliveryConfirmationTransactionFee,
|
||||||
RootAccountForPayments,
|
RootAccountForPayments,
|
||||||
>;
|
>;
|
||||||
type OnDeliveryConfirmed = ();
|
type OnDeliveryConfirmed = pallet_bridge_token_swap::Pallet<Runtime, WithRialtoTokenSwapInstance>;
|
||||||
|
|
||||||
type SourceHeaderChain = crate::rialto_messages::Rialto;
|
type SourceHeaderChain = crate::rialto_messages::Rialto;
|
||||||
type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
|
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!(
|
construct_runtime!(
|
||||||
@@ -407,20 +427,30 @@ construct_runtime!(
|
|||||||
NodeBlock = opaque::Block,
|
NodeBlock = opaque::Block,
|
||||||
UncheckedExtrinsic = UncheckedExtrinsic
|
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>},
|
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
|
||||||
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage},
|
Sudo: pallet_sudo::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
|
|
||||||
|
// Must be before session.
|
||||||
Aura: pallet_aura::{Pallet, Config<T>},
|
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>},
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
|
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>},
|
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
|
||||||
|
Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event},
|
||||||
ShiftSessionManager: pallet_shift_session_manager::{Pallet},
|
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;
|
type Call = crate::Call;
|
||||||
|
|
||||||
fn is_outbound_lane_enabled(lane: &LaneId) -> bool {
|
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 {
|
fn maximal_pending_messages_at_outbound_lane() -> MessageNonce {
|
||||||
|
|||||||
@@ -56,7 +56,11 @@ use bp_messages::{
|
|||||||
};
|
};
|
||||||
use bp_runtime::{ChainId, Size};
|
use bp_runtime::{ChainId, Size};
|
||||||
use codec::{Decode, Encode};
|
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 frame_system::RawOrigin;
|
||||||
use num_traits::{SaturatingAdd, Zero};
|
use num_traits::{SaturatingAdd, Zero};
|
||||||
use sp_runtime::traits::BadOrigin;
|
use sp_runtime::traits::BadOrigin;
|
||||||
@@ -241,94 +245,13 @@ pub mod pallet {
|
|||||||
payload: T::OutboundPayload,
|
payload: T::OutboundPayload,
|
||||||
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
delivery_and_dispatch_fee: T::OutboundMessageFee,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
ensure_normal_operating_mode::<T, I>()?;
|
crate::send_message::<T, I>(
|
||||||
let submitter = origin.into().map_err(|_| BadOrigin)?;
|
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,
|
lane_id,
|
||||||
err,
|
payload,
|
||||||
);
|
|
||||||
|
|
||||||
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,
|
delivery_and_dispatch_fee,
|
||||||
err,
|
)
|
||||||
);
|
.map(|sent_message| sent_message.post_dispatch_info)
|
||||||
|
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self::deposit_event(Event::MessageAccepted(lane_id, nonce));
|
|
||||||
|
|
||||||
Ok(PostDispatchInfo {
|
|
||||||
actual_weight: Some(actual_weight),
|
|
||||||
pays_fee: Pays::Yes,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pay additional fee for the message.
|
/// 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`.
|
/// Ensure that the origin is either root, or `PalletOwner`.
|
||||||
fn ensure_owner_or_root<T: Config<I>, I: 'static>(origin: T::Origin) -> Result<(), BadOrigin> {
|
fn ensure_owner_or_root<T: Config<I>, I: 'static>(origin: T::Origin) -> Result<(), BadOrigin> {
|
||||||
match origin.into() {
|
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-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-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-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]
|
[dev-dependencies]
|
||||||
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
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
|
//! 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.
|
//! temporary `swap_account_at_this_chain` account. It is destroyed upon swap completion.
|
||||||
|
|
||||||
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use bp_messages::{
|
use bp_messages::{
|
||||||
source_chain::{MessagesBridge, OnDeliveryConfirmed},
|
source_chain::{MessagesBridge, OnDeliveryConfirmed},
|
||||||
DeliveredMessages, LaneId, MessageNonce,
|
DeliveredMessages, LaneId, MessageNonce,
|
||||||
@@ -64,6 +66,7 @@ use frame_support::{
|
|||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
use sp_io::hashing::blake2_256;
|
use sp_io::hashing::blake2_256;
|
||||||
use sp_runtime::traits::{Convert, Saturating};
|
use sp_runtime::traits::{Convert, Saturating};
|
||||||
|
use sp_std::vec::Vec;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod mock;
|
mod mock;
|
||||||
@@ -98,7 +101,7 @@ pub mod pallet {
|
|||||||
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
|
type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
|
||||||
|
|
||||||
/// Id of the bridge with the Bridged chain.
|
/// 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
|
/// The identifier of outbound message lane on This chain used to send token transfer
|
||||||
/// messages to the Bridged chain.
|
/// messages to the Bridged chain.
|
||||||
///
|
///
|
||||||
@@ -114,8 +117,6 @@ pub mod pallet {
|
|||||||
<Self::ThisCurrency as Currency<Self::AccountId>>::Balance,
|
<Self::ThisCurrency as Currency<Self::AccountId>>::Balance,
|
||||||
MessagePayloadOf<Self, I>,
|
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.
|
/// This chain Currency used in the tokens swap.
|
||||||
type ThisCurrency: Currency<Self::AccountId>;
|
type ThisCurrency: Currency<Self::AccountId>;
|
||||||
@@ -128,6 +129,10 @@ pub mod pallet {
|
|||||||
type FromBridgedToThisAccountIdConverter: Convert<H256, Self::AccountId>;
|
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.
|
/// Type of the Bridged chain.
|
||||||
pub type BridgedChainOf<T, I> = <T as Config<I>>::BridgedChain;
|
pub type BridgedChainOf<T, I> = <T as Config<I>>::BridgedChain;
|
||||||
/// Tokens balance type at the Bridged chain.
|
/// Tokens balance type at the Bridged chain.
|
||||||
@@ -151,7 +156,7 @@ pub mod pallet {
|
|||||||
/// Type of `TokenSwap` used by the pallet.
|
/// Type of `TokenSwap` used by the pallet.
|
||||||
pub type TokenSwapOf<T, I> = TokenSwap<
|
pub type TokenSwapOf<T, I> = TokenSwap<
|
||||||
BlockNumberFor<T>,
|
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,
|
<T as frame_system::Config>::AccountId,
|
||||||
BridgedBalanceOf<T, I>,
|
BridgedBalanceOf<T, I>,
|
||||||
BridgedAccountIdOf<T, I>,
|
BridgedAccountIdOf<T, I>,
|
||||||
@@ -203,6 +208,7 @@ pub mod pallet {
|
|||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
swap: TokenSwapOf<T, I>,
|
swap: TokenSwapOf<T, I>,
|
||||||
target_public_at_bridged_chain: BridgedAccountPublicOf<T, I>,
|
target_public_at_bridged_chain: BridgedAccountPublicOf<T, I>,
|
||||||
|
swap_delivery_and_dispatch_fee: ThisChainBalance<T, I>,
|
||||||
bridged_chain_spec_version: u32,
|
bridged_chain_spec_version: u32,
|
||||||
bridged_currency_transfer: RawBridgedTransferCall,
|
bridged_currency_transfer: RawBridgedTransferCall,
|
||||||
bridged_currency_transfer_weight: Weight,
|
bridged_currency_transfer_weight: Weight,
|
||||||
@@ -239,13 +245,12 @@ pub mod pallet {
|
|||||||
let swap_account = swap_account_id::<T, I>(&swap);
|
let swap_account = swap_account_id::<T, I>(&swap);
|
||||||
frame_support::storage::with_transaction(|| {
|
frame_support::storage::with_transaction(|| {
|
||||||
// funds are transferred from This account to the temporary Swap account
|
// 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(
|
let transfer_result = T::ThisCurrency::transfer(
|
||||||
&swap.source_account_at_this_chain,
|
&swap.source_account_at_this_chain,
|
||||||
&swap_account,
|
&swap_account,
|
||||||
// saturating_add is ok, or we have the chain where single holder owns all tokens
|
// saturating_add is ok, or we have the chain where single holder owns all tokens
|
||||||
swap.source_balance_at_this_chain
|
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 we'll allow account to die, then he'll be unable to `cancel_claim`
|
||||||
// if something won't work
|
// if something won't work
|
||||||
ExistenceRequirement::KeepAlive,
|
ExistenceRequirement::KeepAlive,
|
||||||
@@ -268,7 +273,7 @@ pub mod pallet {
|
|||||||
// `Currency::transfer` call on the bridged chain, but no checks are made - it is
|
// `Currency::transfer` call on the bridged chain, but no checks are made - it is
|
||||||
// the transaction submitter to ensure it is valid.
|
// the transaction submitter to ensure it is valid.
|
||||||
let send_message_result = T::MessagesBridge::send_message(
|
let send_message_result = T::MessagesBridge::send_message(
|
||||||
swap_account.clone(),
|
bp_messages::source_chain::Sender::from(Some(swap_account.clone())),
|
||||||
T::OutboundMessageLaneId::get(),
|
T::OutboundMessageLaneId::get(),
|
||||||
bp_message_dispatch::MessagePayload {
|
bp_message_dispatch::MessagePayload {
|
||||||
spec_version: bridged_chain_spec_version,
|
spec_version: bridged_chain_spec_version,
|
||||||
@@ -281,7 +286,7 @@ pub mod pallet {
|
|||||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||||
call: bridged_currency_transfer,
|
call: bridged_currency_transfer,
|
||||||
},
|
},
|
||||||
message_delivery_and_dispatch_fee,
|
swap_delivery_and_dispatch_fee,
|
||||||
);
|
);
|
||||||
let transfer_message_nonce = match send_message_result {
|
let transfer_message_nonce = match send_message_result {
|
||||||
Ok(transfer_message_nonce) => transfer_message_nonce,
|
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`).
|
/// 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 {
|
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::FromBridgedToThisAccountIdConverter::convert(bp_runtime::derive_account_id(
|
||||||
T::BridgeChainId::get(),
|
T::BridgedChainId::get(),
|
||||||
bp_runtime::SourceAccount::Account(swap.target_account_at_bridged_chain.clone()),
|
bp_runtime::SourceAccount::Account(swap.target_account_at_bridged_chain.clone()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -584,6 +589,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -606,6 +612,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT + 1),
|
Origin::signed(THIS_CHAIN_ACCOUNT + 1),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -626,6 +633,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
swap,
|
swap,
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -646,6 +654,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
swap,
|
swap,
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -666,6 +675,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
transfer,
|
transfer,
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -683,6 +693,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -694,6 +705,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -713,6 +725,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -731,6 +744,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -749,6 +763,7 @@ mod tests {
|
|||||||
Origin::signed(THIS_CHAIN_ACCOUNT),
|
Origin::signed(THIS_CHAIN_ACCOUNT),
|
||||||
test_swap(),
|
test_swap(),
|
||||||
bridged_chain_account_public(),
|
bridged_chain_account_public(),
|
||||||
|
SWAP_DELIVERY_AND_DISPATCH_FEE,
|
||||||
BRIDGED_CHAIN_SPEC_VERSION,
|
BRIDGED_CHAIN_SPEC_VERSION,
|
||||||
test_transfer(),
|
test_transfer(),
|
||||||
BRIDGED_CHAIN_CALL_WEIGHT,
|
BRIDGED_CHAIN_CALL_WEIGHT,
|
||||||
@@ -763,7 +778,7 @@ mod tests {
|
|||||||
assert_eq!(PendingMessages::<TestRuntime>::get(MESSAGE_NONCE), Some(swap_hash));
|
assert_eq!(PendingMessages::<TestRuntime>::get(MESSAGE_NONCE), Some(swap_hash));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet_balances::Pallet::<TestRuntime>::free_balance(&swap_account_id::<TestRuntime, ()>(&test_swap())),
|
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!(
|
assert!(
|
||||||
frame_system::Pallet::<TestRuntime>::events()
|
frame_system::Pallet::<TestRuntime>::events()
|
||||||
@@ -989,7 +1004,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
pallet_balances::Pallet::<TestRuntime>::free_balance(&THIS_CHAIN_ACCOUNT),
|
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!(
|
assert!(
|
||||||
frame_system::Pallet::<TestRuntime>::events()
|
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: AccountId = 1;
|
||||||
pub const THIS_CHAIN_ACCOUNT_BALANCE: Balance = 100_000;
|
pub const THIS_CHAIN_ACCOUNT_BALANCE: Balance = 100_000;
|
||||||
|
|
||||||
|
pub const SWAP_DELIVERY_AND_DISPATCH_FEE: Balance = 1;
|
||||||
|
|
||||||
frame_support::construct_runtime! {
|
frame_support::construct_runtime! {
|
||||||
pub enum TestRuntime where
|
pub enum TestRuntime where
|
||||||
Block = Block,
|
Block = Block,
|
||||||
@@ -106,18 +108,16 @@ impl pallet_balances::Config for TestRuntime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frame_support::parameter_types! {
|
frame_support::parameter_types! {
|
||||||
pub const BridgeChainId: ChainId = *b"inst";
|
pub const BridgedChainId: ChainId = *b"inst";
|
||||||
pub const OutboundMessageLaneId: LaneId = *b"lane";
|
pub const OutboundMessageLaneId: LaneId = *b"lane";
|
||||||
pub const MessageDeliveryAndDispatchFee: Balance = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl pallet_bridge_token_swap::Config for TestRuntime {
|
impl pallet_bridge_token_swap::Config for TestRuntime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
|
|
||||||
type BridgeChainId = BridgeChainId;
|
type BridgedChainId = BridgedChainId;
|
||||||
type OutboundMessageLaneId = OutboundMessageLaneId;
|
type OutboundMessageLaneId = OutboundMessageLaneId;
|
||||||
type MessagesBridge = TestMessagesBridge;
|
type MessagesBridge = TestMessagesBridge;
|
||||||
type MessageDeliveryAndDispatchFee = MessageDeliveryAndDispatchFee;
|
|
||||||
|
|
||||||
type ThisCurrency = pallet_balances::Pallet<TestRuntime>;
|
type ThisCurrency = pallet_balances::Pallet<TestRuntime>;
|
||||||
type FromSwapToThisAccountIdConverter = TestAccountConverter;
|
type FromSwapToThisAccountIdConverter = TestAccountConverter;
|
||||||
@@ -146,14 +146,14 @@ impl MessagesBridge<AccountId, Balance, MessagePayloadOf<TestRuntime, ()>> for T
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn send_message(
|
fn send_message(
|
||||||
sender: AccountId,
|
sender: frame_system::RawOrigin<AccountId>,
|
||||||
lane: LaneId,
|
lane: LaneId,
|
||||||
message: MessagePayloadOf<TestRuntime, ()>,
|
message: MessagePayloadOf<TestRuntime, ()>,
|
||||||
delivery_and_dispatch_fee: Balance,
|
delivery_and_dispatch_fee: Balance,
|
||||||
) -> Result<MessageNonce, Self::Error> {
|
) -> 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!(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] {
|
match message.call[0] {
|
||||||
OK_TRANSFER_CALL => Ok(MESSAGE_NONCE),
|
OK_TRANSFER_CALL => Ok(MESSAGE_NONCE),
|
||||||
BAD_TRANSFER_CALL => Err(()),
|
BAD_TRANSFER_CALL => Err(()),
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ pub trait MessagesBridge<AccountId, Balance, Payload> {
|
|||||||
///
|
///
|
||||||
/// Returns unique message nonce or error if send has failed.
|
/// Returns unique message nonce or error if send has failed.
|
||||||
fn send_message(
|
fn send_message(
|
||||||
sender: AccountId,
|
sender: Sender<AccountId>,
|
||||||
lane: LaneId,
|
lane: LaneId,
|
||||||
message: Payload,
|
message: Payload,
|
||||||
delivery_and_dispatch_fee: Balance,
|
delivery_and_dispatch_fee: Balance,
|
||||||
|
|||||||
@@ -14,6 +14,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// 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/>.
|
// 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 codec::{Decode, Encode};
|
||||||
use frame_support::RuntimeDebug;
|
use frame_support::RuntimeDebug;
|
||||||
use sp_core::U256;
|
use sp_core::U256;
|
||||||
|
|||||||
@@ -102,6 +102,6 @@ mod tests {
|
|||||||
let hex = encode_message.encode().unwrap();
|
let hex = encode_message.encode().unwrap();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(format!("{:?}", hex), "0x01000000b0d60f000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c040130000000000000000000000000");
|
assert_eq!(format!("{:?}", hex), "0x01000000b0d60f000000000002d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d003c000130000000000000000000000000");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ mod tests {
|
|||||||
weight: 1038000,
|
weight: 1038000,
|
||||||
origin: CallOrigin::SourceAccount(sp_keyring::AccountKeyring::Alice.to_account_id()),
|
origin: CallOrigin::SourceAccount(sp_keyring::AccountKeyring::Alice.to_account_id()),
|
||||||
dispatch_fee_payment: bp_runtime::messages::DispatchFeePayment::AtSourceChain,
|
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