mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 05:11:02 +00:00
committed by
Bastian Köcher
parent
06e0204694
commit
d80d2a5039
@@ -59,9 +59,9 @@ use bp_messages::{
|
|||||||
DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages,
|
DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages,
|
||||||
SourceHeaderChain,
|
SourceHeaderChain,
|
||||||
},
|
},
|
||||||
total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId,
|
DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, MessageKey, MessageNonce,
|
||||||
MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData,
|
MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails,
|
||||||
OutboundMessageDetails, UnrewardedRelayersState, VerificationError,
|
UnrewardedRelayersState, VerificationError,
|
||||||
};
|
};
|
||||||
use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, PreComputedSize, Size};
|
use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, PreComputedSize, Size};
|
||||||
use codec::{Decode, Encode, MaxEncodedLen};
|
use codec::{Decode, Encode, MaxEncodedLen};
|
||||||
@@ -437,21 +437,8 @@ pub mod pallet {
|
|||||||
|
|
||||||
Error::<T, I>::InvalidMessagesDeliveryProof
|
Error::<T, I>::InvalidMessagesDeliveryProof
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// verify that the relayer has declared correct `lane_data::relayers` state
|
|
||||||
// (we only care about total number of entries and messages, because this affects call
|
|
||||||
// weight)
|
|
||||||
ensure!(
|
ensure!(
|
||||||
total_unrewarded_messages(&lane_data.relayers).unwrap_or(MessageNonce::MAX) ==
|
relayers_state.is_valid(&lane_data),
|
||||||
relayers_state.total_messages &&
|
|
||||||
lane_data.relayers.len() as MessageNonce ==
|
|
||||||
relayers_state.unrewarded_relayer_entries,
|
|
||||||
Error::<T, I>::InvalidUnrewardedRelayersState
|
|
||||||
);
|
|
||||||
// the `last_delivered_nonce` field may also be used by the signed extension. Even
|
|
||||||
// though providing wrong value isn't critical, let's also check it here.
|
|
||||||
ensure!(
|
|
||||||
lane_data.last_delivered_nonce() == relayers_state.last_delivered_nonce,
|
|
||||||
Error::<T, I>::InvalidUnrewardedRelayersState
|
Error::<T, I>::InvalidUnrewardedRelayersState
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -975,9 +962,9 @@ mod tests {
|
|||||||
))),
|
))),
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
unrewarded_relayer_entries: 1,
|
unrewarded_relayer_entries: 1,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
total_messages: 1,
|
total_messages: 1,
|
||||||
last_delivered_nonce: 1,
|
last_delivered_nonce: 1,
|
||||||
..Default::default()
|
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -1341,9 +1328,9 @@ mod tests {
|
|||||||
single_message_delivery_proof,
|
single_message_delivery_proof,
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
unrewarded_relayer_entries: 1,
|
unrewarded_relayer_entries: 1,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
total_messages: 1,
|
total_messages: 1,
|
||||||
last_delivered_nonce: 1,
|
last_delivered_nonce: 1,
|
||||||
..Default::default()
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assert_ok!(result);
|
assert_ok!(result);
|
||||||
@@ -1381,9 +1368,9 @@ mod tests {
|
|||||||
two_messages_delivery_proof,
|
two_messages_delivery_proof,
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
unrewarded_relayer_entries: 2,
|
unrewarded_relayer_entries: 2,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
total_messages: 2,
|
total_messages: 2,
|
||||||
last_delivered_nonce: 2,
|
last_delivered_nonce: 2,
|
||||||
..Default::default()
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
assert_ok!(result);
|
assert_ok!(result);
|
||||||
@@ -1746,9 +1733,9 @@ mod tests {
|
|||||||
TestMessagesDeliveryProof(messages_1_and_2_proof),
|
TestMessagesDeliveryProof(messages_1_and_2_proof),
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
unrewarded_relayer_entries: 1,
|
unrewarded_relayer_entries: 1,
|
||||||
|
messages_in_oldest_entry: 2,
|
||||||
total_messages: 2,
|
total_messages: 2,
|
||||||
last_delivered_nonce: 2,
|
last_delivered_nonce: 2,
|
||||||
..Default::default()
|
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
// second tx with message 3
|
// second tx with message 3
|
||||||
@@ -1757,9 +1744,9 @@ mod tests {
|
|||||||
TestMessagesDeliveryProof(messages_3_proof),
|
TestMessagesDeliveryProof(messages_3_proof),
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
unrewarded_relayer_entries: 1,
|
unrewarded_relayer_entries: 1,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
total_messages: 1,
|
total_messages: 1,
|
||||||
last_delivered_nonce: 3,
|
last_delivered_nonce: 3,
|
||||||
..Default::default()
|
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -191,6 +191,17 @@ impl<RelayerId> InboundLaneData<RelayerId> {
|
|||||||
.map(|entry| entry.messages.end)
|
.map(|entry| entry.messages.end)
|
||||||
.unwrap_or(self.last_confirmed_nonce)
|
.unwrap_or(self.last_confirmed_nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the total number of messages in the `relayers` vector,
|
||||||
|
/// saturating in case of underflow or overflow.
|
||||||
|
pub fn total_unrewarded_messages(&self) -> MessageNonce {
|
||||||
|
let relayers = &self.relayers;
|
||||||
|
match (relayers.front(), relayers.back()) {
|
||||||
|
(Some(front), Some(back)) =>
|
||||||
|
(front.messages.begin..=back.messages.end).saturating_len(),
|
||||||
|
_ => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outbound message details, returned by runtime APIs.
|
/// Outbound message details, returned by runtime APIs.
|
||||||
@@ -287,7 +298,7 @@ impl DeliveredMessages {
|
|||||||
|
|
||||||
/// Return total count of delivered messages.
|
/// Return total count of delivered messages.
|
||||||
pub fn total_messages(&self) -> MessageNonce {
|
pub fn total_messages(&self) -> MessageNonce {
|
||||||
(self.begin..=self.end).checked_len().unwrap_or(0)
|
(self.begin..=self.end).saturating_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note new dispatched message.
|
/// Note new dispatched message.
|
||||||
@@ -318,6 +329,13 @@ pub struct UnrewardedRelayersState {
|
|||||||
pub last_delivered_nonce: MessageNonce,
|
pub last_delivered_nonce: MessageNonce,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl UnrewardedRelayersState {
|
||||||
|
// Verify that the relayers state corresponds with the `InboundLaneData`.
|
||||||
|
pub fn is_valid<RelayerId>(&self, lane_data: &InboundLaneData<RelayerId>) -> bool {
|
||||||
|
self == &lane_data.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<RelayerId> From<&InboundLaneData<RelayerId>> for UnrewardedRelayersState {
|
impl<RelayerId> From<&InboundLaneData<RelayerId>> for UnrewardedRelayersState {
|
||||||
fn from(lane: &InboundLaneData<RelayerId>) -> UnrewardedRelayersState {
|
fn from(lane: &InboundLaneData<RelayerId>) -> UnrewardedRelayersState {
|
||||||
UnrewardedRelayersState {
|
UnrewardedRelayersState {
|
||||||
@@ -325,9 +343,9 @@ impl<RelayerId> From<&InboundLaneData<RelayerId>> for UnrewardedRelayersState {
|
|||||||
messages_in_oldest_entry: lane
|
messages_in_oldest_entry: lane
|
||||||
.relayers
|
.relayers
|
||||||
.front()
|
.front()
|
||||||
.and_then(|entry| (entry.messages.begin..=entry.messages.end).checked_len())
|
.map(|entry| entry.messages.total_messages())
|
||||||
.unwrap_or(0),
|
.unwrap_or(0),
|
||||||
total_messages: total_unrewarded_messages(&lane.relayers).unwrap_or(MessageNonce::MAX),
|
total_messages: lane.total_unrewarded_messages(),
|
||||||
last_delivered_nonce: lane.last_delivered_nonce(),
|
last_delivered_nonce: lane.last_delivered_nonce(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,24 +375,6 @@ impl Default for OutboundLaneData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns total number of messages in the `InboundLaneData::relayers` vector.
|
|
||||||
///
|
|
||||||
/// Returns `None` if there are more messages that `MessageNonce` may fit (i.e. `MessageNonce + 1`).
|
|
||||||
pub fn total_unrewarded_messages<RelayerId>(
|
|
||||||
relayers: &VecDeque<UnrewardedRelayer<RelayerId>>,
|
|
||||||
) -> Option<MessageNonce> {
|
|
||||||
match (relayers.front(), relayers.back()) {
|
|
||||||
(Some(front), Some(back)) => {
|
|
||||||
if let Some(difference) = back.messages.end.checked_sub(front.messages.begin) {
|
|
||||||
difference.checked_add(1)
|
|
||||||
} else {
|
|
||||||
Some(0)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => Some(0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculate the number of messages that the relayers have delivered.
|
/// Calculate the number of messages that the relayers have delivered.
|
||||||
pub fn calc_relayers_rewards<AccountId>(
|
pub fn calc_relayers_rewards<AccountId>(
|
||||||
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
|
messages_relayers: VecDeque<UnrewardedRelayer<AccountId>>,
|
||||||
@@ -447,20 +447,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn total_unrewarded_messages_does_not_overflow() {
|
fn total_unrewarded_messages_does_not_overflow() {
|
||||||
assert_eq!(
|
let lane_data = InboundLaneData {
|
||||||
total_unrewarded_messages(
|
relayers: vec![
|
||||||
&vec![
|
UnrewardedRelayer { relayer: 1, messages: DeliveredMessages::new(0) },
|
||||||
UnrewardedRelayer { relayer: 1, messages: DeliveredMessages::new(0) },
|
UnrewardedRelayer {
|
||||||
UnrewardedRelayer {
|
relayer: 2,
|
||||||
relayer: 2,
|
messages: DeliveredMessages::new(MessageNonce::MAX),
|
||||||
messages: DeliveredMessages::new(MessageNonce::MAX)
|
},
|
||||||
},
|
]
|
||||||
]
|
.into_iter()
|
||||||
.into_iter()
|
.collect(),
|
||||||
.collect()
|
last_confirmed_nonce: 0,
|
||||||
),
|
};
|
||||||
None,
|
assert_eq!(lane_data.total_unrewarded_messages(), MessageNonce::MAX);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ pub use chain::{
|
|||||||
UnderlyingChainProvider,
|
UnderlyingChainProvider,
|
||||||
};
|
};
|
||||||
pub use frame_support::storage::storage_prefix as storage_value_final_key;
|
pub use frame_support::storage::storage_prefix as storage_value_final_key;
|
||||||
use num_traits::{CheckedAdd, CheckedSub, One};
|
use num_traits::{CheckedAdd, CheckedSub, One, SaturatingAdd, Zero};
|
||||||
pub use storage_proof::{
|
pub use storage_proof::{
|
||||||
record_all_keys as record_all_trie_keys, Error as StorageProofError,
|
record_all_keys as record_all_trie_keys, Error as StorageProofError,
|
||||||
ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker,
|
ProofSize as StorageProofSize, RawStorageProof, StorageProofChecker,
|
||||||
@@ -527,17 +527,27 @@ impl<T> Debug for StrippableError<T> {
|
|||||||
pub trait RangeInclusiveExt<Idx> {
|
pub trait RangeInclusiveExt<Idx> {
|
||||||
/// Computes the length of the `RangeInclusive`, checking for underflow and overflow.
|
/// Computes the length of the `RangeInclusive`, checking for underflow and overflow.
|
||||||
fn checked_len(&self) -> Option<Idx>;
|
fn checked_len(&self) -> Option<Idx>;
|
||||||
|
/// Computes the length of the `RangeInclusive`, saturating in case of underflow or overflow.
|
||||||
|
fn saturating_len(&self) -> Idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Idx> RangeInclusiveExt<Idx> for RangeInclusive<Idx>
|
impl<Idx> RangeInclusiveExt<Idx> for RangeInclusive<Idx>
|
||||||
where
|
where
|
||||||
Idx: CheckedSub + CheckedAdd + One,
|
Idx: CheckedSub + CheckedAdd + SaturatingAdd + One + Zero,
|
||||||
{
|
{
|
||||||
fn checked_len(&self) -> Option<Idx> {
|
fn checked_len(&self) -> Option<Idx> {
|
||||||
self.end()
|
self.end()
|
||||||
.checked_sub(self.start())
|
.checked_sub(self.start())
|
||||||
.and_then(|len| len.checked_add(&Idx::one()))
|
.and_then(|len| len.checked_add(&Idx::one()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn saturating_len(&self) -> Idx {
|
||||||
|
let len = match self.end().checked_sub(self.start()) {
|
||||||
|
Some(len) => len,
|
||||||
|
None => return Idx::zero(),
|
||||||
|
};
|
||||||
|
len.saturating_add(&Idx::one())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ use crate::{
|
|||||||
use async_std::sync::Arc;
|
use async_std::sync::Arc;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_messages::{
|
use bp_messages::{
|
||||||
storage_keys::inbound_lane_data_key, total_unrewarded_messages, InboundLaneData, LaneId,
|
storage_keys::inbound_lane_data_key, InboundLaneData, LaneId, MessageNonce,
|
||||||
MessageNonce, UnrewardedRelayersState,
|
UnrewardedRelayersState,
|
||||||
};
|
};
|
||||||
use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof;
|
use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof;
|
||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
@@ -45,7 +45,7 @@ use relay_substrate_client::{
|
|||||||
};
|
};
|
||||||
use relay_utils::relay_loop::Client as RelayClient;
|
use relay_utils::relay_loop::Client as RelayClient;
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use std::{collections::VecDeque, convert::TryFrom, ops::RangeInclusive};
|
use std::{convert::TryFrom, ops::RangeInclusive};
|
||||||
|
|
||||||
/// Message receiving proof returned by the target Substrate node.
|
/// Message receiving proof returned by the target Substrate node.
|
||||||
pub type SubstrateMessagesDeliveryProof<C> =
|
pub type SubstrateMessagesDeliveryProof<C> =
|
||||||
@@ -197,20 +197,9 @@ where
|
|||||||
id: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
id: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
||||||
) -> Result<(TargetHeaderIdOf<MessageLaneAdapter<P>>, UnrewardedRelayersState), SubstrateError>
|
) -> Result<(TargetHeaderIdOf<MessageLaneAdapter<P>>, UnrewardedRelayersState), SubstrateError>
|
||||||
{
|
{
|
||||||
let inbound_lane_data = self.inbound_lane_data(id).await?;
|
let inbound_lane_data =
|
||||||
let last_delivered_nonce =
|
self.inbound_lane_data(id).await?.unwrap_or(InboundLaneData::default());
|
||||||
inbound_lane_data.as_ref().map(|data| data.last_delivered_nonce()).unwrap_or(0);
|
Ok((id, (&inbound_lane_data).into()))
|
||||||
let relayers = inbound_lane_data.map(|data| data.relayers).unwrap_or_else(VecDeque::new);
|
|
||||||
let unrewarded_relayers_state = bp_messages::UnrewardedRelayersState {
|
|
||||||
unrewarded_relayer_entries: relayers.len() as _,
|
|
||||||
messages_in_oldest_entry: relayers
|
|
||||||
.front()
|
|
||||||
.map(|entry| 1 + entry.messages.end - entry.messages.begin)
|
|
||||||
.unwrap_or(0),
|
|
||||||
total_messages: total_unrewarded_messages(&relayers).unwrap_or(MessageNonce::MAX),
|
|
||||||
last_delivered_nonce,
|
|
||||||
};
|
|
||||||
Ok((id, unrewarded_relayers_state))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn prove_messages_receiving(
|
async fn prove_messages_receiving(
|
||||||
|
|||||||
Reference in New Issue
Block a user