mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 19:11:02 +00:00
Dynamic fees for bridges-v1 (#2294)
* impl backpressure in the XcmBlobHaulerAdapter * LocalXcmQueueManager + more adapters * OnMessageDelviered callback * forbid mesage delivery transactions when the channel between target bridge hub and target asset hub is suspended * pallet-xcm-bridge-hub-router * removed commented code * improvements and tests for palle-xcm-bridge-router * use LocalXcmChannel in XcmBlobMessageDispatch * new tests for logic changes in messages pallet * tests for LocalXcmQueueSuspender * tests for LocalXcmQueueMessageProcessor * tests for new logic in the XcmBlobHaulerAdapter * fix other tests in the bridge-runtime-common * extension_reject_call_when_dispatcher_is_inactive * benchmarks for pallet-xcm-bridge-hub-router * get rid of redundant storage value * add new pallet to verify-pallets-build.sh * fixing spellcheck, clippy and rustdoc * trigger CI * Revert "trigger CI" This reverts commit 48f1ba032334e3c6d8470436483736988aa060ac. * change log target for xcm bridge router pallet * Update modules/xcm-bridge-hub-router/src/lib.rs Co-authored-by: Branislav Kontur <bkontur@gmail.com> * use saturated_len where possible * fmt * (Suggestion) Ability to externalize configuration for `ExporterFor` (#2313) * Ability to externalize configuration for `ExporterFor` (Replaced `BridgedNetworkId/SiblingBridgeHubLocation` with `Bridges: ExporterFor`) * Fix millau * Compile fix * Return back `BridgedNetworkId` but as optional filter * Replaced `BaseFee` with fees from inner `Bridges: ExporterFor` * typo * Clippy * Rename LocalXcmChannel to XcmChannelStatusProvider (#2319) * Rename LocalXcmChannel to XcmChannelStatusProvider * fmt * added/fixed some docs * Dynamic fees v1: report congestion status to sending chain (#2318) * report congestion status: changes at the sending chain * OnMessagesDelivered is back * report congestion status: changes at the bridge hub * moer logging * fix? benchmarks * spelling * tests for XcmBlobHaulerAdapter and LocalXcmQueueManager * tests for messages pallet * fix typo * rustdoc * Update modules/messages/src/lib.rs * apply review suggestions * ".git/.scripts/commands/fmt/fmt.sh" * Added `XcmBridgeHubRouterCall::report_bridge_status` encodings for AHK/P (#2350) * Added `XcmBridgeHubRouterCall::report_bridge_status` encodings for AHK/P * Spellcheck * Added const for `XcmBridgeHubRouterTransactCallMaxWeight` * Cargo.lock * Introduced base delivery fee constants * Congestion messages as Optional to turn on/off `supports_congestion_detection` * Spellcheck * Ability to externalize dest for benchmarks * Ability to externalize dest for benchmarks --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: command-bot <>
This commit is contained in:
committed by
Bastian Köcher
parent
dc8aa5df7d
commit
31a6cbeafb
@@ -53,7 +53,8 @@ use crate::{
|
||||
|
||||
use bp_messages::{
|
||||
source_chain::{
|
||||
DeliveryConfirmationPayments, LaneMessageVerifier, SendMessageArtifacts, TargetHeaderChain,
|
||||
DeliveryConfirmationPayments, LaneMessageVerifier, OnMessagesDelivered,
|
||||
SendMessageArtifacts, TargetHeaderChain,
|
||||
},
|
||||
target_chain::{
|
||||
DeliveryPayments, DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages,
|
||||
@@ -63,7 +64,9 @@ use bp_messages::{
|
||||
MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails,
|
||||
UnrewardedRelayersState, VerificationError,
|
||||
};
|
||||
use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, PreComputedSize, Size};
|
||||
use bp_runtime::{
|
||||
BasicOperatingMode, ChainId, OwnedBridgeModule, PreComputedSize, RangeInclusiveExt, Size,
|
||||
};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use frame_support::{dispatch::PostDispatchInfo, ensure, fail, traits::Get, DefaultNoBound};
|
||||
use sp_runtime::traits::UniqueSaturatedFrom;
|
||||
@@ -156,6 +159,8 @@ pub mod pallet {
|
||||
type LaneMessageVerifier: LaneMessageVerifier<Self::OutboundPayload>;
|
||||
/// Delivery confirmation payments.
|
||||
type DeliveryConfirmationPayments: DeliveryConfirmationPayments<Self::AccountId>;
|
||||
/// Delivery confirmation callback.
|
||||
type OnMessagesDelivered: OnMessagesDelivered;
|
||||
|
||||
// Types that are used by inbound_lane (on target chain).
|
||||
|
||||
@@ -281,6 +286,9 @@ pub mod pallet {
|
||||
Error::<T, I>::TooManyMessagesInTheProof
|
||||
);
|
||||
|
||||
// if message dispatcher is currently inactive, we won't accept any messages
|
||||
ensure!(T::MessageDispatch::is_active(), Error::<T, I>::MessageDispatchInactive);
|
||||
|
||||
// why do we need to know the weight of this (`receive_messages_proof`) call? Because
|
||||
// we may want to return some funds for not-dispatching (or partially dispatching) some
|
||||
// messages to the call origin (relayer). And this is done by returning actual weight
|
||||
@@ -487,6 +495,12 @@ pub mod pallet {
|
||||
lane_id,
|
||||
);
|
||||
|
||||
// notify others about messages delivery
|
||||
T::OnMessagesDelivered::on_messages_delivered(
|
||||
lane_id,
|
||||
lane.data().queued_messages().saturating_len(),
|
||||
);
|
||||
|
||||
// because of lags, the inbound lane state (`lane_data`) may have entries for
|
||||
// already rewarded relayers and messages (if all entries are duplicated, then
|
||||
// this transaction must be filtered out by our signed extension)
|
||||
@@ -518,6 +532,8 @@ pub mod pallet {
|
||||
NotOperatingNormally,
|
||||
/// The outbound lane is inactive.
|
||||
InactiveOutboundLane,
|
||||
/// The inbound message dispatcher is inactive.
|
||||
MessageDispatchInactive,
|
||||
/// Message has been treated as invalid by chain verifier.
|
||||
MessageRejectedByChainVerifier(VerificationError),
|
||||
/// Message has been treated as invalid by lane verifier.
|
||||
@@ -580,6 +596,25 @@ pub mod pallet {
|
||||
MaxValues = MaybeOutboundLanesCount<T, I>,
|
||||
>;
|
||||
|
||||
/// Map of lane id => is congested signal sent. It is managed by the
|
||||
/// `bridge_runtime_common::LocalXcmQueueManager`.
|
||||
///
|
||||
/// **bridges-v1**: this map is a temporary hack and will be dropped in the `v2`. We can emulate
|
||||
/// a storage map using `sp_io::unhashed` storage functions, but then benchmarks are not
|
||||
/// accounting its `proof_size`, so it is missing from the final weights. So we need to make it
|
||||
/// a map inside some pallet. We could use a simply value instead of map here, because
|
||||
/// in `v1` we'll only have a single lane. But in the case of adding another lane before `v2`,
|
||||
/// it'll be easier to deal with the isolated storage map instead.
|
||||
#[pallet::storage]
|
||||
pub type OutboundLanesCongestedSignals<T: Config<I>, I: 'static = ()> = StorageMap<
|
||||
Hasher = Blake2_128Concat,
|
||||
Key = LaneId,
|
||||
Value = bool,
|
||||
QueryKind = ValueQuery,
|
||||
OnEmpty = GetDefault,
|
||||
MaxValues = MaybeOutboundLanesCount<T, I>,
|
||||
>;
|
||||
|
||||
/// All queued outbound messages.
|
||||
#[pallet::storage]
|
||||
pub type OutboundMessages<T: Config<I>, I: 'static = ()> =
|
||||
@@ -627,6 +662,11 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return outbound lane data.
|
||||
pub fn outbound_lane_data(lane: LaneId) -> OutboundLaneData {
|
||||
OutboundLanes::<T, I>::get(lane)
|
||||
}
|
||||
|
||||
/// Return inbound lane data.
|
||||
pub fn inbound_lane_data(lane: LaneId) -> InboundLaneData<T::InboundRelayer> {
|
||||
InboundLanes::<T, I>::get(lane).0
|
||||
@@ -703,6 +743,9 @@ fn send_message<T: Config<I>, I: 'static>(
|
||||
.send_message(encoded_payload)
|
||||
.map_err(Error::<T, I>::MessageRejectedByPallet)?;
|
||||
|
||||
// return number of messages in the queue to let sender know about its state
|
||||
let enqueued_messages = lane.data().queued_messages().saturating_len();
|
||||
|
||||
log::trace!(
|
||||
target: LOG_TARGET,
|
||||
"Accepted message {} to lane {:?}. Message size: {:?}",
|
||||
@@ -713,7 +756,7 @@ fn send_message<T: Config<I>, I: 'static>(
|
||||
|
||||
Pallet::<T, I>::deposit_event(Event::MessageAccepted { lane_id, nonce });
|
||||
|
||||
Ok(SendMessageArtifacts { nonce })
|
||||
Ok(SendMessageArtifacts { nonce, enqueued_messages })
|
||||
}
|
||||
|
||||
/// Ensure that the pallet is in normal operational mode.
|
||||
@@ -881,8 +924,9 @@ mod tests {
|
||||
mock::{
|
||||
inbound_unrewarded_relayers_state, message, message_payload, run_test,
|
||||
unrewarded_relayer, AccountId, DbWeight, RuntimeEvent as TestEvent, RuntimeOrigin,
|
||||
TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessagesDeliveryProof,
|
||||
TestMessagesProof, TestRelayer, TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE,
|
||||
TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessageDispatch,
|
||||
TestMessagesDeliveryProof, TestMessagesProof, TestOnMessagesDelivered, TestRelayer,
|
||||
TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE,
|
||||
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2,
|
||||
TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
|
||||
},
|
||||
@@ -908,10 +952,12 @@ mod tests {
|
||||
fn send_regular_message() {
|
||||
get_ready_for_events();
|
||||
|
||||
let message_nonce =
|
||||
outbound_lane::<TestRuntime, ()>(TEST_LANE_ID).data().latest_generated_nonce + 1;
|
||||
send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD)
|
||||
let outbound_lane = outbound_lane::<TestRuntime, ()>(TEST_LANE_ID);
|
||||
let message_nonce = outbound_lane.data().latest_generated_nonce + 1;
|
||||
let prev_enqueud_messages = outbound_lane.data().queued_messages().saturating_len();
|
||||
let artifacts = send_message::<TestRuntime, ()>(TEST_LANE_ID, REGULAR_PAYLOAD)
|
||||
.expect("send_message has failed");
|
||||
assert_eq!(artifacts.enqueued_messages, prev_enqueud_messages + 1);
|
||||
|
||||
// check event with assigned nonce
|
||||
assert_eq!(
|
||||
@@ -1201,6 +1247,23 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn receive_messages_fails_if_dispatcher_is_inactive() {
|
||||
run_test(|| {
|
||||
TestMessageDispatch::deactivate();
|
||||
assert_noop!(
|
||||
Pallet::<TestRuntime>::receive_messages_proof(
|
||||
RuntimeOrigin::signed(1),
|
||||
TEST_RELAYER_A,
|
||||
Ok(vec![message(1, REGULAR_PAYLOAD)]).into(),
|
||||
1,
|
||||
REGULAR_PAYLOAD.declared_weight,
|
||||
),
|
||||
Error::<TestRuntime, ()>::MessageDispatchInactive,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn receive_messages_proof_does_not_accept_message_if_dispatch_weight_is_not_enough() {
|
||||
run_test(|| {
|
||||
@@ -1304,6 +1367,7 @@ mod tests {
|
||||
);
|
||||
assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
|
||||
assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1));
|
||||
assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 1)));
|
||||
|
||||
// this reports delivery of both message 1 and message 2 => reward is paid only to
|
||||
// TEST_RELAYER_B
|
||||
@@ -1346,6 +1410,7 @@ mod tests {
|
||||
);
|
||||
assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
|
||||
assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1));
|
||||
assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 0)));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user