mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-24 09:01:08 +00:00
Limit max number of unconfirmed messages at inbound lane (#545)
* limit maximal number of unconfirmed messages at inbound lane * unrewarded_relayer_entries API * change relay to support max unrewarded relayer entries * Update modules/message-lane/src/inbound_lane.rs Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update relays/messages-relay/src/message_lane_loop.rs Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * removed pub Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
93b3d49047
commit
2944f997d1
@@ -322,6 +322,8 @@ impl pallet_shift_session_manager::Trait for Runtime {}
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MaxMessagesToPruneAtOnce: bp_message_lane::MessageNonce = 8;
|
pub const MaxMessagesToPruneAtOnce: bp_message_lane::MessageNonce = 8;
|
||||||
|
pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_message_lane::MessageNonce =
|
||||||
|
bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE;
|
||||||
pub const MaxUnconfirmedMessagesAtInboundLane: bp_message_lane::MessageNonce =
|
pub const MaxUnconfirmedMessagesAtInboundLane: bp_message_lane::MessageNonce =
|
||||||
bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
|
bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
|
||||||
pub const MaxMessagesInDeliveryTransaction: bp_message_lane::MessageNonce =
|
pub const MaxMessagesInDeliveryTransaction: bp_message_lane::MessageNonce =
|
||||||
@@ -331,6 +333,7 @@ parameter_types! {
|
|||||||
impl pallet_message_lane::Trait for Runtime {
|
impl pallet_message_lane::Trait for Runtime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
||||||
|
|
||||||
@@ -580,5 +583,9 @@ impl_runtime_apis! {
|
|||||||
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
||||||
BridgeRialtoMessageLane::inbound_latest_confirmed_nonce(lane)
|
BridgeRialtoMessageLane::inbound_latest_confirmed_nonce(lane)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unrewarded_relayers_state(lane: bp_message_lane::LaneId) -> bp_message_lane::UnrewardedRelayersState {
|
||||||
|
BridgeRialtoMessageLane::inbound_unrewarded_relayers_state(lane)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -429,6 +429,8 @@ impl pallet_shift_session_manager::Trait for Runtime {}
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MaxMessagesToPruneAtOnce: bp_message_lane::MessageNonce = 8;
|
pub const MaxMessagesToPruneAtOnce: bp_message_lane::MessageNonce = 8;
|
||||||
|
pub const MaxUnrewardedRelayerEntriesAtInboundLane: bp_message_lane::MessageNonce =
|
||||||
|
bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE;
|
||||||
pub const MaxUnconfirmedMessagesAtInboundLane: bp_message_lane::MessageNonce =
|
pub const MaxUnconfirmedMessagesAtInboundLane: bp_message_lane::MessageNonce =
|
||||||
bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
|
bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE;
|
||||||
pub const MaxMessagesInDeliveryTransaction: bp_message_lane::MessageNonce =
|
pub const MaxMessagesInDeliveryTransaction: bp_message_lane::MessageNonce =
|
||||||
@@ -438,6 +440,7 @@ parameter_types! {
|
|||||||
impl pallet_message_lane::Trait for Runtime {
|
impl pallet_message_lane::Trait for Runtime {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
||||||
|
|
||||||
@@ -743,6 +746,10 @@ impl_runtime_apis! {
|
|||||||
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
fn latest_confirmed_nonce(lane: bp_message_lane::LaneId) -> bp_message_lane::MessageNonce {
|
||||||
BridgeMillauMessageLane::inbound_latest_confirmed_nonce(lane)
|
BridgeMillauMessageLane::inbound_latest_confirmed_nonce(lane)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unrewarded_relayers_state(lane: bp_message_lane::LaneId) -> bp_message_lane::UnrewardedRelayersState {
|
||||||
|
BridgeMillauMessageLane::inbound_unrewarded_relayers_state(lane)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ pub trait InboundLaneStorage {
|
|||||||
|
|
||||||
/// Lane id.
|
/// Lane id.
|
||||||
fn id(&self) -> LaneId;
|
fn id(&self) -> LaneId;
|
||||||
|
/// Return maximal number of unrewarded relayer entries in inbound lane.
|
||||||
|
fn max_unrewarded_relayer_entries(&self) -> MessageNonce;
|
||||||
/// Return maximal number of unconfirmed messages in inbound lane.
|
/// Return maximal number of unconfirmed messages in inbound lane.
|
||||||
fn max_unconfirmed_messages(&self) -> MessageNonce;
|
fn max_unconfirmed_messages(&self) -> MessageNonce;
|
||||||
/// Get lane data from the storage.
|
/// Get lane data from the storage.
|
||||||
@@ -97,8 +99,14 @@ impl<S: InboundLaneStorage> InboundLane<S> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if there are more unrewarded relayer entries than we may accept, reject this message
|
||||||
|
if data.relayers.len() as MessageNonce >= self.storage.max_unrewarded_relayer_entries() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// if there are more unconfirmed messages than we may accept, reject this message
|
// if there are more unconfirmed messages than we may accept, reject this message
|
||||||
if self.storage.max_unconfirmed_messages() <= data.relayers.len() as MessageNonce {
|
let unconfirmed_messages_count = nonce.saturating_sub(data.latest_confirmed_nonce);
|
||||||
|
if unconfirmed_messages_count > self.storage.max_unconfirmed_messages() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,10 +279,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fails_to_receive_messages_above_max_limit_per_lane() {
|
fn fails_to_receive_messages_above_unrewarded_relayer_entries_limit_per_lane() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
let mut lane = inbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
let mut lane = inbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||||
let max_nonce = <TestRuntime as crate::Trait>::MaxUnconfirmedMessagesAtInboundLane::get();
|
let max_nonce = <TestRuntime as crate::Trait>::MaxUnrewardedRelayerEntriesAtInboundLane::get();
|
||||||
for current_nonce in 1..max_nonce + 1 {
|
for current_nonce in 1..max_nonce + 1 {
|
||||||
assert!(lane.receive_message::<TestMessageDispatch>(
|
assert!(lane.receive_message::<TestMessageDispatch>(
|
||||||
TEST_RELAYER_A + current_nonce,
|
TEST_RELAYER_A + current_nonce,
|
||||||
@@ -303,6 +311,39 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fails_to_receive_messages_above_unconfirmed_messages_limit_per_lane() {
|
||||||
|
run_test(|| {
|
||||||
|
let mut lane = inbound_lane::<TestRuntime, _>(TEST_LANE_ID);
|
||||||
|
let max_nonce = <TestRuntime as crate::Trait>::MaxUnconfirmedMessagesAtInboundLane::get();
|
||||||
|
for current_nonce in 1..=max_nonce {
|
||||||
|
assert!(lane.receive_message::<TestMessageDispatch>(
|
||||||
|
TEST_RELAYER_A,
|
||||||
|
current_nonce,
|
||||||
|
message_data(REGULAR_PAYLOAD).into()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
// Fails to dispatch new message from different than latest relayer.
|
||||||
|
assert_eq!(
|
||||||
|
false,
|
||||||
|
lane.receive_message::<TestMessageDispatch>(
|
||||||
|
TEST_RELAYER_B,
|
||||||
|
max_nonce + 1,
|
||||||
|
message_data(REGULAR_PAYLOAD).into()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// Fails to dispatch new messages from latest relayer.
|
||||||
|
assert_eq!(
|
||||||
|
false,
|
||||||
|
lane.receive_message::<TestMessageDispatch>(
|
||||||
|
TEST_RELAYER_A,
|
||||||
|
max_nonce + 1,
|
||||||
|
message_data(REGULAR_PAYLOAD).into()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn correctly_receives_following_messages_from_two_relayers_alternately() {
|
fn correctly_receives_following_messages_from_two_relayers_alternately() {
|
||||||
run_test(|| {
|
run_test(|| {
|
||||||
|
|||||||
@@ -75,16 +75,20 @@ pub trait Trait<I = DefaultInstance>: frame_system::Trait {
|
|||||||
/// confirmed. The reason is that if you want to use lane, you should be ready to pay
|
/// confirmed. The reason is that if you want to use lane, you should be ready to pay
|
||||||
/// for it.
|
/// for it.
|
||||||
type MaxMessagesToPruneAtOnce: Get<MessageNonce>;
|
type MaxMessagesToPruneAtOnce: Get<MessageNonce>;
|
||||||
/// Maximal number of "messages" (see note below) in the 'unconfirmed' state at inbound lane.
|
/// Maximal number of unrewarded relayer entries at inbound lane. Unrewarded means that the
|
||||||
/// Unconfirmed message at inbound lane is the message that has been: sent, delivered and
|
/// relayer has delivered messages, but either confirmations haven't been delivered back to the
|
||||||
/// dispatched. Its delivery confirmation is still pending. This limit is introduced to bound
|
/// source chain, or we haven't received reward confirmations yet.
|
||||||
/// maximal number of relayers-ids in the inbound lane state.
|
|
||||||
///
|
///
|
||||||
/// "Message" in this context does not necessarily mean an individual message, but instead
|
/// This constant limits maximal number of entries in the `InboundLaneData::relayers`. Keep
|
||||||
/// continuous range of individual messages, that are delivered by single relayer. So if relayer#1
|
/// in mind that the same relayer account may take several (non-consecutive) entries in this
|
||||||
/// has submitted delivery transaction#1 with individual messages [1; 2] and then delivery
|
/// set.
|
||||||
/// transaction#2 with individual messages [3; 4], this would be treated as single "Message" and
|
type MaxUnrewardedRelayerEntriesAtInboundLane: Get<MessageNonce>;
|
||||||
/// would occupy single unit of `MaxUnconfirmedMessagesAtInboundLane` limit.
|
/// Maximal number of unconfirmed messages at inbound lane. Unconfirmed means that the
|
||||||
|
/// message has been delivered, but either confirmations haven't been delivered back to the
|
||||||
|
/// source chain, or we haven't received reward confirmations for these messages yet.
|
||||||
|
///
|
||||||
|
/// This constant limits difference between last message from last entry of the
|
||||||
|
/// `InboundLaneData::relayers` and first message at the first entry.
|
||||||
type MaxUnconfirmedMessagesAtInboundLane: Get<MessageNonce>;
|
type MaxUnconfirmedMessagesAtInboundLane: Get<MessageNonce>;
|
||||||
/// Maximal number of messages in single delivery transaction. This directly affects the base
|
/// Maximal number of messages in single delivery transaction. This directly affects the base
|
||||||
/// weight of the delivery transaction.
|
/// weight of the delivery transaction.
|
||||||
@@ -481,6 +485,17 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
|
|||||||
pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce {
|
pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce {
|
||||||
InboundLanes::<T, I>::get(&lane).latest_confirmed_nonce
|
InboundLanes::<T, I>::get(&lane).latest_confirmed_nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get state of unrewarded relayers set.
|
||||||
|
pub fn inbound_unrewarded_relayers_state(
|
||||||
|
lane: bp_message_lane::LaneId,
|
||||||
|
) -> bp_message_lane::UnrewardedRelayersState {
|
||||||
|
let relayers = InboundLanes::<T, I>::get(&lane).relayers;
|
||||||
|
bp_message_lane::UnrewardedRelayersState {
|
||||||
|
unrewarded_relayer_entries: relayers.len() as _,
|
||||||
|
messages_in_oldest_entry: relayers.front().map(|(begin, end, _)| 1 + end - begin).unwrap_or(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Getting storage keys for messages and lanes states. These keys are normally used when building
|
/// Getting storage keys for messages and lanes states. These keys are normally used when building
|
||||||
@@ -569,6 +584,10 @@ impl<T: Trait<I>, I: Instance> InboundLaneStorage for RuntimeInboundLaneStorage<
|
|||||||
self.lane_id
|
self.lane_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn max_unrewarded_relayer_entries(&self) -> MessageNonce {
|
||||||
|
T::MaxUnrewardedRelayerEntriesAtInboundLane::get()
|
||||||
|
}
|
||||||
|
|
||||||
fn max_unconfirmed_messages(&self) -> MessageNonce {
|
fn max_unconfirmed_messages(&self) -> MessageNonce {
|
||||||
T::MaxUnconfirmedMessagesAtInboundLane::get()
|
T::MaxUnconfirmedMessagesAtInboundLane::get()
|
||||||
}
|
}
|
||||||
@@ -681,6 +700,7 @@ mod tests {
|
|||||||
message, run_test, Origin, TestEvent, TestMessageDeliveryAndDispatchPayment, TestMessagesProof, TestRuntime,
|
message, run_test, Origin, TestEvent, TestMessageDeliveryAndDispatchPayment, TestMessagesProof, TestRuntime,
|
||||||
PAYLOAD_REJECTED_BY_TARGET_CHAIN, 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 frame_support::{assert_noop, assert_ok};
|
use frame_support::{assert_noop, assert_ok};
|
||||||
use frame_system::{EventRecord, Module as System, Phase};
|
use frame_system::{EventRecord, Module as System, Phase};
|
||||||
use hex_literal::hex;
|
use hex_literal::hex;
|
||||||
@@ -916,6 +936,13 @@ mod tests {
|
|||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Module::<TestRuntime>::inbound_unrewarded_relayers_state(TEST_LANE_ID),
|
||||||
|
UnrewardedRelayersState {
|
||||||
|
unrewarded_relayer_entries: 2,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// message proof includes outbound lane state with latest confirmed message updated to 9
|
// message proof includes outbound lane state with latest confirmed message updated to 9
|
||||||
let mut message_proof: TestMessagesProof = Ok(vec![message(11, REGULAR_PAYLOAD)]).into();
|
let mut message_proof: TestMessagesProof = Ok(vec![message(11, REGULAR_PAYLOAD)]).into();
|
||||||
@@ -941,6 +968,13 @@ mod tests {
|
|||||||
latest_confirmed_nonce: 9,
|
latest_confirmed_nonce: 9,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Module::<TestRuntime>::inbound_unrewarded_relayers_state(TEST_LANE_ID),
|
||||||
|
UnrewardedRelayersState {
|
||||||
|
unrewarded_relayer_entries: 2,
|
||||||
|
messages_in_oldest_entry: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,13 +99,15 @@ impl frame_system::Trait for TestRuntime {
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const MaxMessagesToPruneAtOnce: u64 = 10;
|
pub const MaxMessagesToPruneAtOnce: u64 = 10;
|
||||||
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 16;
|
pub const MaxUnrewardedRelayerEntriesAtInboundLane: u64 = 16;
|
||||||
|
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 32;
|
||||||
pub const MaxMessagesInDeliveryTransaction: u64 = 128;
|
pub const MaxMessagesInDeliveryTransaction: u64 = 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Trait for TestRuntime {
|
impl Trait for TestRuntime {
|
||||||
type Event = TestEvent;
|
type Event = TestEvent;
|
||||||
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
|
||||||
|
type MaxUnrewardedRelayerEntriesAtInboundLane = MaxUnrewardedRelayerEntriesAtInboundLane;
|
||||||
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
|
||||||
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
type MaxMessagesInDeliveryTransaction = MaxMessagesInDeliveryTransaction;
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,16 @@ impl<RelayerId> Default for InboundLaneData<RelayerId> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gist of `InboundLaneData::relayers` field used by runtime APIs.
|
||||||
|
#[derive(Clone, Encode, Decode, RuntimeDebug, PartialEq, Eq)]
|
||||||
|
pub struct UnrewardedRelayersState {
|
||||||
|
/// Number of entries in the `InboundLaneData::relayers` set.
|
||||||
|
pub unrewarded_relayer_entries: MessageNonce,
|
||||||
|
/// Number of messages in the oldest entry of `InboundLaneData::relayers`. This is the
|
||||||
|
/// minimal number of reward proofs required to push out this entry from the set.
|
||||||
|
pub messages_in_oldest_entry: MessageNonce,
|
||||||
|
}
|
||||||
|
|
||||||
/// Outbound lane data.
|
/// Outbound lane data.
|
||||||
#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)]
|
#[derive(Encode, Decode, Clone, RuntimeDebug, PartialEq, Eq)]
|
||||||
pub struct OutboundLaneData {
|
pub struct OutboundLaneData {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
mod millau_hash;
|
mod millau_hash;
|
||||||
|
|
||||||
use bp_message_lane::{LaneId, MessageNonce};
|
use bp_message_lane::{LaneId, MessageNonce, UnrewardedRelayersState};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use frame_support::{weights::Weight, RuntimeDebug};
|
use frame_support::{weights::Weight, RuntimeDebug};
|
||||||
use sp_core::Hasher as HasherT;
|
use sp_core::Hasher as HasherT;
|
||||||
@@ -83,6 +83,8 @@ pub const MAXIMUM_EXTRINSIC_SIZE: u32 = MAXIMUM_BLOCK_SIZE / 100 * AVAILABLE_BLO
|
|||||||
// TODO: may need to be updated after https://github.com/paritytech/parity-bridges-common/issues/78
|
// TODO: may need to be updated after https://github.com/paritytech/parity-bridges-common/issues/78
|
||||||
/// Maximal number of messages in single delivery transaction.
|
/// Maximal number of messages in single delivery transaction.
|
||||||
pub const MAX_MESSAGES_IN_DELIVERY_TRANSACTION: MessageNonce = 1024;
|
pub const MAX_MESSAGES_IN_DELIVERY_TRANSACTION: MessageNonce = 1024;
|
||||||
|
/// Maximal number of unrewarded relayer entries at inbound lane.
|
||||||
|
pub const MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE: MessageNonce = 1024;
|
||||||
/// Maximal number of unconfirmed messages at inbound lane.
|
/// Maximal number of unconfirmed messages at inbound lane.
|
||||||
pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 1024;
|
pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 1024;
|
||||||
|
|
||||||
@@ -129,6 +131,8 @@ pub const TO_MILLAU_LATEST_GENERATED_NONCE_METHOD: &str = "ToMillauOutboundLaneA
|
|||||||
pub const FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_received_nonce";
|
pub const FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_received_nonce";
|
||||||
/// Name of the `FromMillauInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
/// Name of the `FromMillauInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
||||||
pub const FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_confirmed_nonce";
|
pub const FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromMillauInboundLaneApi_latest_confirmed_nonce";
|
||||||
|
/// Name of the `FromMillauInboundLaneApi::unrewarded_relayers_state` runtime method.
|
||||||
|
pub const FROM_MILLAU_UNREWARDED_RELAYERS_STATE: &str = "FromMillauInboundLaneApi_unrewarded_relayers_state";
|
||||||
|
|
||||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||||
pub type Signature = MultiSignature;
|
pub type Signature = MultiSignature;
|
||||||
@@ -206,5 +210,7 @@ sp_api::decl_runtime_apis! {
|
|||||||
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
||||||
/// Nonce of latest message that has been confirmed to the bridged chain.
|
/// Nonce of latest message that has been confirmed to the bridged chain.
|
||||||
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
/// State of the unrewarded relayers set at given lane.
|
||||||
|
fn unrewarded_relayers_state(lane: LaneId) -> UnrewardedRelayersState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
// Runtime-generated DecodeLimit::decode_all_With_depth_limit
|
// Runtime-generated DecodeLimit::decode_all_With_depth_limit
|
||||||
#![allow(clippy::unnecessary_mut_passed)]
|
#![allow(clippy::unnecessary_mut_passed)]
|
||||||
|
|
||||||
use bp_message_lane::{LaneId, MessageNonce};
|
use bp_message_lane::{LaneId, MessageNonce, UnrewardedRelayersState};
|
||||||
use bp_runtime::Chain;
|
use bp_runtime::Chain;
|
||||||
use frame_support::{weights::Weight, RuntimeDebug};
|
use frame_support::{weights::Weight, RuntimeDebug};
|
||||||
use sp_core::Hasher as HasherT;
|
use sp_core::Hasher as HasherT;
|
||||||
@@ -45,6 +45,8 @@ pub const MAXIMUM_EXTRINSIC_SIZE: u32 = MAXIMUM_BLOCK_SIZE / 100 * AVAILABLE_BLO
|
|||||||
// TODO: may need to be updated after https://github.com/paritytech/parity-bridges-common/issues/78
|
// TODO: may need to be updated after https://github.com/paritytech/parity-bridges-common/issues/78
|
||||||
/// Maximal number of messages in single delivery transaction.
|
/// Maximal number of messages in single delivery transaction.
|
||||||
pub const MAX_MESSAGES_IN_DELIVERY_TRANSACTION: MessageNonce = 128;
|
pub const MAX_MESSAGES_IN_DELIVERY_TRANSACTION: MessageNonce = 128;
|
||||||
|
/// Maximal number of unrewarded relayer entries at inbound lane.
|
||||||
|
pub const MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE: MessageNonce = 128;
|
||||||
/// Maximal number of unconfirmed messages at inbound lane.
|
/// Maximal number of unconfirmed messages at inbound lane.
|
||||||
pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 128;
|
pub const MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE: MessageNonce = 128;
|
||||||
|
|
||||||
@@ -91,6 +93,8 @@ pub const TO_RIALTO_LATEST_RECEIVED_NONCE_METHOD: &str = "ToRialtoOutboundLaneAp
|
|||||||
pub const FROM_RIALTO_LATEST_RECEIVED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_received_nonce";
|
pub const FROM_RIALTO_LATEST_RECEIVED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_received_nonce";
|
||||||
/// Name of the `FromRialtoInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
/// Name of the `FromRialtoInboundLaneApi::latest_onfirmed_nonce` runtime method.
|
||||||
pub const FROM_RIALTO_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_confirmed_nonce";
|
pub const FROM_RIALTO_LATEST_CONFIRMED_NONCE_METHOD: &str = "FromRialtoInboundLaneApi_latest_confirmed_nonce";
|
||||||
|
/// Name of the `FromRialtoInboundLaneApi::unrewarded_relayers_state` runtime method.
|
||||||
|
pub const FROM_RIALTO_UNREWARDED_RELAYERS_STATE: &str = "FromRialtoInboundLaneApi_unrewarded_relayers_state";
|
||||||
|
|
||||||
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
|
||||||
pub type Signature = MultiSignature;
|
pub type Signature = MultiSignature;
|
||||||
@@ -169,5 +173,7 @@ sp_api::decl_runtime_apis! {
|
|||||||
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
fn latest_received_nonce(lane: LaneId) -> MessageNonce;
|
||||||
/// Nonce of latest message that has been confirmed to the bridged chain.
|
/// Nonce of latest message that has been confirmed to the bridged chain.
|
||||||
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
fn latest_confirmed_nonce(lane: LaneId) -> MessageNonce;
|
||||||
|
/// State of the unrewarded relayers set at given lane.
|
||||||
|
fn unrewarded_relayers_state(lane: LaneId) -> UnrewardedRelayersState;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use crate::message_race_receiving::run as run_message_receiving_race;
|
|||||||
use crate::metrics::MessageLaneLoopMetrics;
|
use crate::metrics::MessageLaneLoopMetrics;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_message_lane::{LaneId, MessageNonce, Weight};
|
use bp_message_lane::{LaneId, MessageNonce, UnrewardedRelayersState, Weight};
|
||||||
use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt};
|
use futures::{channel::mpsc::unbounded, future::FutureExt, stream::StreamExt};
|
||||||
use relay_utils::{
|
use relay_utils::{
|
||||||
interval,
|
interval,
|
||||||
@@ -59,6 +59,10 @@ pub struct Params {
|
|||||||
/// Message delivery race parameters.
|
/// Message delivery race parameters.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MessageDeliveryParams {
|
pub struct MessageDeliveryParams {
|
||||||
|
/// Maximal number of unconfirmed relayer entries at the inbound lane. If there's that number of entries
|
||||||
|
/// in the `InboundLaneData::relayers` set, all new messages will be rejected until reward payment will
|
||||||
|
/// be proved (by including outbound lane state to the message delivery transaction).
|
||||||
|
pub max_unrewarded_relayer_entries_at_target: MessageNonce,
|
||||||
/// Message delivery race will stop delivering messages if there are `max_unconfirmed_nonces_at_target`
|
/// Message delivery race will stop delivering messages if there are `max_unconfirmed_nonces_at_target`
|
||||||
/// unconfirmed nonces on the target node. The race would continue once they're confirmed by the
|
/// unconfirmed nonces on the target node. The race would continue once they're confirmed by the
|
||||||
/// receiving race.
|
/// receiving race.
|
||||||
@@ -153,6 +157,11 @@ pub trait TargetClient<P: MessageLane>: Clone + Send + Sync {
|
|||||||
&self,
|
&self,
|
||||||
id: TargetHeaderIdOf<P>,
|
id: TargetHeaderIdOf<P>,
|
||||||
) -> Result<(TargetHeaderIdOf<P>, MessageNonce), Self::Error>;
|
) -> Result<(TargetHeaderIdOf<P>, MessageNonce), Self::Error>;
|
||||||
|
/// Get state of unrewarded relayers set at the inbound lane.
|
||||||
|
async fn unrewarded_relayers_state(
|
||||||
|
&self,
|
||||||
|
id: TargetHeaderIdOf<P>,
|
||||||
|
) -> Result<(TargetHeaderIdOf<P>, UnrewardedRelayersState), Self::Error>;
|
||||||
|
|
||||||
/// Prove messages receiving at given block.
|
/// Prove messages receiving at given block.
|
||||||
async fn prove_messages_receiving(
|
async fn prove_messages_receiving(
|
||||||
@@ -662,6 +671,19 @@ pub(crate) mod tests {
|
|||||||
Ok((id, data.target_latest_received_nonce))
|
Ok((id, data.target_latest_received_nonce))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn unrewarded_relayers_state(
|
||||||
|
&self,
|
||||||
|
id: TargetHeaderIdOf<TestMessageLane>,
|
||||||
|
) -> Result<(TargetHeaderIdOf<TestMessageLane>, UnrewardedRelayersState), Self::Error> {
|
||||||
|
Ok((
|
||||||
|
id,
|
||||||
|
UnrewardedRelayersState {
|
||||||
|
unrewarded_relayer_entries: 0,
|
||||||
|
messages_in_oldest_entry: 0,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
async fn latest_confirmed_received_nonce(
|
async fn latest_confirmed_received_nonce(
|
||||||
&self,
|
&self,
|
||||||
id: TargetHeaderIdOf<TestMessageLane>,
|
id: TargetHeaderIdOf<TestMessageLane>,
|
||||||
@@ -728,6 +750,7 @@ pub(crate) mod tests {
|
|||||||
reconnect_delay: Duration::from_millis(0),
|
reconnect_delay: Duration::from_millis(0),
|
||||||
stall_timeout: Duration::from_millis(60 * 1000),
|
stall_timeout: Duration::from_millis(60 * 1000),
|
||||||
delivery_params: MessageDeliveryParams {
|
delivery_params: MessageDeliveryParams {
|
||||||
|
max_unrewarded_relayer_entries_at_target: 4,
|
||||||
max_unconfirmed_nonces_at_target: 4,
|
max_unconfirmed_nonces_at_target: 4,
|
||||||
max_messages_in_single_batch: 4,
|
max_messages_in_single_batch: 4,
|
||||||
max_messages_weight_in_single_batch: 4,
|
max_messages_weight_in_single_batch: 4,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use crate::message_race_strategy::BasicStrategy;
|
|||||||
use crate::metrics::MessageLaneLoopMetrics;
|
use crate::metrics::MessageLaneLoopMetrics;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_message_lane::{MessageNonce, Weight};
|
use bp_message_lane::{MessageNonce, UnrewardedRelayersState, Weight};
|
||||||
use futures::stream::FusedStream;
|
use futures::stream::FusedStream;
|
||||||
use relay_utils::FailedClient;
|
use relay_utils::FailedClient;
|
||||||
use std::{collections::BTreeMap, marker::PhantomData, ops::RangeInclusive, time::Duration};
|
use std::{collections::BTreeMap, marker::PhantomData, ops::RangeInclusive, time::Duration};
|
||||||
@@ -56,6 +56,7 @@ pub async fn run<P: MessageLane>(
|
|||||||
target_state_updates,
|
target_state_updates,
|
||||||
stall_timeout,
|
stall_timeout,
|
||||||
MessageDeliveryStrategy::<P> {
|
MessageDeliveryStrategy::<P> {
|
||||||
|
max_unrewarded_relayer_entries_at_target: params.max_unrewarded_relayer_entries_at_target,
|
||||||
max_unconfirmed_nonces_at_target: params.max_unconfirmed_nonces_at_target,
|
max_unconfirmed_nonces_at_target: params.max_unconfirmed_nonces_at_target,
|
||||||
max_messages_in_single_batch: params.max_messages_in_single_batch,
|
max_messages_in_single_batch: params.max_messages_in_single_batch,
|
||||||
max_messages_weight_in_single_batch: params.max_messages_weight_in_single_batch,
|
max_messages_weight_in_single_batch: params.max_messages_weight_in_single_batch,
|
||||||
@@ -157,13 +158,15 @@ where
|
|||||||
C: MessageLaneTargetClient<P>,
|
C: MessageLaneTargetClient<P>,
|
||||||
{
|
{
|
||||||
type Error = C::Error;
|
type Error = C::Error;
|
||||||
|
type TargetNoncesData = DeliveryRaceTargetNoncesData;
|
||||||
|
|
||||||
async fn nonces(
|
async fn nonces(
|
||||||
&self,
|
&self,
|
||||||
at_block: TargetHeaderIdOf<P>,
|
at_block: TargetHeaderIdOf<P>,
|
||||||
) -> Result<(TargetHeaderIdOf<P>, TargetClientNonces), Self::Error> {
|
) -> Result<(TargetHeaderIdOf<P>, TargetClientNonces<DeliveryRaceTargetNoncesData>), Self::Error> {
|
||||||
let (at_block, latest_received_nonce) = self.client.latest_received_nonce(at_block).await?;
|
let (at_block, latest_received_nonce) = self.client.latest_received_nonce(at_block).await?;
|
||||||
let (at_block, latest_confirmed_nonce) = self.client.latest_confirmed_received_nonce(at_block).await?;
|
let (at_block, latest_confirmed_nonce) = self.client.latest_confirmed_received_nonce(at_block).await?;
|
||||||
|
let (at_block, unrewarded_relayers) = self.client.unrewarded_relayers_state(at_block).await?;
|
||||||
|
|
||||||
if let Some(metrics_msg) = self.metrics_msg.as_ref() {
|
if let Some(metrics_msg) = self.metrics_msg.as_ref() {
|
||||||
metrics_msg.update_target_latest_received_nonce::<P>(latest_received_nonce);
|
metrics_msg.update_target_latest_received_nonce::<P>(latest_received_nonce);
|
||||||
@@ -174,7 +177,10 @@ where
|
|||||||
at_block,
|
at_block,
|
||||||
TargetClientNonces {
|
TargetClientNonces {
|
||||||
latest_nonce: latest_received_nonce,
|
latest_nonce: latest_received_nonce,
|
||||||
confirmed_nonce: Some(latest_confirmed_nonce),
|
nonces_data: DeliveryRaceTargetNoncesData {
|
||||||
|
confirmed_nonce: latest_confirmed_nonce,
|
||||||
|
unrewarded_relayers,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -191,8 +197,21 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Additional nonces data from the target client used by message delivery race.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct DeliveryRaceTargetNoncesData {
|
||||||
|
/// Latest nonce that we know: (1) has been delivered to us (2) has been confirmed
|
||||||
|
/// back to the source node (by confirmations race) and (3) relayer has received
|
||||||
|
/// reward for (and this has been confirmed by the message delivery race).
|
||||||
|
confirmed_nonce: MessageNonce,
|
||||||
|
/// State of the unrewarded relayers set at the target node.
|
||||||
|
unrewarded_relayers: UnrewardedRelayersState,
|
||||||
|
}
|
||||||
|
|
||||||
/// Messages delivery strategy.
|
/// Messages delivery strategy.
|
||||||
struct MessageDeliveryStrategy<P: MessageLane> {
|
struct MessageDeliveryStrategy<P: MessageLane> {
|
||||||
|
/// Maximal unrewarded relayer entries at target client.
|
||||||
|
max_unrewarded_relayer_entries_at_target: MessageNonce,
|
||||||
/// Maximal unconfirmed nonces at target client.
|
/// Maximal unconfirmed nonces at target client.
|
||||||
max_unconfirmed_nonces_at_target: MessageNonce,
|
max_unconfirmed_nonces_at_target: MessageNonce,
|
||||||
/// Maximal number of messages in the single delivery transaction.
|
/// Maximal number of messages in the single delivery transaction.
|
||||||
@@ -202,7 +221,7 @@ struct MessageDeliveryStrategy<P: MessageLane> {
|
|||||||
/// Latest confirmed nonce at the source client.
|
/// Latest confirmed nonce at the source client.
|
||||||
latest_confirmed_nonce_at_source: Option<MessageNonce>,
|
latest_confirmed_nonce_at_source: Option<MessageNonce>,
|
||||||
/// Target nonces from the source client.
|
/// Target nonces from the source client.
|
||||||
target_nonces: Option<TargetClientNonces>,
|
target_nonces: Option<TargetClientNonces<DeliveryRaceTargetNoncesData>>,
|
||||||
/// Basic delivery strategy.
|
/// Basic delivery strategy.
|
||||||
strategy: MessageDeliveryStrategyBase<P>,
|
strategy: MessageDeliveryStrategyBase<P>,
|
||||||
}
|
}
|
||||||
@@ -221,6 +240,7 @@ impl<P: MessageLane> RaceStrategy<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::M
|
|||||||
{
|
{
|
||||||
type SourceNoncesRange = MessageWeightsMap;
|
type SourceNoncesRange = MessageWeightsMap;
|
||||||
type ProofParameters = MessageProofParameters;
|
type ProofParameters = MessageProofParameters;
|
||||||
|
type TargetNoncesData = DeliveryRaceTargetNoncesData;
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.strategy.is_empty()
|
self.strategy.is_empty()
|
||||||
@@ -245,22 +265,23 @@ impl<P: MessageLane> RaceStrategy<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::M
|
|||||||
|
|
||||||
fn target_nonces_updated(
|
fn target_nonces_updated(
|
||||||
&mut self,
|
&mut self,
|
||||||
nonces: TargetClientNonces,
|
nonces: TargetClientNonces<DeliveryRaceTargetNoncesData>,
|
||||||
race_state: &mut RaceState<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::MessagesProof>,
|
race_state: &mut RaceState<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::MessagesProof>,
|
||||||
) {
|
) {
|
||||||
self.target_nonces = Some(nonces.clone());
|
self.target_nonces = Some(nonces.clone());
|
||||||
self.strategy.target_nonces_updated(nonces, race_state)
|
self.strategy.target_nonces_updated(
|
||||||
|
TargetClientNonces {
|
||||||
|
latest_nonce: nonces.latest_nonce,
|
||||||
|
nonces_data: (),
|
||||||
|
},
|
||||||
|
race_state,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_nonces_to_deliver(
|
fn select_nonces_to_deliver(
|
||||||
&mut self,
|
&mut self,
|
||||||
race_state: &RaceState<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::MessagesProof>,
|
race_state: &RaceState<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::MessagesProof>,
|
||||||
) -> Option<(RangeInclusive<MessageNonce>, Self::ProofParameters)> {
|
) -> Option<(RangeInclusive<MessageNonce>, Self::ProofParameters)> {
|
||||||
const CONFIRMED_NONCE_PROOF: &str = "\
|
|
||||||
ClientNonces are crafted by MessageDeliveryRace(Source|Target);\
|
|
||||||
MessageDeliveryRace(Source|Target) always fills confirmed_nonce field;\
|
|
||||||
qed";
|
|
||||||
|
|
||||||
let latest_confirmed_nonce_at_source = self.latest_confirmed_nonce_at_source?;
|
let latest_confirmed_nonce_at_source = self.latest_confirmed_nonce_at_source?;
|
||||||
let target_nonces = self.target_nonces.as_ref()?;
|
let target_nonces = self.target_nonces.as_ref()?;
|
||||||
|
|
||||||
@@ -295,9 +316,28 @@ impl<P: MessageLane> RaceStrategy<SourceHeaderIdOf<P>, TargetHeaderIdOf<P>, P::M
|
|||||||
//
|
//
|
||||||
// Important note: we're including outbound state lane proof whenever there are unconfirmed nonces
|
// Important note: we're including outbound state lane proof whenever there are unconfirmed nonces
|
||||||
// on the target chain. Other strategy is to include it only if it's absolutely necessary.
|
// on the target chain. Other strategy is to include it only if it's absolutely necessary.
|
||||||
let latest_confirmed_nonce_at_target = target_nonces.confirmed_nonce.expect(CONFIRMED_NONCE_PROOF);
|
let latest_confirmed_nonce_at_target = target_nonces.nonces_data.confirmed_nonce;
|
||||||
let outbound_state_proof_required = latest_confirmed_nonce_at_target < latest_confirmed_nonce_at_source;
|
let outbound_state_proof_required = latest_confirmed_nonce_at_target < latest_confirmed_nonce_at_source;
|
||||||
|
|
||||||
|
// The target node would also reject messages if there are too many entries in the
|
||||||
|
// "unrewarded relayers" set. If we are unable to prove new rewards to the target node, then
|
||||||
|
// we should wait for confirmations race.
|
||||||
|
let unrewarded_relayer_entries_limit_reached =
|
||||||
|
target_nonces.nonces_data.unrewarded_relayers.unrewarded_relayer_entries
|
||||||
|
>= self.max_unrewarded_relayer_entries_at_target;
|
||||||
|
if unrewarded_relayer_entries_limit_reached {
|
||||||
|
// so there are already too many unrewarded relayer entries in the set
|
||||||
|
//
|
||||||
|
// => check if we can prove enough rewards. If not, we should wait for more rewards to be paid
|
||||||
|
let number_of_rewards_being_proved =
|
||||||
|
latest_confirmed_nonce_at_source.saturating_sub(latest_confirmed_nonce_at_target);
|
||||||
|
let enough_rewards_being_proved = number_of_rewards_being_proved
|
||||||
|
>= target_nonces.nonces_data.unrewarded_relayers.messages_in_oldest_entry;
|
||||||
|
if !enough_rewards_being_proved {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we're here, then the confirmations race did its job && sending side now knows that messages
|
// If we're here, then the confirmations race did its job && sending side now knows that messages
|
||||||
// have been delivered. Now let's select nonces that we want to deliver.
|
// have been delivered. Now let's select nonces that we want to deliver.
|
||||||
//
|
//
|
||||||
@@ -404,13 +444,20 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut race_strategy = TestStrategy {
|
let mut race_strategy = TestStrategy {
|
||||||
|
max_unrewarded_relayer_entries_at_target: 4,
|
||||||
max_unconfirmed_nonces_at_target: 4,
|
max_unconfirmed_nonces_at_target: 4,
|
||||||
max_messages_in_single_batch: 4,
|
max_messages_in_single_batch: 4,
|
||||||
max_messages_weight_in_single_batch: 4,
|
max_messages_weight_in_single_batch: 4,
|
||||||
latest_confirmed_nonce_at_source: Some(19),
|
latest_confirmed_nonce_at_source: Some(19),
|
||||||
target_nonces: Some(TargetClientNonces {
|
target_nonces: Some(TargetClientNonces {
|
||||||
latest_nonce: 19,
|
latest_nonce: 19,
|
||||||
confirmed_nonce: Some(19),
|
nonces_data: DeliveryRaceTargetNoncesData {
|
||||||
|
confirmed_nonce: 19,
|
||||||
|
unrewarded_relayers: UnrewardedRelayersState {
|
||||||
|
unrewarded_relayer_entries: 0,
|
||||||
|
messages_in_oldest_entry: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
strategy: BasicStrategy::new(),
|
strategy: BasicStrategy::new(),
|
||||||
};
|
};
|
||||||
@@ -422,9 +469,13 @@ mod tests {
|
|||||||
confirmed_nonce: Some(19),
|
confirmed_nonce: Some(19),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
race_strategy
|
race_strategy.strategy.target_nonces_updated(
|
||||||
.strategy
|
TargetClientNonces {
|
||||||
.target_nonces_updated(race_strategy.target_nonces.clone().unwrap(), &mut race_state);
|
latest_nonce: 19,
|
||||||
|
nonces_data: (),
|
||||||
|
},
|
||||||
|
&mut race_state,
|
||||||
|
);
|
||||||
|
|
||||||
(race_state, race_strategy)
|
(race_state, race_strategy)
|
||||||
}
|
}
|
||||||
@@ -483,7 +534,58 @@ mod tests {
|
|||||||
// if there are new confirmed nonces on source, we want to relay this information
|
// if there are new confirmed nonces on source, we want to relay this information
|
||||||
// to target to prune rewards queue
|
// to target to prune rewards queue
|
||||||
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
||||||
strategy.target_nonces.as_mut().unwrap().confirmed_nonce = Some(prev_confirmed_nonce_at_source - 1);
|
strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 1;
|
||||||
|
assert_eq!(
|
||||||
|
strategy.select_nonces_to_deliver(&state),
|
||||||
|
Some(((20..=23), proof_parameters(true, 4)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn message_delivery_strategy_selects_nothing_if_there_are_too_many_unrewarded_relayers() {
|
||||||
|
let (state, mut strategy) = prepare_strategy();
|
||||||
|
|
||||||
|
// if there are already `max_unrewarded_relayer_entries_at_target` entries at target,
|
||||||
|
// we need to wait until rewards will be paid
|
||||||
|
{
|
||||||
|
let mut unrewarded_relayers = &mut strategy.target_nonces.as_mut().unwrap().nonces_data.unrewarded_relayers;
|
||||||
|
unrewarded_relayers.unrewarded_relayer_entries = strategy.max_unrewarded_relayer_entries_at_target;
|
||||||
|
unrewarded_relayers.messages_in_oldest_entry = 4;
|
||||||
|
}
|
||||||
|
assert_eq!(strategy.select_nonces_to_deliver(&state), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn message_delivery_strategy_selects_nothing_if_proved_rewards_is_not_enough_to_remove_oldest_unrewarded_entry() {
|
||||||
|
let (state, mut strategy) = prepare_strategy();
|
||||||
|
|
||||||
|
// if there are already `max_unrewarded_relayer_entries_at_target` entries at target,
|
||||||
|
// we need to prove at least `messages_in_oldest_entry` rewards
|
||||||
|
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
||||||
|
{
|
||||||
|
let mut nonces_data = &mut strategy.target_nonces.as_mut().unwrap().nonces_data;
|
||||||
|
nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 1;
|
||||||
|
let mut unrewarded_relayers = &mut nonces_data.unrewarded_relayers;
|
||||||
|
unrewarded_relayers.unrewarded_relayer_entries = strategy.max_unrewarded_relayer_entries_at_target;
|
||||||
|
unrewarded_relayers.messages_in_oldest_entry = 4;
|
||||||
|
}
|
||||||
|
assert_eq!(strategy.select_nonces_to_deliver(&state), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn message_delivery_strategy_includes_outbound_state_proof_if_proved_rewards_is_enough() {
|
||||||
|
let (state, mut strategy) = prepare_strategy();
|
||||||
|
|
||||||
|
// if there are already `max_unrewarded_relayer_entries_at_target` entries at target,
|
||||||
|
// we need to prove at least `messages_in_oldest_entry` rewards
|
||||||
|
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
||||||
|
{
|
||||||
|
let mut nonces_data = &mut strategy.target_nonces.as_mut().unwrap().nonces_data;
|
||||||
|
nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 3;
|
||||||
|
let mut unrewarded_relayers = &mut nonces_data.unrewarded_relayers;
|
||||||
|
unrewarded_relayers.unrewarded_relayer_entries = strategy.max_unrewarded_relayer_entries_at_target;
|
||||||
|
unrewarded_relayers.messages_in_oldest_entry = 3;
|
||||||
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
strategy.select_nonces_to_deliver(&state),
|
strategy.select_nonces_to_deliver(&state),
|
||||||
Some(((20..=23), proof_parameters(true, 4)))
|
Some(((20..=23), proof_parameters(true, 4)))
|
||||||
@@ -522,7 +624,7 @@ mod tests {
|
|||||||
// relay 3 new messages
|
// relay 3 new messages
|
||||||
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
let prev_confirmed_nonce_at_source = strategy.latest_confirmed_nonce_at_source.unwrap();
|
||||||
strategy.latest_confirmed_nonce_at_source = Some(prev_confirmed_nonce_at_source - 1);
|
strategy.latest_confirmed_nonce_at_source = Some(prev_confirmed_nonce_at_source - 1);
|
||||||
strategy.target_nonces.as_mut().unwrap().confirmed_nonce = Some(prev_confirmed_nonce_at_source - 1);
|
strategy.target_nonces.as_mut().unwrap().nonces_data.confirmed_nonce = prev_confirmed_nonce_at_source - 1;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
strategy.select_nonces_to_deliver(&state),
|
strategy.select_nonces_to_deliver(&state),
|
||||||
Some(((20..=22), proof_parameters(false, 3)))
|
Some(((20..=22), proof_parameters(false, 3)))
|
||||||
|
|||||||
@@ -83,12 +83,11 @@ pub struct SourceClientNonces<NoncesRange> {
|
|||||||
|
|
||||||
/// Nonces on the race target client.
|
/// Nonces on the race target client.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TargetClientNonces {
|
pub struct TargetClientNonces<TargetNoncesData> {
|
||||||
/// Latest nonce that is known to the target client.
|
/// Latest nonce that is known to the target client.
|
||||||
pub latest_nonce: MessageNonce,
|
pub latest_nonce: MessageNonce,
|
||||||
/// Latest nonce that is confirmed to the bridged client. This nonce only makes
|
/// Additional data from target node that may be used by the race.
|
||||||
/// sense in some races. In other races it is `None`.
|
pub nonces_data: TargetNoncesData,
|
||||||
pub confirmed_nonce: Option<MessageNonce>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One of message lane clients, which is source client for the race.
|
/// One of message lane clients, which is source client for the race.
|
||||||
@@ -121,10 +120,14 @@ pub trait SourceClient<P: MessageRace> {
|
|||||||
pub trait TargetClient<P: MessageRace> {
|
pub trait TargetClient<P: MessageRace> {
|
||||||
/// Type of error this clients returns.
|
/// Type of error this clients returns.
|
||||||
type Error: std::fmt::Debug + MaybeConnectionError;
|
type Error: std::fmt::Debug + MaybeConnectionError;
|
||||||
|
/// Type of the additional data from the target client, used by the race.
|
||||||
|
type TargetNoncesData: std::fmt::Debug;
|
||||||
|
|
||||||
/// Return nonces that are known to the target client.
|
/// Return nonces that are known to the target client.
|
||||||
async fn nonces(&self, at_block: P::TargetHeaderId)
|
async fn nonces(
|
||||||
-> Result<(P::TargetHeaderId, TargetClientNonces), Self::Error>;
|
&self,
|
||||||
|
at_block: P::TargetHeaderId,
|
||||||
|
) -> Result<(P::TargetHeaderId, TargetClientNonces<Self::TargetNoncesData>), Self::Error>;
|
||||||
/// Submit proof to the target client.
|
/// Submit proof to the target client.
|
||||||
async fn submit_proof(
|
async fn submit_proof(
|
||||||
&self,
|
&self,
|
||||||
@@ -140,6 +143,8 @@ pub trait RaceStrategy<SourceHeaderId, TargetHeaderId, Proof> {
|
|||||||
type SourceNoncesRange: NoncesRange;
|
type SourceNoncesRange: NoncesRange;
|
||||||
/// Additional proof parameters required to generate proof.
|
/// Additional proof parameters required to generate proof.
|
||||||
type ProofParameters;
|
type ProofParameters;
|
||||||
|
/// Additional data expected from the target client.
|
||||||
|
type TargetNoncesData;
|
||||||
|
|
||||||
/// Should return true if nothing has to be synced.
|
/// Should return true if nothing has to be synced.
|
||||||
fn is_empty(&self) -> bool;
|
fn is_empty(&self) -> bool;
|
||||||
@@ -158,7 +163,7 @@ pub trait RaceStrategy<SourceHeaderId, TargetHeaderId, Proof> {
|
|||||||
/// Called when nonces are updated at target node of the race.
|
/// Called when nonces are updated at target node of the race.
|
||||||
fn target_nonces_updated(
|
fn target_nonces_updated(
|
||||||
&mut self,
|
&mut self,
|
||||||
nonces: TargetClientNonces,
|
nonces: TargetClientNonces<Self::TargetNoncesData>,
|
||||||
race_state: &mut RaceState<SourceHeaderId, TargetHeaderId, Proof>,
|
race_state: &mut RaceState<SourceHeaderId, TargetHeaderId, Proof>,
|
||||||
);
|
);
|
||||||
/// Should return `Some(nonces)` if we need to deliver proof of `nonces` (and associated
|
/// Should return `Some(nonces)` if we need to deliver proof of `nonces` (and associated
|
||||||
@@ -187,10 +192,10 @@ pub struct RaceState<SourceHeaderId, TargetHeaderId, Proof> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run race loop until connection with target or source node is lost.
|
/// Run race loop until connection with target or source node is lost.
|
||||||
pub async fn run<P: MessageRace, SC: SourceClient<P>>(
|
pub async fn run<P: MessageRace, SC: SourceClient<P>, TC: TargetClient<P>>(
|
||||||
race_source: SC,
|
race_source: SC,
|
||||||
race_source_updated: impl FusedStream<Item = SourceClientState<P>>,
|
race_source_updated: impl FusedStream<Item = SourceClientState<P>>,
|
||||||
race_target: impl TargetClient<P>,
|
race_target: TC,
|
||||||
race_target_updated: impl FusedStream<Item = TargetClientState<P>>,
|
race_target_updated: impl FusedStream<Item = TargetClientState<P>>,
|
||||||
stall_timeout: Duration,
|
stall_timeout: Duration,
|
||||||
mut strategy: impl RaceStrategy<
|
mut strategy: impl RaceStrategy<
|
||||||
@@ -199,6 +204,7 @@ pub async fn run<P: MessageRace, SC: SourceClient<P>>(
|
|||||||
P::Proof,
|
P::Proof,
|
||||||
SourceNoncesRange = SC::NoncesRange,
|
SourceNoncesRange = SC::NoncesRange,
|
||||||
ProofParameters = SC::ProofParameters,
|
ProofParameters = SC::ProofParameters,
|
||||||
|
TargetNoncesData = TC::TargetNoncesData,
|
||||||
>,
|
>,
|
||||||
) -> Result<(), FailedClient> {
|
) -> Result<(), FailedClient> {
|
||||||
let mut progress_context = Instant::now();
|
let mut progress_context = Instant::now();
|
||||||
@@ -524,7 +530,7 @@ mod tests {
|
|||||||
strategy.target_nonces_updated(
|
strategy.target_nonces_updated(
|
||||||
TargetClientNonces {
|
TargetClientNonces {
|
||||||
latest_nonce: 5u64,
|
latest_nonce: 5u64,
|
||||||
confirmed_nonce: None,
|
nonces_data: (),
|
||||||
},
|
},
|
||||||
&mut race_state,
|
&mut race_state,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -157,11 +157,12 @@ where
|
|||||||
C: MessageLaneSourceClient<P>,
|
C: MessageLaneSourceClient<P>,
|
||||||
{
|
{
|
||||||
type Error = C::Error;
|
type Error = C::Error;
|
||||||
|
type TargetNoncesData = ();
|
||||||
|
|
||||||
async fn nonces(
|
async fn nonces(
|
||||||
&self,
|
&self,
|
||||||
at_block: SourceHeaderIdOf<P>,
|
at_block: SourceHeaderIdOf<P>,
|
||||||
) -> Result<(SourceHeaderIdOf<P>, TargetClientNonces), Self::Error> {
|
) -> Result<(SourceHeaderIdOf<P>, TargetClientNonces<()>), Self::Error> {
|
||||||
let (at_block, latest_confirmed_nonce) = self.client.latest_confirmed_received_nonce(at_block).await?;
|
let (at_block, latest_confirmed_nonce) = self.client.latest_confirmed_received_nonce(at_block).await?;
|
||||||
if let Some(metrics_msg) = self.metrics_msg.as_ref() {
|
if let Some(metrics_msg) = self.metrics_msg.as_ref() {
|
||||||
metrics_msg.update_source_latest_confirmed_nonce::<P>(latest_confirmed_nonce);
|
metrics_msg.update_source_latest_confirmed_nonce::<P>(latest_confirmed_nonce);
|
||||||
@@ -170,7 +171,7 @@ where
|
|||||||
at_block,
|
at_block,
|
||||||
TargetClientNonces {
|
TargetClientNonces {
|
||||||
latest_nonce: latest_confirmed_nonce,
|
latest_nonce: latest_confirmed_nonce,
|
||||||
confirmed_nonce: None,
|
nonces_data: (),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ where
|
|||||||
{
|
{
|
||||||
type SourceNoncesRange = SourceNoncesRange;
|
type SourceNoncesRange = SourceNoncesRange;
|
||||||
type ProofParameters = ();
|
type ProofParameters = ();
|
||||||
|
type TargetNoncesData = ();
|
||||||
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.source_queue.is_empty()
|
self.source_queue.is_empty()
|
||||||
@@ -185,7 +186,7 @@ where
|
|||||||
|
|
||||||
fn target_nonces_updated(
|
fn target_nonces_updated(
|
||||||
&mut self,
|
&mut self,
|
||||||
nonces: TargetClientNonces,
|
nonces: TargetClientNonces<()>,
|
||||||
race_state: &mut RaceState<
|
race_state: &mut RaceState<
|
||||||
HeaderId<SourceHeaderHash, SourceHeaderNumber>,
|
HeaderId<SourceHeaderHash, SourceHeaderNumber>,
|
||||||
HeaderId<TargetHeaderHash, TargetHeaderNumber>,
|
HeaderId<TargetHeaderHash, TargetHeaderNumber>,
|
||||||
@@ -269,10 +270,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn target_nonces(latest_nonce: MessageNonce) -> TargetClientNonces {
|
fn target_nonces(latest_nonce: MessageNonce) -> TargetClientNonces<()> {
|
||||||
TargetClientNonces {
|
TargetClientNonces {
|
||||||
latest_nonce,
|
latest_nonce,
|
||||||
confirmed_nonce: None,
|
nonces_data: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,12 @@ pub trait SubstrateMessageLane: MessageLane {
|
|||||||
/// Name of the runtime method that returns latest received (confirmed) nonce at the the source chain.
|
/// Name of the runtime method that returns latest received (confirmed) nonce at the the source chain.
|
||||||
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
const OUTBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
||||||
|
|
||||||
/// Name of the runtime method that returns latest received nonce at the source chain.
|
/// Name of the runtime method that returns latest received nonce at the target chain.
|
||||||
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str;
|
||||||
/// Name of the runtime method that returns latest confirmed (reward-paid) nonce at the source chain.
|
/// Name of the runtime method that returns latest confirmed (reward-paid) nonce at the target chain.
|
||||||
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str;
|
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str;
|
||||||
|
/// Numebr of the runtime method that returns state of "unrewarded relayers" set at the target chain.
|
||||||
|
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str;
|
||||||
|
|
||||||
/// Name of the runtime method that returns id of best finalized source header at target chain.
|
/// Name of the runtime method that returns id of best finalized source header at target chain.
|
||||||
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str;
|
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use crate::messages_lane::SubstrateMessageLane;
|
|||||||
use crate::messages_source::read_client_state;
|
use crate::messages_source::read_client_state;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bp_message_lane::{LaneId, MessageNonce};
|
use bp_message_lane::{LaneId, MessageNonce, UnrewardedRelayersState};
|
||||||
use bp_runtime::InstanceId;
|
use bp_runtime::InstanceId;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
@@ -135,6 +135,23 @@ where
|
|||||||
Ok((id, latest_received_nonce))
|
Ok((id, latest_received_nonce))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn unrewarded_relayers_state(
|
||||||
|
&self,
|
||||||
|
id: TargetHeaderIdOf<P>,
|
||||||
|
) -> Result<(TargetHeaderIdOf<P>, UnrewardedRelayersState), Self::Error> {
|
||||||
|
let encoded_response = self
|
||||||
|
.client
|
||||||
|
.state_call(
|
||||||
|
P::INBOUND_LANE_UNREWARDED_RELAYERS_STATE.into(),
|
||||||
|
Bytes(self.lane_id.encode()),
|
||||||
|
Some(id.1),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let unrewarded_relayers_state: UnrewardedRelayersState =
|
||||||
|
Decode::decode(&mut &encoded_response.0[..]).map_err(SubstrateError::ResponseParseFailed)?;
|
||||||
|
Ok((id, unrewarded_relayers_state))
|
||||||
|
}
|
||||||
|
|
||||||
async fn prove_messages_receiving(
|
async fn prove_messages_receiving(
|
||||||
&self,
|
&self,
|
||||||
id: TargetHeaderIdOf<P>,
|
id: TargetHeaderIdOf<P>,
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
|
|||||||
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_millau::FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD;
|
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_millau::FROM_MILLAU_LATEST_RECEIVED_NONCE_METHOD;
|
||||||
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
|
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
|
||||||
bp_millau::FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD;
|
bp_millau::FROM_MILLAU_LATEST_CONFIRMED_NONCE_METHOD;
|
||||||
|
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str = bp_millau::FROM_MILLAU_UNREWARDED_RELAYERS_STATE;
|
||||||
|
|
||||||
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_millau::FINALIZED_MILLAU_BLOCK_METHOD;
|
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_millau::FINALIZED_MILLAU_BLOCK_METHOD;
|
||||||
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rialto::FINALIZED_RIALTO_BLOCK_METHOD;
|
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rialto::FINALIZED_RIALTO_BLOCK_METHOD;
|
||||||
@@ -126,6 +127,7 @@ pub fn run(
|
|||||||
reconnect_delay,
|
reconnect_delay,
|
||||||
stall_timeout,
|
stall_timeout,
|
||||||
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
|
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
|
||||||
|
max_unrewarded_relayer_entries_at_target: bp_rialto::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
|
||||||
max_unconfirmed_nonces_at_target: bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
|
max_unconfirmed_nonces_at_target: bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
|
||||||
max_messages_in_single_batch: bp_rialto::MAX_MESSAGES_IN_DELIVERY_TRANSACTION,
|
max_messages_in_single_batch: bp_rialto::MAX_MESSAGES_IN_DELIVERY_TRANSACTION,
|
||||||
// TODO: subtract base weight of delivery from this when it'll be known
|
// TODO: subtract base weight of delivery from this when it'll be known
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
|
|||||||
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_rialto::FROM_RIALTO_LATEST_RECEIVED_NONCE_METHOD;
|
const INBOUND_LANE_LATEST_RECEIVED_NONCE_METHOD: &'static str = bp_rialto::FROM_RIALTO_LATEST_RECEIVED_NONCE_METHOD;
|
||||||
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
|
const INBOUND_LANE_LATEST_CONFIRMED_NONCE_METHOD: &'static str =
|
||||||
bp_rialto::FROM_RIALTO_LATEST_CONFIRMED_NONCE_METHOD;
|
bp_rialto::FROM_RIALTO_LATEST_CONFIRMED_NONCE_METHOD;
|
||||||
|
const INBOUND_LANE_UNREWARDED_RELAYERS_STATE: &'static str = bp_rialto::FROM_RIALTO_UNREWARDED_RELAYERS_STATE;
|
||||||
|
|
||||||
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rialto::FINALIZED_RIALTO_BLOCK_METHOD;
|
const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rialto::FINALIZED_RIALTO_BLOCK_METHOD;
|
||||||
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_millau::FINALIZED_MILLAU_BLOCK_METHOD;
|
const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_millau::FINALIZED_MILLAU_BLOCK_METHOD;
|
||||||
@@ -126,6 +127,7 @@ pub fn run(
|
|||||||
reconnect_delay,
|
reconnect_delay,
|
||||||
stall_timeout,
|
stall_timeout,
|
||||||
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
|
delivery_params: messages_relay::message_lane_loop::MessageDeliveryParams {
|
||||||
|
max_unrewarded_relayer_entries_at_target: bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE,
|
||||||
max_unconfirmed_nonces_at_target: bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
|
max_unconfirmed_nonces_at_target: bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE,
|
||||||
max_messages_in_single_batch: bp_millau::MAX_MESSAGES_IN_DELIVERY_TRANSACTION,
|
max_messages_in_single_batch: bp_millau::MAX_MESSAGES_IN_DELIVERY_TRANSACTION,
|
||||||
// TODO: subtract base weight of delivery from this when it'll be known
|
// TODO: subtract base weight of delivery from this when it'll be known
|
||||||
|
|||||||
Reference in New Issue
Block a user