mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
Message lane pallet parameters + updatable conversion rate (#728)
* message lane pallet parameters * updated comment * Update modules/message-lane/src/lib.rs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * fmt Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
e8b5a53eed
commit
1bf2eb1ab5
@@ -336,6 +336,7 @@ impl pallet_message_lane::Config for Runtime {
|
|||||||
type Event = Event;
|
type Event = Event;
|
||||||
// TODO: https://github.com/paritytech/parity-bridges-common/issues/390
|
// TODO: https://github.com/paritytech/parity-bridges-common/issues/390
|
||||||
type WeightInfo = pallet_message_lane::weights::RialtoWeight<Runtime>;
|
type WeightInfo = pallet_message_lane::weights::RialtoWeight<Runtime>;
|
||||||
|
type Parameter = rialto_messages::MillauToRialtoMessageLaneParameter;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
|
|||||||
@@ -21,17 +21,25 @@ use crate::Runtime;
|
|||||||
use bp_message_lane::{
|
use bp_message_lane::{
|
||||||
source_chain::TargetHeaderChain,
|
source_chain::TargetHeaderChain,
|
||||||
target_chain::{ProvedMessages, SourceHeaderChain},
|
target_chain::{ProvedMessages, SourceHeaderChain},
|
||||||
InboundLaneData, LaneId, Message, MessageNonce,
|
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessageLaneParameter,
|
||||||
};
|
};
|
||||||
use bp_runtime::{InstanceId, RIALTO_BRIDGE_INSTANCE};
|
use bp_runtime::{InstanceId, RIALTO_BRIDGE_INSTANCE};
|
||||||
use bridge_runtime_common::messages::{self, ChainWithMessageLanes, MessageBridge};
|
use bridge_runtime_common::messages::{self, ChainWithMessageLanes, MessageBridge};
|
||||||
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
parameter_types,
|
||||||
weights::{DispatchClass, Weight, WeightToFeePolynomial},
|
weights::{DispatchClass, Weight, WeightToFeePolynomial},
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
};
|
};
|
||||||
use sp_core::storage::StorageKey;
|
use sp_core::storage::StorageKey;
|
||||||
|
use sp_runtime::{FixedPointNumber, FixedU128};
|
||||||
use sp_std::{convert::TryFrom, ops::RangeInclusive};
|
use sp_std::{convert::TryFrom, ops::RangeInclusive};
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
/// Rialto to Millau conversion rate. Initially we treat both tokens as equal.
|
||||||
|
storage RialtoToMillauConversionRate: FixedU128 = 1.into();
|
||||||
|
}
|
||||||
|
|
||||||
/// Storage key of the Millau -> Rialto message in the runtime storage.
|
/// Storage key of the Millau -> Rialto message in the runtime storage.
|
||||||
pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey {
|
pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey {
|
||||||
pallet_message_lane::storage_keys::message_key::<Runtime, <Millau as ChainWithMessageLanes>::MessageLaneInstance>(
|
pallet_message_lane::storage_keys::message_key::<Runtime, <Millau as ChainWithMessageLanes>::MessageLaneInstance>(
|
||||||
@@ -145,8 +153,8 @@ impl MessageBridge for WithRialtoMessageBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance {
|
fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance {
|
||||||
// 1:1 conversion that will probably change in the future
|
bp_millau::Balance::try_from(RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance))
|
||||||
bridged_balance as _
|
.unwrap_or(bp_millau::Balance::MAX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,3 +235,20 @@ impl SourceHeaderChain<bp_rialto::Balance> for Rialto {
|
|||||||
messages::target::verify_messages_proof::<WithRialtoMessageBridge, Runtime>(proof, messages_count)
|
messages::target::verify_messages_proof::<WithRialtoMessageBridge, Runtime>(proof, messages_count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Millau -> Rialto message lane pallet parameters.
|
||||||
|
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq)]
|
||||||
|
pub enum MillauToRialtoMessageLaneParameter {
|
||||||
|
/// The conversion formula we use is: `MillauTokens = RialtoTokens * conversion_rate`.
|
||||||
|
RialtoToMillauConversionRate(FixedU128),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageLaneParameter for MillauToRialtoMessageLaneParameter {
|
||||||
|
fn save(&self) {
|
||||||
|
match *self {
|
||||||
|
MillauToRialtoMessageLaneParameter::RialtoToMillauConversionRate(ref conversion_rate) => {
|
||||||
|
RialtoToMillauConversionRate::set(conversion_rate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -443,6 +443,7 @@ pub(crate) type WithMillauMessageLaneInstance = pallet_message_lane::DefaultInst
|
|||||||
impl pallet_message_lane::Config for Runtime {
|
impl pallet_message_lane::Config for Runtime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type WeightInfo = pallet_message_lane::weights::RialtoWeight<Runtime>;
|
type WeightInfo = pallet_message_lane::weights::RialtoWeight<Runtime>;
|
||||||
|
type Parameter = millau_messages::RialtoToMillauMessageLaneParameter;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
|
|||||||
@@ -21,17 +21,25 @@ use crate::Runtime;
|
|||||||
use bp_message_lane::{
|
use bp_message_lane::{
|
||||||
source_chain::TargetHeaderChain,
|
source_chain::TargetHeaderChain,
|
||||||
target_chain::{ProvedMessages, SourceHeaderChain},
|
target_chain::{ProvedMessages, SourceHeaderChain},
|
||||||
InboundLaneData, LaneId, Message, MessageNonce,
|
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessageLaneParameter,
|
||||||
};
|
};
|
||||||
use bp_runtime::{InstanceId, MILLAU_BRIDGE_INSTANCE};
|
use bp_runtime::{InstanceId, MILLAU_BRIDGE_INSTANCE};
|
||||||
use bridge_runtime_common::messages::{self, ChainWithMessageLanes, MessageBridge};
|
use bridge_runtime_common::messages::{self, ChainWithMessageLanes, MessageBridge};
|
||||||
|
use codec::{Decode, Encode};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
|
parameter_types,
|
||||||
weights::{DispatchClass, Weight, WeightToFeePolynomial},
|
weights::{DispatchClass, Weight, WeightToFeePolynomial},
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
};
|
};
|
||||||
use sp_core::storage::StorageKey;
|
use sp_core::storage::StorageKey;
|
||||||
|
use sp_runtime::{FixedPointNumber, FixedU128};
|
||||||
use sp_std::{convert::TryFrom, ops::RangeInclusive};
|
use sp_std::{convert::TryFrom, ops::RangeInclusive};
|
||||||
|
|
||||||
|
parameter_types! {
|
||||||
|
/// Millau to Rialto conversion rate. Initially we treat both tokens as equal.
|
||||||
|
storage MillauToRialtoConversionRate: FixedU128 = 1.into();
|
||||||
|
}
|
||||||
|
|
||||||
/// Storage key of the Rialto -> Millau message in the runtime storage.
|
/// Storage key of the Rialto -> Millau message in the runtime storage.
|
||||||
pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey {
|
pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey {
|
||||||
pallet_message_lane::storage_keys::message_key::<Runtime, <Rialto as ChainWithMessageLanes>::MessageLaneInstance>(
|
pallet_message_lane::storage_keys::message_key::<Runtime, <Rialto as ChainWithMessageLanes>::MessageLaneInstance>(
|
||||||
@@ -145,8 +153,8 @@ impl MessageBridge for WithMillauMessageBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance {
|
fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance {
|
||||||
// 1:1 conversion that will probably change in the future
|
bp_rialto::Balance::try_from(MillauToRialtoConversionRate::get().saturating_mul_int(bridged_balance))
|
||||||
bridged_balance as _
|
.unwrap_or(bp_rialto::Balance::MAX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,3 +235,20 @@ impl SourceHeaderChain<bp_millau::Balance> for Millau {
|
|||||||
messages::target::verify_messages_proof::<WithMillauMessageBridge, Runtime>(proof, messages_count)
|
messages::target::verify_messages_proof::<WithMillauMessageBridge, Runtime>(proof, messages_count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rialto -> Millau message lane pallet parameters.
|
||||||
|
#[derive(RuntimeDebug, Clone, Encode, Decode, PartialEq, Eq)]
|
||||||
|
pub enum RialtoToMillauMessageLaneParameter {
|
||||||
|
/// The conversion formula we use is: `RialtoTokens = MillauTokens * conversion_rate`.
|
||||||
|
MillauToRialtoConversionRate(FixedU128),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageLaneParameter for RialtoToMillauMessageLaneParameter {
|
||||||
|
fn save(&self) {
|
||||||
|
match *self {
|
||||||
|
RialtoToMillauMessageLaneParameter::MillauToRialtoConversionRate(ref conversion_rate) => {
|
||||||
|
MillauToRialtoConversionRate::set(conversion_rate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ use bp_message_lane::{
|
|||||||
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, RelayersRewards, TargetHeaderChain},
|
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, RelayersRewards, TargetHeaderChain},
|
||||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
|
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
|
||||||
total_unrewarded_messages, InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload,
|
total_unrewarded_messages, InboundLaneData, LaneId, MessageData, MessageKey, MessageNonce, MessagePayload,
|
||||||
OutboundLaneData, UnrewardedRelayersState,
|
OutboundLaneData, Parameter as MessageLaneParameter, UnrewardedRelayersState,
|
||||||
};
|
};
|
||||||
use bp_runtime::Size;
|
use bp_runtime::Size;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
@@ -84,6 +84,12 @@ pub trait Config<I = DefaultInstance>: frame_system::Config {
|
|||||||
type Event: From<Event<Self, I>> + Into<<Self as frame_system::Config>::Event>;
|
type Event: From<Event<Self, I>> + Into<<Self as frame_system::Config>::Event>;
|
||||||
/// Benchmarks results from runtime we're plugged into.
|
/// Benchmarks results from runtime we're plugged into.
|
||||||
type WeightInfo: WeightInfoExt;
|
type WeightInfo: WeightInfoExt;
|
||||||
|
/// Pallet parameter that is opaque to the pallet itself, but may be used by the runtime
|
||||||
|
/// for integrating the pallet.
|
||||||
|
///
|
||||||
|
/// All pallet parameters may only be updated either by the root, or by the pallet owner.
|
||||||
|
type Parameter: MessageLaneParameter;
|
||||||
|
|
||||||
/// Maximal number of messages that may be pruned during maintenance. Maintenance occurs
|
/// Maximal number of messages that may be pruned during maintenance. Maintenance occurs
|
||||||
/// whenever new message is sent. The reason is that if you want to use lane, you should
|
/// whenever new message is sent. The reason is that if you want to use lane, you should
|
||||||
/// be ready to pay for its maintenance.
|
/// be ready to pay for its maintenance.
|
||||||
@@ -211,9 +217,13 @@ decl_storage! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decl_event!(
|
decl_event!(
|
||||||
pub enum Event<T, I = DefaultInstance> where
|
pub enum Event<T, I = DefaultInstance>
|
||||||
<T as frame_system::Config>::AccountId,
|
where
|
||||||
|
AccountId = <T as frame_system::Config>::AccountId,
|
||||||
|
Parameter = <T as Config<I>>::Parameter,
|
||||||
{
|
{
|
||||||
|
/// Pallet parameter has been updated.
|
||||||
|
ParameterUpdated(Parameter),
|
||||||
/// Message has been accepted and is waiting to be delivered.
|
/// Message has been accepted and is waiting to be delivered.
|
||||||
MessageAccepted(LaneId, MessageNonce),
|
MessageAccepted(LaneId, MessageNonce),
|
||||||
/// Messages in the inclusive range have been delivered and processed by the bridged chain.
|
/// Messages in the inclusive range have been delivered and processed by the bridged chain.
|
||||||
@@ -274,6 +284,18 @@ decl_module! {
|
|||||||
frame_support::debug::info!("Resuming pallet operations.");
|
frame_support::debug::info!("Resuming pallet operations.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Update pallet parameter.
|
||||||
|
///
|
||||||
|
/// May only be called either by root, or by `ModuleOwner`.
|
||||||
|
///
|
||||||
|
/// The weight is: single read for permissions check + 2 writes for parameter value and event.
|
||||||
|
#[weight = (T::DbWeight::get().reads_writes(1, 2), DispatchClass::Operational)]
|
||||||
|
pub fn update_pallet_parameter(origin, parameter: T::Parameter) {
|
||||||
|
ensure_owner_or_root::<T, I>(origin)?;
|
||||||
|
parameter.save();
|
||||||
|
Self::deposit_event(RawEvent::ParameterUpdated(parameter));
|
||||||
|
}
|
||||||
|
|
||||||
/// Send message over lane.
|
/// Send message over lane.
|
||||||
#[weight = T::WeightInfo::send_message_weight(payload)]
|
#[weight = T::WeightInfo::send_message_weight(payload)]
|
||||||
pub fn send_message(
|
pub fn send_message(
|
||||||
@@ -821,9 +843,9 @@ fn verify_and_decode_messages_proof<Chain: SourceHeaderChain<Fee>, Fee, Dispatch
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::mock::{
|
use crate::mock::{
|
||||||
message, run_test, Event as TestEvent, Origin, TestMessageDeliveryAndDispatchPayment,
|
message, run_test, Event as TestEvent, Origin, TestMessageDeliveryAndDispatchPayment, TestMessageLaneParameter,
|
||||||
TestMessagesDeliveryProof, TestMessagesProof, TestPayload, TestRuntime, PAYLOAD_REJECTED_BY_TARGET_CHAIN,
|
TestMessagesDeliveryProof, TestMessagesProof, TestPayload, TestRuntime, TokenConversionRate,
|
||||||
REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B,
|
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B,
|
||||||
};
|
};
|
||||||
use bp_message_lane::UnrewardedRelayersState;
|
use bp_message_lane::UnrewardedRelayersState;
|
||||||
use frame_support::{assert_noop, assert_ok};
|
use frame_support::{assert_noop, assert_ok};
|
||||||
@@ -831,9 +853,13 @@ mod tests {
|
|||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
use sp_runtime::DispatchError;
|
use sp_runtime::DispatchError;
|
||||||
|
|
||||||
fn send_regular_message() {
|
fn get_ready_for_events() {
|
||||||
System::<TestRuntime>::set_block_number(1);
|
System::<TestRuntime>::set_block_number(1);
|
||||||
System::<TestRuntime>::reset_events();
|
System::<TestRuntime>::reset_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_regular_message() {
|
||||||
|
get_ready_for_events();
|
||||||
|
|
||||||
assert_ok!(Module::<TestRuntime>::send_message(
|
assert_ok!(Module::<TestRuntime>::send_message(
|
||||||
Origin::signed(1),
|
Origin::signed(1),
|
||||||
@@ -940,6 +966,101 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pallet_parameter_may_be_updated_by_root() {
|
||||||
|
run_test(|| {
|
||||||
|
get_ready_for_events();
|
||||||
|
|
||||||
|
let parameter = TestMessageLaneParameter::TokenConversionRate(10.into());
|
||||||
|
assert_ok!(Module::<TestRuntime>::update_pallet_parameter(
|
||||||
|
Origin::root(),
|
||||||
|
parameter.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(TokenConversionRate::get(), 10.into());
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::pallet_message_lane(RawEvent::ParameterUpdated(parameter)),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pallet_parameter_may_be_updated_by_owner() {
|
||||||
|
run_test(|| {
|
||||||
|
ModuleOwner::<TestRuntime>::put(2);
|
||||||
|
get_ready_for_events();
|
||||||
|
|
||||||
|
let parameter = TestMessageLaneParameter::TokenConversionRate(10.into());
|
||||||
|
assert_ok!(Module::<TestRuntime>::update_pallet_parameter(
|
||||||
|
Origin::signed(2),
|
||||||
|
parameter.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(TokenConversionRate::get(), 10.into());
|
||||||
|
assert_eq!(
|
||||||
|
System::<TestRuntime>::events(),
|
||||||
|
vec![EventRecord {
|
||||||
|
phase: Phase::Initialization,
|
||||||
|
event: TestEvent::pallet_message_lane(RawEvent::ParameterUpdated(parameter)),
|
||||||
|
topics: vec![],
|
||||||
|
}],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pallet_parameter_cant_be_updated_by_arbitrary_submitter() {
|
||||||
|
run_test(|| {
|
||||||
|
assert_noop!(
|
||||||
|
Module::<TestRuntime>::update_pallet_parameter(
|
||||||
|
Origin::signed(2),
|
||||||
|
TestMessageLaneParameter::TokenConversionRate(10.into()),
|
||||||
|
),
|
||||||
|
DispatchError::BadOrigin,
|
||||||
|
);
|
||||||
|
|
||||||
|
ModuleOwner::<TestRuntime>::put(2);
|
||||||
|
|
||||||
|
assert_noop!(
|
||||||
|
Module::<TestRuntime>::update_pallet_parameter(
|
||||||
|
Origin::signed(1),
|
||||||
|
TestMessageLaneParameter::TokenConversionRate(10.into()),
|
||||||
|
),
|
||||||
|
DispatchError::BadOrigin,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fixed_u128_works_as_i_think() {
|
||||||
|
// this test is here just to be sure that conversion rate may be represented with FixedU128
|
||||||
|
run_test(|| {
|
||||||
|
use sp_runtime::{FixedPointNumber, FixedU128};
|
||||||
|
|
||||||
|
// 1:1 conversion that we use by default for testnets
|
||||||
|
let rialto_token = 1u64;
|
||||||
|
let rialto_token_in_millau_tokens = TokenConversionRate::get().saturating_mul_int(rialto_token);
|
||||||
|
assert_eq!(rialto_token_in_millau_tokens, 1);
|
||||||
|
|
||||||
|
// let's say conversion rate is 1:1.7
|
||||||
|
let conversion_rate = FixedU128::saturating_from_rational(170, 100);
|
||||||
|
let rialto_tokens = 100u64;
|
||||||
|
let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens);
|
||||||
|
assert_eq!(rialto_tokens_in_millau_tokens, 170);
|
||||||
|
|
||||||
|
// let's say conversion rate is 1:0.25
|
||||||
|
let conversion_rate = FixedU128::saturating_from_rational(25, 100);
|
||||||
|
let rialto_tokens = 100u64;
|
||||||
|
let rialto_tokens_in_millau_tokens = conversion_rate.saturating_mul_int(rialto_tokens);
|
||||||
|
assert_eq!(rialto_tokens_in_millau_tokens, 25);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pallet_rejects_transactions_if_halted() {
|
fn pallet_rejects_transactions_if_halted() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use bp_message_lane::{
|
|||||||
},
|
},
|
||||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
|
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
|
||||||
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||||
|
Parameter as MessageLaneParameter,
|
||||||
};
|
};
|
||||||
use bp_runtime::Size;
|
use bp_runtime::Size;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
@@ -33,7 +34,7 @@ use sp_core::H256;
|
|||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
testing::Header as SubstrateHeader,
|
testing::Header as SubstrateHeader,
|
||||||
traits::{BlakeTwo256, IdentityLookup},
|
traits::{BlakeTwo256, IdentityLookup},
|
||||||
Perbill,
|
FixedU128, Perbill,
|
||||||
};
|
};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@@ -119,11 +120,28 @@ parameter_types! {
|
|||||||
pub const MaxMessagesToPruneAtOnce: u64 = 10;
|
pub const MaxMessagesToPruneAtOnce: u64 = 10;
|
||||||
pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16;
|
pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16;
|
||||||
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 32;
|
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 32;
|
||||||
|
pub storage TokenConversionRate: FixedU128 = 1.into();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Encode, Decode, PartialEq, Eq)]
|
||||||
|
pub enum TestMessageLaneParameter {
|
||||||
|
TokenConversionRate(FixedU128),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageLaneParameter for TestMessageLaneParameter {
|
||||||
|
fn save(&self) {
|
||||||
|
match *self {
|
||||||
|
TestMessageLaneParameter::TokenConversionRate(conversion_rate) => {
|
||||||
|
TokenConversionRate::set(&conversion_rate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config for TestRuntime {
|
impl Config for TestRuntime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
|
type Parameter = TestMessageLaneParameter;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
|
|||||||
@@ -32,6 +32,12 @@ pub mod target_chain;
|
|||||||
// Weight is reexported to avoid additional frame-support dependencies in message-lane related crates.
|
// Weight is reexported to avoid additional frame-support dependencies in message-lane related crates.
|
||||||
pub use frame_support::weights::Weight;
|
pub use frame_support::weights::Weight;
|
||||||
|
|
||||||
|
/// Message lane pallet parameter.
|
||||||
|
pub trait Parameter: frame_support::Parameter {
|
||||||
|
/// Save parameter value in the runtime storage.
|
||||||
|
fn save(&self);
|
||||||
|
}
|
||||||
|
|
||||||
/// Lane identifier.
|
/// Lane identifier.
|
||||||
pub type LaneId = [u8; 4];
|
pub type LaneId = [u8; 4];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user