mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 07:31:02 +00:00
Refund messages confirmation tx (#1904)
* Refund messages confirmation tx * Fixes
This commit is contained in:
committed by
Bastian Köcher
parent
f5fee288b9
commit
ba155f990f
@@ -453,7 +453,6 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
|
|||||||
Runtime,
|
Runtime,
|
||||||
WithRialtoMessagesInstance,
|
WithRialtoMessagesInstance,
|
||||||
frame_support::traits::ConstU64<100_000>,
|
frame_support::traits::ConstU64<100_000>,
|
||||||
frame_support::traits::ConstU64<10_000>,
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceHeaderChain = crate::rialto_messages::RialtoAsSourceHeaderChain;
|
type SourceHeaderChain = crate::rialto_messages::RialtoAsSourceHeaderChain;
|
||||||
@@ -485,7 +484,6 @@ impl pallet_bridge_messages::Config<WithRialtoParachainMessagesInstance> for Run
|
|||||||
Runtime,
|
Runtime,
|
||||||
WithRialtoParachainMessagesInstance,
|
WithRialtoParachainMessagesInstance,
|
||||||
frame_support::traits::ConstU64<100_000>,
|
frame_support::traits::ConstU64<100_000>,
|
||||||
frame_support::traits::ConstU64<10_000>,
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsSourceHeaderChain;
|
type SourceHeaderChain = crate::rialto_parachain_messages::RialtoParachainAsSourceHeaderChain;
|
||||||
|
|||||||
@@ -571,7 +571,6 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
|
|||||||
Runtime,
|
Runtime,
|
||||||
WithMillauMessagesInstance,
|
WithMillauMessagesInstance,
|
||||||
frame_support::traits::ConstU128<100_000>,
|
frame_support::traits::ConstU128<100_000>,
|
||||||
frame_support::traits::ConstU128<100_000>,
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain;
|
type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain;
|
||||||
|
|||||||
@@ -445,7 +445,6 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
|
|||||||
Runtime,
|
Runtime,
|
||||||
WithMillauMessagesInstance,
|
WithMillauMessagesInstance,
|
||||||
frame_support::traits::ConstU128<100_000>,
|
frame_support::traits::ConstU128<100_000>,
|
||||||
frame_support::traits::ConstU128<100_000>,
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain;
|
type SourceHeaderChain = crate::millau_messages::MillauAsSourceHeaderChain;
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ where
|
|||||||
/// even honest relayers may lose their funds if there are multiple relays running and
|
/// even honest relayers may lose their funds if there are multiple relays running and
|
||||||
/// submitting the same messages/confirmations.
|
/// submitting the same messages/confirmations.
|
||||||
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
|
fn validate(call: &T::RuntimeCall) -> TransactionValidity {
|
||||||
call.check_obsolete_receive_messages_proof()?;
|
call.check_obsolete_call()
|
||||||
call.check_obsolete_receive_messages_delivery_proof()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,25 +22,57 @@ use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
|
|||||||
use pallet_bridge_messages::{Config, Pallet};
|
use pallet_bridge_messages::{Config, Pallet};
|
||||||
use sp_runtime::transaction_validity::TransactionValidity;
|
use sp_runtime::transaction_validity::TransactionValidity;
|
||||||
|
|
||||||
/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
|
/// Generic info about a messages delivery/confirmation proof.
|
||||||
#[derive(PartialEq, RuntimeDebug)]
|
#[derive(PartialEq, RuntimeDebug)]
|
||||||
pub struct ReceiveMessagesProofInfo {
|
pub struct BaseMessagesProofInfo {
|
||||||
pub lane_id: LaneId,
|
pub lane_id: LaneId,
|
||||||
pub best_proof_nonce: MessageNonce,
|
pub best_bundled_nonce: MessageNonce,
|
||||||
pub best_stored_nonce: MessageNonce,
|
pub best_stored_nonce: MessageNonce,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper struct that provides methods for working with the `ReceiveMessagesProof` call.
|
impl BaseMessagesProofInfo {
|
||||||
pub struct ReceiveMessagesProofHelper<T: Config<I>, I: 'static> {
|
fn is_obsolete(&self) -> bool {
|
||||||
|
self.best_bundled_nonce <= self.best_stored_nonce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
|
||||||
|
#[derive(PartialEq, RuntimeDebug)]
|
||||||
|
pub struct ReceiveMessagesProofInfo(pub BaseMessagesProofInfo);
|
||||||
|
|
||||||
|
/// Info about a `ReceiveMessagesDeliveryProof` call which tries to update a single lane.
|
||||||
|
#[derive(PartialEq, RuntimeDebug)]
|
||||||
|
pub struct ReceiveMessagesDeliveryProofInfo(pub BaseMessagesProofInfo);
|
||||||
|
|
||||||
|
/// Info about a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call
|
||||||
|
/// which tries to update a single lane.
|
||||||
|
#[derive(PartialEq, RuntimeDebug)]
|
||||||
|
pub enum CallInfo {
|
||||||
|
ReceiveMessagesProof(ReceiveMessagesProofInfo),
|
||||||
|
ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper struct that provides methods for working with a call supported by `CallInfo`.
|
||||||
|
pub struct CallHelper<T: Config<I>, I: 'static> {
|
||||||
pub _phantom_data: sp_std::marker::PhantomData<(T, I)>,
|
pub _phantom_data: sp_std::marker::PhantomData<(T, I)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config<I>, I: 'static> ReceiveMessagesProofHelper<T, I> {
|
impl<T: Config<I>, I: 'static> CallHelper<T, I> {
|
||||||
/// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
|
/// Check if a call delivered proof/confirmation for at least some of the messages that it
|
||||||
/// it contained.
|
/// contained.
|
||||||
pub fn was_partially_successful(info: &ReceiveMessagesProofInfo) -> bool {
|
pub fn was_partially_successful(info: &CallInfo) -> bool {
|
||||||
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(info.lane_id);
|
match info {
|
||||||
inbound_lane_data.last_delivered_nonce() > info.best_stored_nonce
|
CallInfo::ReceiveMessagesProof(info) => {
|
||||||
|
let inbound_lane_data =
|
||||||
|
pallet_bridge_messages::InboundLanes::<T, I>::get(info.0.lane_id);
|
||||||
|
inbound_lane_data.last_delivered_nonce() > info.0.best_stored_nonce
|
||||||
|
},
|
||||||
|
CallInfo::ReceiveMessagesDeliveryProof(info) => {
|
||||||
|
let outbound_lane_data =
|
||||||
|
pallet_bridge_messages::OutboundLanes::<T, I>::get(info.0.lane_id);
|
||||||
|
outbound_lane_data.latest_received_nonce > info.0.best_stored_nonce
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,17 +83,21 @@ pub trait MessagesCallSubType<T: Config<I, RuntimeCall = Self>, I: 'static>:
|
|||||||
/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call.
|
/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call.
|
||||||
fn receive_messages_proof_info(&self) -> Option<ReceiveMessagesProofInfo>;
|
fn receive_messages_proof_info(&self) -> Option<ReceiveMessagesProofInfo>;
|
||||||
|
|
||||||
/// Create a new instance of `ReceiveMessagesProofInfo` from a `ReceiveMessagesProof` call,
|
/// Create a new instance of `ReceiveMessagesDeliveryProofInfo` from
|
||||||
/// if the call is for the provided lane.
|
/// a `ReceiveMessagesDeliveryProof` call.
|
||||||
fn receive_messages_proof_info_for(&self, lane_id: LaneId) -> Option<ReceiveMessagesProofInfo>;
|
fn receive_messages_delivery_proof_info(&self) -> Option<ReceiveMessagesDeliveryProofInfo>;
|
||||||
|
|
||||||
/// Check that a `ReceiveMessagesProof` call is trying to deliver at least some messages that
|
/// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
|
||||||
/// are better than the ones we know of.
|
/// or a `ReceiveMessagesDeliveryProof` call.
|
||||||
fn check_obsolete_receive_messages_proof(&self) -> TransactionValidity;
|
fn call_info(&self) -> Option<CallInfo>;
|
||||||
|
|
||||||
/// Check that a `ReceiveMessagesDeliveryProof` call is trying to deliver at least some message
|
/// Create a new instance of `CallInfo` from a `ReceiveMessagesProof`
|
||||||
/// confirmations that are better than the ones we know of.
|
/// or a `ReceiveMessagesDeliveryProof` call, if the call is for the provided lane.
|
||||||
fn check_obsolete_receive_messages_delivery_proof(&self) -> TransactionValidity;
|
fn call_info_for(&self, lane_id: LaneId) -> Option<CallInfo>;
|
||||||
|
|
||||||
|
/// Check that a `ReceiveMessagesProof` or a `ReceiveMessagesDeliveryProof` call is trying
|
||||||
|
/// to deliver/confirm at least some messages that are better than the ones we know of.
|
||||||
|
fn check_obsolete_call(&self) -> TransactionValidity;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
@@ -88,40 +124,17 @@ impl<
|
|||||||
{
|
{
|
||||||
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(proof.lane);
|
let inbound_lane_data = pallet_bridge_messages::InboundLanes::<T, I>::get(proof.lane);
|
||||||
|
|
||||||
return Some(ReceiveMessagesProofInfo {
|
return Some(ReceiveMessagesProofInfo(BaseMessagesProofInfo {
|
||||||
lane_id: proof.lane,
|
lane_id: proof.lane,
|
||||||
best_proof_nonce: proof.nonces_end,
|
best_bundled_nonce: proof.nonces_end,
|
||||||
best_stored_nonce: inbound_lane_data.last_delivered_nonce(),
|
best_stored_nonce: inbound_lane_data.last_delivered_nonce(),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive_messages_proof_info_for(&self, lane_id: LaneId) -> Option<ReceiveMessagesProofInfo> {
|
fn receive_messages_delivery_proof_info(&self) -> Option<ReceiveMessagesDeliveryProofInfo> {
|
||||||
self.receive_messages_proof_info().filter(|info| info.lane_id == lane_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_obsolete_receive_messages_proof(&self) -> TransactionValidity {
|
|
||||||
if let Some(proof_info) = self.receive_messages_proof_info() {
|
|
||||||
if proof_info.best_proof_nonce <= proof_info.best_stored_nonce {
|
|
||||||
log::trace!(
|
|
||||||
target: pallet_bridge_messages::LOG_TARGET,
|
|
||||||
"Rejecting obsolete messages delivery transaction: \
|
|
||||||
lane {:?}, bundled {:?}, best {:?}",
|
|
||||||
proof_info.lane_id,
|
|
||||||
proof_info.best_proof_nonce,
|
|
||||||
proof_info.best_stored_nonce,
|
|
||||||
);
|
|
||||||
|
|
||||||
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(sp_runtime::transaction_validity::ValidTransaction::default())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_obsolete_receive_messages_delivery_proof(&self) -> TransactionValidity {
|
|
||||||
if let Some(pallet_bridge_messages::Call::<T, I>::receive_messages_delivery_proof {
|
if let Some(pallet_bridge_messages::Call::<T, I>::receive_messages_delivery_proof {
|
||||||
ref proof,
|
ref proof,
|
||||||
ref relayers_state,
|
ref relayers_state,
|
||||||
@@ -129,18 +142,62 @@ impl<
|
|||||||
}) = self.is_sub_type()
|
}) = self.is_sub_type()
|
||||||
{
|
{
|
||||||
let outbound_lane_data = pallet_bridge_messages::OutboundLanes::<T, I>::get(proof.lane);
|
let outbound_lane_data = pallet_bridge_messages::OutboundLanes::<T, I>::get(proof.lane);
|
||||||
if relayers_state.last_delivered_nonce <= outbound_lane_data.latest_received_nonce {
|
|
||||||
|
return Some(ReceiveMessagesDeliveryProofInfo(BaseMessagesProofInfo {
|
||||||
|
lane_id: proof.lane,
|
||||||
|
best_bundled_nonce: relayers_state.last_delivered_nonce,
|
||||||
|
best_stored_nonce: outbound_lane_data.latest_received_nonce,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_info(&self) -> Option<CallInfo> {
|
||||||
|
if let Some(info) = self.receive_messages_proof_info() {
|
||||||
|
return Some(CallInfo::ReceiveMessagesProof(info))
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(info) = self.receive_messages_delivery_proof_info() {
|
||||||
|
return Some(CallInfo::ReceiveMessagesDeliveryProof(info))
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_info_for(&self, lane_id: LaneId) -> Option<CallInfo> {
|
||||||
|
self.call_info().filter(|info| {
|
||||||
|
let actual_lane_id = match info {
|
||||||
|
CallInfo::ReceiveMessagesProof(info) => info.0.lane_id,
|
||||||
|
CallInfo::ReceiveMessagesDeliveryProof(info) => info.0.lane_id,
|
||||||
|
};
|
||||||
|
actual_lane_id == lane_id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_obsolete_call(&self) -> TransactionValidity {
|
||||||
|
match self.call_info() {
|
||||||
|
Some(CallInfo::ReceiveMessagesProof(proof_info)) if proof_info.0.is_obsolete() => {
|
||||||
log::trace!(
|
log::trace!(
|
||||||
target: pallet_bridge_messages::LOG_TARGET,
|
target: pallet_bridge_messages::LOG_TARGET,
|
||||||
"Rejecting obsolete messages confirmation transaction: \
|
"Rejecting obsolete messages delivery transaction: {:?}",
|
||||||
lane {:?}, bundled {:?}, best {:?}",
|
proof_info
|
||||||
proof.lane,
|
|
||||||
relayers_state.last_delivered_nonce,
|
|
||||||
outbound_lane_data.latest_received_nonce,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
|
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
|
||||||
}
|
},
|
||||||
|
Some(CallInfo::ReceiveMessagesDeliveryProof(proof_info))
|
||||||
|
if proof_info.0.is_obsolete() =>
|
||||||
|
{
|
||||||
|
log::trace!(
|
||||||
|
target: pallet_bridge_messages::LOG_TARGET,
|
||||||
|
"Rejecting obsolete messages confirmation transaction: {:?}",
|
||||||
|
proof_info,
|
||||||
|
);
|
||||||
|
|
||||||
|
return sp_runtime::transaction_validity::InvalidTransaction::Stale.into()
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(sp_runtime::transaction_validity::ValidTransaction::default())
|
Ok(sp_runtime::transaction_validity::ValidTransaction::default())
|
||||||
@@ -153,8 +210,8 @@ mod tests {
|
|||||||
messages::{
|
messages::{
|
||||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||||
},
|
},
|
||||||
|
messages_call_ext::MessagesCallSubType,
|
||||||
mock::{TestRuntime, ThisChainRuntimeCall},
|
mock::{TestRuntime, ThisChainRuntimeCall},
|
||||||
BridgeRuntimeFilterCall,
|
|
||||||
};
|
};
|
||||||
use bp_messages::UnrewardedRelayersState;
|
use bp_messages::UnrewardedRelayersState;
|
||||||
|
|
||||||
@@ -169,8 +226,7 @@ mod tests {
|
|||||||
nonces_start: bp_messages::MessageNonce,
|
nonces_start: bp_messages::MessageNonce,
|
||||||
nonces_end: bp_messages::MessageNonce,
|
nonces_end: bp_messages::MessageNonce,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
pallet_bridge_messages::Pallet::<TestRuntime>::validate(
|
ThisChainRuntimeCall::BridgeMessages(
|
||||||
&ThisChainRuntimeCall::BridgeMessages(
|
|
||||||
pallet_bridge_messages::Call::<TestRuntime, ()>::receive_messages_proof {
|
pallet_bridge_messages::Call::<TestRuntime, ()>::receive_messages_proof {
|
||||||
relayer_id_at_bridged_chain: 42,
|
relayer_id_at_bridged_chain: 42,
|
||||||
messages_count: (nonces_end - nonces_start + 1) as u32,
|
messages_count: (nonces_end - nonces_start + 1) as u32,
|
||||||
@@ -183,8 +239,8 @@ mod tests {
|
|||||||
nonces_end,
|
nonces_end,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
.check_obsolete_call()
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,8 +286,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate_message_confirmation(last_delivered_nonce: bp_messages::MessageNonce) -> bool {
|
fn validate_message_confirmation(last_delivered_nonce: bp_messages::MessageNonce) -> bool {
|
||||||
pallet_bridge_messages::Pallet::<TestRuntime>::validate(
|
ThisChainRuntimeCall::BridgeMessages(
|
||||||
&ThisChainRuntimeCall::BridgeMessages(
|
|
||||||
pallet_bridge_messages::Call::<TestRuntime>::receive_messages_delivery_proof {
|
pallet_bridge_messages::Call::<TestRuntime>::receive_messages_delivery_proof {
|
||||||
proof: FromBridgedChainMessagesDeliveryProof {
|
proof: FromBridgedChainMessagesDeliveryProof {
|
||||||
bridged_header_hash: Default::default(),
|
bridged_header_hash: Default::default(),
|
||||||
@@ -243,8 +298,8 @@ mod tests {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
.check_obsolete_call()
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -230,8 +230,7 @@ impl pallet_bridge_messages::Config for TestRuntime {
|
|||||||
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
|
type DeliveryConfirmationPayments = pallet_bridge_relayers::DeliveryConfirmationPaymentsAdapter<
|
||||||
TestRuntime,
|
TestRuntime,
|
||||||
(),
|
(),
|
||||||
frame_support::traits::ConstU64<100_000>,
|
ConstU64<100_000>,
|
||||||
frame_support::traits::ConstU64<10_000>,
|
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>;
|
type SourceHeaderChain = SourceHeaderChainAdapter<OnThisChainBridge>;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
//! (parachain or relay chain).
|
//! (parachain or relay chain).
|
||||||
|
|
||||||
use crate::messages_call_ext::{
|
use crate::messages_call_ext::{
|
||||||
MessagesCallSubType, ReceiveMessagesProofHelper, ReceiveMessagesProofInfo,
|
CallHelper as MessagesCallHelper, CallInfo as MessagesCallInfo, MessagesCallSubType,
|
||||||
};
|
};
|
||||||
use bp_messages::LaneId;
|
use bp_messages::LaneId;
|
||||||
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
|
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
|
||||||
@@ -143,23 +143,23 @@ pub struct PreDispatchData<AccountId> {
|
|||||||
/// Type of the call that the extension recognizes.
|
/// Type of the call that the extension recognizes.
|
||||||
#[derive(RuntimeDebugNoBound, PartialEq)]
|
#[derive(RuntimeDebugNoBound, PartialEq)]
|
||||||
pub enum CallInfo {
|
pub enum CallInfo {
|
||||||
/// Relay chain finality + parachain finality + message delivery calls.
|
/// Relay chain finality + parachain finality + message delivery/confirmation calls.
|
||||||
AllFinalityAndDelivery(
|
AllFinalityAndMsgs(
|
||||||
SubmitFinalityProofInfo<RelayBlockNumber>,
|
SubmitFinalityProofInfo<RelayBlockNumber>,
|
||||||
SubmitParachainHeadsInfo,
|
SubmitParachainHeadsInfo,
|
||||||
ReceiveMessagesProofInfo,
|
MessagesCallInfo,
|
||||||
),
|
),
|
||||||
/// Parachain finality + message delivery calls.
|
/// Parachain finality + message delivery/confirmation calls.
|
||||||
ParachainFinalityAndDelivery(SubmitParachainHeadsInfo, ReceiveMessagesProofInfo),
|
ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo),
|
||||||
/// Standalone message delivery call.
|
/// Standalone message delivery/confirmation call.
|
||||||
Delivery(ReceiveMessagesProofInfo),
|
Msgs(MessagesCallInfo),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CallInfo {
|
impl CallInfo {
|
||||||
/// Returns the pre-dispatch `finality_target` sent to the `SubmitFinalityProof` call.
|
/// Returns the pre-dispatch `finality_target` sent to the `SubmitFinalityProof` call.
|
||||||
fn submit_finality_proof_info(&self) -> Option<SubmitFinalityProofInfo<RelayBlockNumber>> {
|
fn submit_finality_proof_info(&self) -> Option<SubmitFinalityProofInfo<RelayBlockNumber>> {
|
||||||
match *self {
|
match *self {
|
||||||
Self::AllFinalityAndDelivery(info, _, _) => Some(info),
|
Self::AllFinalityAndMsgs(info, _, _) => Some(info),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,18 +167,18 @@ impl CallInfo {
|
|||||||
/// Returns the pre-dispatch `SubmitParachainHeadsInfo`.
|
/// Returns the pre-dispatch `SubmitParachainHeadsInfo`.
|
||||||
fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
|
fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
|
||||||
match self {
|
match self {
|
||||||
Self::AllFinalityAndDelivery(_, info, _) => Some(info),
|
Self::AllFinalityAndMsgs(_, info, _) => Some(info),
|
||||||
Self::ParachainFinalityAndDelivery(info, _) => Some(info),
|
Self::ParachainFinalityAndMsgs(info, _) => Some(info),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the pre-dispatch `ReceiveMessagesProofInfo`.
|
/// Returns the pre-dispatch `ReceiveMessagesProofInfo`.
|
||||||
fn receive_messages_proof_info(&self) -> &ReceiveMessagesProofInfo {
|
fn messages_call_info(&self) -> &MessagesCallInfo {
|
||||||
match self {
|
match self {
|
||||||
Self::AllFinalityAndDelivery(_, _, info) => info,
|
Self::AllFinalityAndMsgs(_, _, info) => info,
|
||||||
Self::ParachainFinalityAndDelivery(_, info) => info,
|
Self::ParachainFinalityAndMsgs(_, info) => info,
|
||||||
Self::Delivery(info) => info,
|
Self::Msgs(info) => info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,7 +269,7 @@ where
|
|||||||
for nested_call in calls {
|
for nested_call in calls {
|
||||||
nested_call.check_obsolete_submit_finality_proof()?;
|
nested_call.check_obsolete_submit_finality_proof()?;
|
||||||
nested_call.check_obsolete_submit_parachain_heads()?;
|
nested_call.check_obsolete_submit_parachain_heads()?;
|
||||||
nested_call.check_obsolete_receive_messages_proof()?;
|
nested_call.check_obsolete_call()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,18 +290,16 @@ where
|
|||||||
let parse_call = || {
|
let parse_call = || {
|
||||||
let mut calls = self.expand_call(call)?.into_iter();
|
let mut calls = self.expand_call(call)?.into_iter();
|
||||||
match calls.len() {
|
match calls.len() {
|
||||||
3 => Some(CallInfo::AllFinalityAndDelivery(
|
3 => Some(CallInfo::AllFinalityAndMsgs(
|
||||||
calls.next()?.submit_finality_proof_info()?,
|
calls.next()?.submit_finality_proof_info()?,
|
||||||
calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
|
calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
|
||||||
calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
|
calls.next()?.call_info_for(Msgs::Id::get())?,
|
||||||
)),
|
)),
|
||||||
2 => Some(CallInfo::ParachainFinalityAndDelivery(
|
2 => Some(CallInfo::ParachainFinalityAndMsgs(
|
||||||
calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
|
calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
|
||||||
calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
|
calls.next()?.call_info_for(Msgs::Id::get())?,
|
||||||
)),
|
|
||||||
1 => Some(CallInfo::Delivery(
|
|
||||||
calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
|
|
||||||
)),
|
)),
|
||||||
|
1 => Some(CallInfo::Msgs(calls.next()?.call_info_for(Msgs::Id::get())?)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -374,10 +372,9 @@ where
|
|||||||
|
|
||||||
// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
|
// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
|
||||||
// it contained. If this happens, we consider the transaction "helpful" and refund it.
|
// it contained. If this happens, we consider the transaction "helpful" and refund it.
|
||||||
let msgs_proof_info = call_info.receive_messages_proof_info();
|
let msgs_call_info = call_info.messages_call_info();
|
||||||
if !ReceiveMessagesProofHelper::<Runtime, Msgs::Instance>::was_partially_successful(
|
if !MessagesCallHelper::<Runtime, Msgs::Instance>::was_partially_successful(msgs_call_info)
|
||||||
msgs_proof_info,
|
{
|
||||||
) {
|
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,11 +395,15 @@ where
|
|||||||
let refund = Refund::compute_refund(info, &post_info, post_info_len, tip);
|
let refund = Refund::compute_refund(info, &post_info, post_info_len, tip);
|
||||||
|
|
||||||
// finally - register refund in relayers pallet
|
// finally - register refund in relayers pallet
|
||||||
|
let rewards_account_owner = match msgs_call_info {
|
||||||
|
MessagesCallInfo::ReceiveMessagesProof(_) => RewardsAccountOwner::ThisChain,
|
||||||
|
MessagesCallInfo::ReceiveMessagesDeliveryProof(_) => RewardsAccountOwner::BridgedChain,
|
||||||
|
};
|
||||||
RelayersPallet::<Runtime>::register_relayer_reward(
|
RelayersPallet::<Runtime>::register_relayer_reward(
|
||||||
RewardsAccountParams::new(
|
RewardsAccountParams::new(
|
||||||
Msgs::Id::get(),
|
Msgs::Id::get(),
|
||||||
Runtime::BridgedChainId::get(),
|
Runtime::BridgedChainId::get(),
|
||||||
RewardsAccountOwner::ThisChain,
|
rewards_account_owner,
|
||||||
),
|
),
|
||||||
&relayer,
|
&relayer,
|
||||||
refund,
|
refund,
|
||||||
@@ -425,8 +426,16 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{messages::target::FromBridgedChainMessagesProof, mock::*};
|
use crate::{
|
||||||
use bp_messages::{InboundLaneData, MessageNonce};
|
messages::{
|
||||||
|
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||||
|
},
|
||||||
|
messages_call_ext::{
|
||||||
|
BaseMessagesProofInfo, ReceiveMessagesDeliveryProofInfo, ReceiveMessagesProofInfo,
|
||||||
|
},
|
||||||
|
mock::*,
|
||||||
|
};
|
||||||
|
use bp_messages::{InboundLaneData, MessageNonce, OutboundLaneData, UnrewardedRelayersState};
|
||||||
use bp_parachains::{BestParaHeadHash, ParaInfo};
|
use bp_parachains::{BestParaHeadHash, ParaInfo};
|
||||||
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
use bp_polkadot_core::parachains::{ParaHash, ParaHeadsProof, ParaId};
|
||||||
use bp_runtime::HeaderId;
|
use bp_runtime::HeaderId;
|
||||||
@@ -442,7 +451,8 @@ mod tests {
|
|||||||
parameter_types! {
|
parameter_types! {
|
||||||
TestParachain: u32 = 1000;
|
TestParachain: u32 = 1000;
|
||||||
pub TestLaneId: LaneId = TEST_LANE_ID;
|
pub TestLaneId: LaneId = TEST_LANE_ID;
|
||||||
pub DirectedTestLaneId: RewardsAccountParams = RewardsAccountParams::new(TEST_LANE_ID, TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::ThisChain);
|
pub MsgProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new(TEST_LANE_ID, TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::ThisChain);
|
||||||
|
pub MsgDeliveryProofsRewardsAccount: RewardsAccountParams = RewardsAccountParams::new(TEST_LANE_ID, TEST_BRIDGED_CHAIN_ID, RewardsAccountOwner::BridgedChain);
|
||||||
}
|
}
|
||||||
|
|
||||||
bp_runtime::generate_static_str_provider!(TestExtension);
|
bp_runtime::generate_static_str_provider!(TestExtension);
|
||||||
@@ -466,7 +476,7 @@ mod tests {
|
|||||||
best_relay_header_number: RelayBlockNumber,
|
best_relay_header_number: RelayBlockNumber,
|
||||||
parachain_head_at_relay_header_number: RelayBlockNumber,
|
parachain_head_at_relay_header_number: RelayBlockNumber,
|
||||||
parachain_head_hash: ParaHash,
|
parachain_head_hash: ParaHash,
|
||||||
best_delivered_message: MessageNonce,
|
best_message: MessageNonce,
|
||||||
) {
|
) {
|
||||||
let authorities = test_keyring().into_iter().map(|(a, w)| (a.into(), w)).collect();
|
let authorities = test_keyring().into_iter().map(|(a, w)| (a.into(), w)).collect();
|
||||||
let best_relay_header = HeaderId(best_relay_header_number, RelayBlockHash::default());
|
let best_relay_header = HeaderId(best_relay_header_number, RelayBlockHash::default());
|
||||||
@@ -486,9 +496,13 @@ mod tests {
|
|||||||
pallet_bridge_parachains::ParasInfo::<TestRuntime>::insert(para_id, para_info);
|
pallet_bridge_parachains::ParasInfo::<TestRuntime>::insert(para_id, para_info);
|
||||||
|
|
||||||
let lane_id = TestLaneId::get();
|
let lane_id = TestLaneId::get();
|
||||||
let lane_data =
|
let in_lane_data =
|
||||||
InboundLaneData { last_confirmed_nonce: best_delivered_message, ..Default::default() };
|
InboundLaneData { last_confirmed_nonce: best_message, ..Default::default() };
|
||||||
pallet_bridge_messages::InboundLanes::<TestRuntime>::insert(lane_id, lane_data);
|
pallet_bridge_messages::InboundLanes::<TestRuntime>::insert(lane_id, in_lane_data);
|
||||||
|
|
||||||
|
let out_lane_data =
|
||||||
|
OutboundLaneData { latest_received_nonce: best_message, ..Default::default() };
|
||||||
|
pallet_bridge_messages::OutboundLanes::<TestRuntime>::insert(lane_id, out_lane_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit_relay_header_call(relay_header_number: RelayBlockNumber) -> RuntimeCall {
|
fn submit_relay_header_call(relay_header_number: RelayBlockNumber) -> RuntimeCall {
|
||||||
@@ -532,6 +546,20 @@ mod tests {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn message_confirmation_call(best_message: MessageNonce) -> RuntimeCall {
|
||||||
|
RuntimeCall::BridgeMessages(MessagesCall::receive_messages_delivery_proof {
|
||||||
|
proof: FromBridgedChainMessagesDeliveryProof {
|
||||||
|
bridged_header_hash: Default::default(),
|
||||||
|
storage_proof: vec![],
|
||||||
|
lane: TestLaneId::get(),
|
||||||
|
},
|
||||||
|
relayers_state: UnrewardedRelayersState {
|
||||||
|
last_delivered_nonce: best_message,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn parachain_finality_and_delivery_batch_call(
|
fn parachain_finality_and_delivery_batch_call(
|
||||||
parachain_head_at_relay_header_number: RelayBlockNumber,
|
parachain_head_at_relay_header_number: RelayBlockNumber,
|
||||||
best_message: MessageNonce,
|
best_message: MessageNonce,
|
||||||
@@ -544,6 +572,18 @@ mod tests {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parachain_finality_and_confirmation_batch_call(
|
||||||
|
parachain_head_at_relay_header_number: RelayBlockNumber,
|
||||||
|
best_message: MessageNonce,
|
||||||
|
) -> RuntimeCall {
|
||||||
|
RuntimeCall::Utility(UtilityCall::batch_all {
|
||||||
|
calls: vec![
|
||||||
|
submit_parachain_head_call(parachain_head_at_relay_header_number),
|
||||||
|
message_confirmation_call(best_message),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn all_finality_and_delivery_batch_call(
|
fn all_finality_and_delivery_batch_call(
|
||||||
relay_header_number: RelayBlockNumber,
|
relay_header_number: RelayBlockNumber,
|
||||||
parachain_head_at_relay_header_number: RelayBlockNumber,
|
parachain_head_at_relay_header_number: RelayBlockNumber,
|
||||||
@@ -558,10 +598,24 @@ mod tests {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn all_finality_and_confirmation_batch_call(
|
||||||
|
relay_header_number: RelayBlockNumber,
|
||||||
|
parachain_head_at_relay_header_number: RelayBlockNumber,
|
||||||
|
best_message: MessageNonce,
|
||||||
|
) -> RuntimeCall {
|
||||||
|
RuntimeCall::Utility(UtilityCall::batch_all {
|
||||||
|
calls: vec![
|
||||||
|
submit_relay_header_call(relay_header_number),
|
||||||
|
submit_parachain_head_call(parachain_head_at_relay_header_number),
|
||||||
|
message_confirmation_call(best_message),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn all_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
fn all_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
PreDispatchData {
|
PreDispatchData {
|
||||||
relayer: relayer_account_at_this_chain(),
|
relayer: relayer_account_at_this_chain(),
|
||||||
call_info: CallInfo::AllFinalityAndDelivery(
|
call_info: CallInfo::AllFinalityAndMsgs(
|
||||||
SubmitFinalityProofInfo {
|
SubmitFinalityProofInfo {
|
||||||
block_number: 200,
|
block_number: 200,
|
||||||
extra_weight: Weight::zero(),
|
extra_weight: Weight::zero(),
|
||||||
@@ -572,11 +626,38 @@ mod tests {
|
|||||||
para_id: ParaId(TestParachain::get()),
|
para_id: ParaId(TestParachain::get()),
|
||||||
para_head_hash: [1u8; 32].into(),
|
para_head_hash: [1u8; 32].into(),
|
||||||
},
|
},
|
||||||
ReceiveMessagesProofInfo {
|
MessagesCallInfo::ReceiveMessagesProof(ReceiveMessagesProofInfo(
|
||||||
|
BaseMessagesProofInfo {
|
||||||
lane_id: TEST_LANE_ID,
|
lane_id: TEST_LANE_ID,
|
||||||
best_proof_nonce: 200,
|
best_bundled_nonce: 200,
|
||||||
best_stored_nonce: 100,
|
best_stored_nonce: 100,
|
||||||
},
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn all_finality_confirmation_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
|
PreDispatchData {
|
||||||
|
relayer: relayer_account_at_this_chain(),
|
||||||
|
call_info: CallInfo::AllFinalityAndMsgs(
|
||||||
|
SubmitFinalityProofInfo {
|
||||||
|
block_number: 200,
|
||||||
|
extra_weight: Weight::zero(),
|
||||||
|
extra_size: 0,
|
||||||
|
},
|
||||||
|
SubmitParachainHeadsInfo {
|
||||||
|
at_relay_block_number: 200,
|
||||||
|
para_id: ParaId(TestParachain::get()),
|
||||||
|
para_head_hash: [1u8; 32].into(),
|
||||||
|
},
|
||||||
|
MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
|
||||||
|
BaseMessagesProofInfo {
|
||||||
|
lane_id: TEST_LANE_ID,
|
||||||
|
best_bundled_nonce: 200,
|
||||||
|
best_stored_nonce: 100,
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -584,17 +665,39 @@ mod tests {
|
|||||||
fn parachain_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
fn parachain_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
PreDispatchData {
|
PreDispatchData {
|
||||||
relayer: relayer_account_at_this_chain(),
|
relayer: relayer_account_at_this_chain(),
|
||||||
call_info: CallInfo::ParachainFinalityAndDelivery(
|
call_info: CallInfo::ParachainFinalityAndMsgs(
|
||||||
SubmitParachainHeadsInfo {
|
SubmitParachainHeadsInfo {
|
||||||
at_relay_block_number: 200,
|
at_relay_block_number: 200,
|
||||||
para_id: ParaId(TestParachain::get()),
|
para_id: ParaId(TestParachain::get()),
|
||||||
para_head_hash: [1u8; 32].into(),
|
para_head_hash: [1u8; 32].into(),
|
||||||
},
|
},
|
||||||
ReceiveMessagesProofInfo {
|
MessagesCallInfo::ReceiveMessagesProof(ReceiveMessagesProofInfo(
|
||||||
|
BaseMessagesProofInfo {
|
||||||
lane_id: TEST_LANE_ID,
|
lane_id: TEST_LANE_ID,
|
||||||
best_proof_nonce: 200,
|
best_bundled_nonce: 200,
|
||||||
best_stored_nonce: 100,
|
best_stored_nonce: 100,
|
||||||
},
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parachain_finality_confirmation_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
|
PreDispatchData {
|
||||||
|
relayer: relayer_account_at_this_chain(),
|
||||||
|
call_info: CallInfo::ParachainFinalityAndMsgs(
|
||||||
|
SubmitParachainHeadsInfo {
|
||||||
|
at_relay_block_number: 200,
|
||||||
|
para_id: ParaId(TestParachain::get()),
|
||||||
|
para_head_hash: [1u8; 32].into(),
|
||||||
|
},
|
||||||
|
MessagesCallInfo::ReceiveMessagesDeliveryProof(ReceiveMessagesDeliveryProofInfo(
|
||||||
|
BaseMessagesProofInfo {
|
||||||
|
lane_id: TEST_LANE_ID,
|
||||||
|
best_bundled_nonce: 200,
|
||||||
|
best_stored_nonce: 100,
|
||||||
|
},
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -602,11 +705,26 @@ mod tests {
|
|||||||
fn delivery_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
fn delivery_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
PreDispatchData {
|
PreDispatchData {
|
||||||
relayer: relayer_account_at_this_chain(),
|
relayer: relayer_account_at_this_chain(),
|
||||||
call_info: CallInfo::Delivery(ReceiveMessagesProofInfo {
|
call_info: CallInfo::Msgs(MessagesCallInfo::ReceiveMessagesProof(
|
||||||
|
ReceiveMessagesProofInfo(BaseMessagesProofInfo {
|
||||||
lane_id: TEST_LANE_ID,
|
lane_id: TEST_LANE_ID,
|
||||||
best_proof_nonce: 200,
|
best_bundled_nonce: 200,
|
||||||
best_stored_nonce: 100,
|
best_stored_nonce: 100,
|
||||||
}),
|
}),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn confirmation_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
|
||||||
|
PreDispatchData {
|
||||||
|
relayer: relayer_account_at_this_chain(),
|
||||||
|
call_info: CallInfo::Msgs(MessagesCallInfo::ReceiveMessagesDeliveryProof(
|
||||||
|
ReceiveMessagesDeliveryProofInfo(BaseMessagesProofInfo {
|
||||||
|
lane_id: TEST_LANE_ID,
|
||||||
|
best_bundled_nonce: 200,
|
||||||
|
best_stored_nonce: 100,
|
||||||
|
}),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,16 +787,28 @@ mod tests {
|
|||||||
initialize_environment(100, 100, Default::default(), 100);
|
initialize_environment(100, 100, Default::default(), 100);
|
||||||
|
|
||||||
assert_eq!(run_validate(message_delivery_call(200)), Ok(ValidTransaction::default()),);
|
assert_eq!(run_validate(message_delivery_call(200)), Ok(ValidTransaction::default()),);
|
||||||
|
assert_eq!(
|
||||||
|
run_validate(message_confirmation_call(200)),
|
||||||
|
Ok(ValidTransaction::default()),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_validate(parachain_finality_and_delivery_batch_call(200, 200)),
|
run_validate(parachain_finality_and_delivery_batch_call(200, 200)),
|
||||||
Ok(ValidTransaction::default()),
|
Ok(ValidTransaction::default()),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_validate(parachain_finality_and_confirmation_batch_call(200, 200)),
|
||||||
|
Ok(ValidTransaction::default()),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_validate(all_finality_and_delivery_batch_call(200, 200, 200)),
|
run_validate(all_finality_and_delivery_batch_call(200, 200, 200)),
|
||||||
Ok(ValidTransaction::default()),
|
Ok(ValidTransaction::default()),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_validate(all_finality_and_confirmation_batch_call(200, 200, 200)),
|
||||||
|
Ok(ValidTransaction::default()),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,17 +838,15 @@ mod tests {
|
|||||||
run_pre_dispatch(all_finality_and_delivery_batch_call(101, 100, 200)),
|
run_pre_dispatch(all_finality_and_delivery_batch_call(101, 100, 200)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
run_pre_dispatch(parachain_finality_and_delivery_batch_call(100, 200)),
|
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_validate(all_finality_and_delivery_batch_call(101, 100, 200)),
|
run_validate(all_finality_and_delivery_batch_call(101, 100, 200)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(parachain_finality_and_delivery_batch_call(100, 200)),
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_validate(parachain_finality_and_delivery_batch_call(100, 200)),
|
run_validate(parachain_finality_and_delivery_batch_call(100, 200)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
@@ -735,9 +863,8 @@ mod tests {
|
|||||||
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 100)),
|
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 100)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 100)),
|
run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 100)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -745,11 +872,28 @@ mod tests {
|
|||||||
run_validate(all_finality_and_delivery_batch_call(200, 200, 100)),
|
run_validate(all_finality_and_delivery_batch_call(200, 200, 100)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_validate(all_finality_and_confirmation_batch_call(200, 200, 100)),
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 100)),
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 100)),
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
run_validate(parachain_finality_and_delivery_batch_call(200, 100)),
|
run_validate(parachain_finality_and_delivery_batch_call(200, 100)),
|
||||||
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_validate(parachain_finality_and_confirmation_batch_call(200, 100)),
|
||||||
|
Err(TransactionValidityError::Invalid(InvalidTransaction::Stale)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -762,6 +906,10 @@ mod tests {
|
|||||||
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
|
run_pre_dispatch(all_finality_and_delivery_batch_call(200, 200, 200)),
|
||||||
Ok(Some(all_finality_pre_dispatch_data())),
|
Ok(Some(all_finality_pre_dispatch_data())),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(all_finality_and_confirmation_batch_call(200, 200, 200)),
|
||||||
|
Ok(Some(all_finality_confirmation_pre_dispatch_data())),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -774,6 +922,10 @@ mod tests {
|
|||||||
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
|
run_pre_dispatch(parachain_finality_and_delivery_batch_call(200, 200)),
|
||||||
Ok(Some(parachain_finality_pre_dispatch_data())),
|
Ok(Some(parachain_finality_pre_dispatch_data())),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(parachain_finality_and_confirmation_batch_call(200, 200)),
|
||||||
|
Ok(Some(parachain_finality_confirmation_pre_dispatch_data())),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +953,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pre_dispatch_parses_message_delivery_transaction() {
|
fn pre_dispatch_parses_message_transaction() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
initialize_environment(100, 100, Default::default(), 100);
|
initialize_environment(100, 100, Default::default(), 100);
|
||||||
|
|
||||||
@@ -809,6 +961,10 @@ mod tests {
|
|||||||
run_pre_dispatch(message_delivery_call(200)),
|
run_pre_dispatch(message_delivery_call(200)),
|
||||||
Ok(Some(delivery_pre_dispatch_data())),
|
Ok(Some(delivery_pre_dispatch_data())),
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
run_pre_dispatch(message_confirmation_call(200)),
|
||||||
|
Ok(Some(confirmation_pre_dispatch_data())),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -862,6 +1018,16 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
));
|
));
|
||||||
assert_storage_noop!(run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())));
|
assert_storage_noop!(run_post_dispatch(Some(delivery_pre_dispatch_data()), Ok(())));
|
||||||
|
|
||||||
|
assert_storage_noop!(run_post_dispatch(
|
||||||
|
Some(all_finality_confirmation_pre_dispatch_data()),
|
||||||
|
Ok(())
|
||||||
|
));
|
||||||
|
assert_storage_noop!(run_post_dispatch(
|
||||||
|
Some(parachain_finality_confirmation_pre_dispatch_data()),
|
||||||
|
Ok(())
|
||||||
|
));
|
||||||
|
assert_storage_noop!(run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(())));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,7 +1048,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayersPallet::<TestRuntime>::relayer_reward(
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
relayer_account_at_this_chain(),
|
relayer_account_at_this_chain(),
|
||||||
DirectedTestLaneId::get()
|
MsgProofsRewardsAccount::get()
|
||||||
),
|
),
|
||||||
Some(regular_reward),
|
Some(regular_reward),
|
||||||
);
|
);
|
||||||
@@ -890,7 +1056,7 @@ mod tests {
|
|||||||
// now repeat the same with size+weight refund: we expect smaller reward
|
// now repeat the same with size+weight refund: we expect smaller reward
|
||||||
let mut pre_dispatch_data = all_finality_pre_dispatch_data();
|
let mut pre_dispatch_data = all_finality_pre_dispatch_data();
|
||||||
match pre_dispatch_data.call_info {
|
match pre_dispatch_data.call_info {
|
||||||
CallInfo::AllFinalityAndDelivery(ref mut info, ..) => {
|
CallInfo::AllFinalityAndMsgs(ref mut info, ..) => {
|
||||||
info.extra_weight.set_ref_time(
|
info.extra_weight.set_ref_time(
|
||||||
frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
|
frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND,
|
||||||
);
|
);
|
||||||
@@ -901,7 +1067,7 @@ mod tests {
|
|||||||
run_post_dispatch(Some(pre_dispatch_data), Ok(()));
|
run_post_dispatch(Some(pre_dispatch_data), Ok(()));
|
||||||
let reward_after_two_calls = RelayersPallet::<TestRuntime>::relayer_reward(
|
let reward_after_two_calls = RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
relayer_account_at_this_chain(),
|
relayer_account_at_this_chain(),
|
||||||
DirectedTestLaneId::get(),
|
MsgProofsRewardsAccount::get(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
@@ -922,7 +1088,16 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayersPallet::<TestRuntime>::relayer_reward(
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
relayer_account_at_this_chain(),
|
relayer_account_at_this_chain(),
|
||||||
DirectedTestLaneId::get()
|
MsgProofsRewardsAccount::get()
|
||||||
|
),
|
||||||
|
Some(expected_reward()),
|
||||||
|
);
|
||||||
|
|
||||||
|
run_post_dispatch(Some(all_finality_confirmation_pre_dispatch_data()), Ok(()));
|
||||||
|
assert_eq!(
|
||||||
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
|
relayer_account_at_this_chain(),
|
||||||
|
MsgDeliveryProofsRewardsAccount::get()
|
||||||
),
|
),
|
||||||
Some(expected_reward()),
|
Some(expected_reward()),
|
||||||
);
|
);
|
||||||
@@ -938,7 +1113,16 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayersPallet::<TestRuntime>::relayer_reward(
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
relayer_account_at_this_chain(),
|
relayer_account_at_this_chain(),
|
||||||
DirectedTestLaneId::get()
|
MsgProofsRewardsAccount::get()
|
||||||
|
),
|
||||||
|
Some(expected_reward()),
|
||||||
|
);
|
||||||
|
|
||||||
|
run_post_dispatch(Some(parachain_finality_confirmation_pre_dispatch_data()), Ok(()));
|
||||||
|
assert_eq!(
|
||||||
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
|
relayer_account_at_this_chain(),
|
||||||
|
MsgDeliveryProofsRewardsAccount::get()
|
||||||
),
|
),
|
||||||
Some(expected_reward()),
|
Some(expected_reward()),
|
||||||
);
|
);
|
||||||
@@ -946,7 +1130,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn post_dispatch_refunds_relayer_in_message_delivery_transaction() {
|
fn post_dispatch_refunds_relayer_in_message_transaction() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
initialize_environment(200, 200, Default::default(), 200);
|
initialize_environment(200, 200, Default::default(), 200);
|
||||||
|
|
||||||
@@ -954,7 +1138,16 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayersPallet::<TestRuntime>::relayer_reward(
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
relayer_account_at_this_chain(),
|
relayer_account_at_this_chain(),
|
||||||
DirectedTestLaneId::get()
|
MsgProofsRewardsAccount::get()
|
||||||
|
),
|
||||||
|
Some(expected_reward()),
|
||||||
|
);
|
||||||
|
|
||||||
|
run_post_dispatch(Some(confirmation_pre_dispatch_data()), Ok(()));
|
||||||
|
assert_eq!(
|
||||||
|
RelayersPallet::<TestRuntime>::relayer_reward(
|
||||||
|
relayer_account_at_this_chain(),
|
||||||
|
MsgDeliveryProofsRewardsAccount::get()
|
||||||
),
|
),
|
||||||
Some(expected_reward()),
|
Some(expected_reward()),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,22 +24,21 @@ use bp_messages::{
|
|||||||
};
|
};
|
||||||
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
|
use bp_relayers::{RewardsAccountOwner, RewardsAccountParams};
|
||||||
use frame_support::{sp_runtime::SaturatedConversion, traits::Get};
|
use frame_support::{sp_runtime::SaturatedConversion, traits::Get};
|
||||||
use sp_arithmetic::traits::{Saturating, UniqueSaturatedFrom, Zero};
|
use sp_arithmetic::traits::{Saturating, Zero};
|
||||||
use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive};
|
use sp_std::{collections::vec_deque::VecDeque, marker::PhantomData, ops::RangeInclusive};
|
||||||
|
|
||||||
/// Adapter that allows relayers pallet to be used as a delivery+dispatch payment mechanism
|
/// Adapter that allows relayers pallet to be used as a delivery+dispatch payment mechanism
|
||||||
/// for the messages pallet.
|
/// for the messages pallet.
|
||||||
pub struct DeliveryConfirmationPaymentsAdapter<T, MI, DeliveryReward, ConfirmationReward>(
|
pub struct DeliveryConfirmationPaymentsAdapter<T, MI, DeliveryReward>(
|
||||||
PhantomData<(T, MI, DeliveryReward, ConfirmationReward)>,
|
PhantomData<(T, MI, DeliveryReward)>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<T, MI, DeliveryReward, ConfirmationReward> DeliveryConfirmationPayments<T::AccountId>
|
impl<T, MI, DeliveryReward> DeliveryConfirmationPayments<T::AccountId>
|
||||||
for DeliveryConfirmationPaymentsAdapter<T, MI, DeliveryReward, ConfirmationReward>
|
for DeliveryConfirmationPaymentsAdapter<T, MI, DeliveryReward>
|
||||||
where
|
where
|
||||||
T: Config + pallet_bridge_messages::Config<MI>,
|
T: Config + pallet_bridge_messages::Config<MI>,
|
||||||
MI: 'static,
|
MI: 'static,
|
||||||
DeliveryReward: Get<T::Reward>,
|
DeliveryReward: Get<T::Reward>,
|
||||||
ConfirmationReward: Get<T::Reward>,
|
|
||||||
{
|
{
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ where
|
|||||||
RewardsAccountOwner::BridgedChain,
|
RewardsAccountOwner::BridgedChain,
|
||||||
),
|
),
|
||||||
DeliveryReward::get(),
|
DeliveryReward::get(),
|
||||||
ConfirmationReward::get(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,32 +70,17 @@ fn register_relayers_rewards<T: Config>(
|
|||||||
relayers_rewards: RelayersRewards<T::AccountId>,
|
relayers_rewards: RelayersRewards<T::AccountId>,
|
||||||
lane_id: RewardsAccountParams,
|
lane_id: RewardsAccountParams,
|
||||||
delivery_fee: T::Reward,
|
delivery_fee: T::Reward,
|
||||||
confirmation_fee: T::Reward,
|
|
||||||
) {
|
) {
|
||||||
// reward every relayer except `confirmation_relayer`
|
// reward every relayer except `confirmation_relayer`
|
||||||
let mut confirmation_relayer_reward = T::Reward::zero();
|
let mut confirmation_relayer_reward = T::Reward::zero();
|
||||||
for (relayer, messages) in relayers_rewards {
|
for (relayer, messages) in relayers_rewards {
|
||||||
// sane runtime configurations guarantee that the number of messages will be below
|
// sane runtime configurations guarantee that the number of messages will be below
|
||||||
// `u32::MAX`
|
// `u32::MAX`
|
||||||
let mut relayer_reward =
|
let relayer_reward = T::Reward::saturated_from(messages).saturating_mul(delivery_fee);
|
||||||
T::Reward::unique_saturated_from(messages).saturating_mul(delivery_fee);
|
|
||||||
|
|
||||||
if relayer != *confirmation_relayer {
|
if relayer != *confirmation_relayer {
|
||||||
// If delivery confirmation is submitted by other relayer, let's deduct confirmation fee
|
|
||||||
// from relayer reward.
|
|
||||||
//
|
|
||||||
// If confirmation fee has been increased (or if it was the only component of message
|
|
||||||
// fee), then messages relayer may receive zero reward.
|
|
||||||
let mut confirmation_reward =
|
|
||||||
T::Reward::saturated_from(messages).saturating_mul(confirmation_fee);
|
|
||||||
confirmation_reward = sp_std::cmp::min(confirmation_reward, relayer_reward);
|
|
||||||
relayer_reward = relayer_reward.saturating_sub(confirmation_reward);
|
|
||||||
confirmation_relayer_reward =
|
|
||||||
confirmation_relayer_reward.saturating_add(confirmation_reward);
|
|
||||||
Pallet::<T>::register_relayer_reward(lane_id, &relayer, relayer_reward);
|
Pallet::<T>::register_relayer_reward(lane_id, &relayer, relayer_reward);
|
||||||
} else {
|
} else {
|
||||||
// If delivery confirmation is submitted by this relayer, let's add confirmation fee
|
|
||||||
// from other relayers to this relayer reward.
|
|
||||||
confirmation_relayer_reward =
|
confirmation_relayer_reward =
|
||||||
confirmation_relayer_reward.saturating_add(relayer_reward);
|
confirmation_relayer_reward.saturating_add(relayer_reward);
|
||||||
}
|
}
|
||||||
@@ -132,69 +115,41 @@ mod tests {
|
|||||||
relayers_rewards(),
|
relayers_rewards(),
|
||||||
TEST_REWARDS_ACCOUNT_PARAMS,
|
TEST_REWARDS_ACCOUNT_PARAMS,
|
||||||
50,
|
50,
|
||||||
10,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_1, TEST_REWARDS_ACCOUNT_PARAMS),
|
RelayerRewards::<TestRuntime>::get(RELAYER_1, TEST_REWARDS_ACCOUNT_PARAMS),
|
||||||
Some(80)
|
Some(100)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_2, TEST_REWARDS_ACCOUNT_PARAMS),
|
RelayerRewards::<TestRuntime>::get(RELAYER_2, TEST_REWARDS_ACCOUNT_PARAMS),
|
||||||
Some(170)
|
Some(150)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn confirmation_relayer_is_rewarded_if_it_has_not_delivered_any_delivered_messages() {
|
fn confirmation_relayer_is_not_rewarded_if_it_has_not_delivered_any_messages() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
register_relayers_rewards::<TestRuntime>(
|
register_relayers_rewards::<TestRuntime>(
|
||||||
&RELAYER_3,
|
&RELAYER_3,
|
||||||
relayers_rewards(),
|
relayers_rewards(),
|
||||||
TEST_REWARDS_ACCOUNT_PARAMS,
|
TEST_REWARDS_ACCOUNT_PARAMS,
|
||||||
50,
|
50,
|
||||||
10,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_1, TEST_REWARDS_ACCOUNT_PARAMS),
|
RelayerRewards::<TestRuntime>::get(RELAYER_1, TEST_REWARDS_ACCOUNT_PARAMS),
|
||||||
Some(80)
|
Some(100)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_2, TEST_REWARDS_ACCOUNT_PARAMS),
|
RelayerRewards::<TestRuntime>::get(RELAYER_2, TEST_REWARDS_ACCOUNT_PARAMS),
|
||||||
Some(120)
|
Some(150)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_3, TEST_REWARDS_ACCOUNT_PARAMS),
|
RelayerRewards::<TestRuntime>::get(RELAYER_3, TEST_REWARDS_ACCOUNT_PARAMS),
|
||||||
Some(50)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn only_confirmation_relayer_is_rewarded_if_confirmation_fee_has_significantly_increased() {
|
|
||||||
run_test(|| {
|
|
||||||
register_relayers_rewards::<TestRuntime>(
|
|
||||||
&RELAYER_3,
|
|
||||||
relayers_rewards(),
|
|
||||||
TEST_REWARDS_ACCOUNT_PARAMS,
|
|
||||||
50,
|
|
||||||
1000,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_1, TEST_REWARDS_ACCOUNT_PARAMS),
|
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
assert_eq!(
|
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_2, TEST_REWARDS_ACCOUNT_PARAMS),
|
|
||||||
None
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
RelayerRewards::<TestRuntime>::get(RELAYER_3, TEST_REWARDS_ACCOUNT_PARAMS),
|
|
||||||
Some(250)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user