Skip to content

Commit

Permalink
fix patch
Browse files Browse the repository at this point in the history
fix

fix

fixfix

dgd
  • Loading branch information
cl0w committed Oct 16, 2024
1 parent 90da58c commit ea91db2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 49 deletions.
105 changes: 57 additions & 48 deletions substrate/frame/message-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ pub mod pallet {
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
if let Some(weight_limit) = T::ServiceWeight::get() {
Self::service_queues(weight_limit, ServiceQueuesContext::OnInitialize)
Self::service_queues_impl(weight_limit, ServiceQueuesContext::OnInitialize)
} else {
Weight::zero()
}
Expand All @@ -655,7 +655,10 @@ pub mod pallet {
fn on_idle(_n: BlockNumberFor<T>, remaining_weight: Weight) -> Weight {
if let Some(weight_limit) = T::IdleMaxServiceWeight::get() {
// Make use of the remaining weight to process enqueued messages.
Self::service_queues(weight_limit.min(remaining_weight), ServiceQueuesContext::OnIdle)
Self::service_queues_impl(
weight_limit.min(remaining_weight),
ServiceQueuesContext::OnIdle
)
} else {
Weight::zero()
}
Expand All @@ -676,11 +679,13 @@ pub mod pallet {
/// The context to pass to service_queues through on_idle and on_initialize hooks
/// We don't want to throw the defensive message if called from on_idle hook
#[derive(PartialEq)]
enum ServiceQueuesContext {
pub enum ServiceQueuesContext {
/// Context of on_idle hook
OnIdle,
/// Context of on_initialize hook
OnInitialize,
/// Context `service_queues` trait function.
ServiceQueues,
}

#[pallet::call]
Expand Down Expand Up @@ -1484,6 +1489,53 @@ impl<T: Config> Pallet<T> {
},
}
}

fn service_queues_impl(weight_limit: Weight, context: ServiceQueuesContext) -> Weight {
let mut weight = WeightMeter::with_limit(weight_limit);

// Get the maximum weight that processing a single message may take:
let max_weight = Self::max_message_weight(weight_limit).unwrap_or_else(|| {
if matches!(context, ServiceQueuesContext::OnInitialize) {
defensive!("Not enough weight to service a single message.");
}
Weight::zero()
});

match with_service_mutex(|| {
let mut next = match Self::bump_service_head(&mut weight) {
Some(h) => h,
None => return weight.consumed(),
};
// The last queue that did not make any progress.
// The loop aborts as soon as it arrives at this queue again without making any progress
// on other queues in between.
let mut last_no_progress = None;

loop {
let (progressed, n) = Self::service_queue(next.clone(), &mut weight, max_weight);
next = match n {
Some(n) =>
if !progressed {
if last_no_progress == Some(n.clone()) {
break
}
if last_no_progress.is_none() {
last_no_progress = Some(next.clone())
}
n
} else {
last_no_progress = None;
n
},
None => break,
}
}
weight.consumed()
}) {
Err(()) => weight.consumed(),
Ok(w) => w,
}
}
}

/// Run a closure that errors on re-entrance. Meant to be used by anything that services queues.
Expand Down Expand Up @@ -1552,51 +1604,8 @@ impl<T: Get<O>, O: Into<u32>> Get<u32> for IntoU32<T, O> {
impl<T: Config> ServiceQueues for Pallet<T> {
type OverweightMessageAddress = (MessageOriginOf<T>, PageIndex, T::Size);

fn service_queues(weight_limit: Weight, context: ServiceQueuesContext) -> Weight {
let mut weight = WeightMeter::with_limit(weight_limit);

// Get the maximum weight that processing a single message may take:
let max_weight = Self::max_message_weight(weight_limit).unwrap_or_else(|| {
if matches(context, ServiceQueuesContext::OnInitialize) {
defensive!("Not enough weight to service a single message.");
}
Weight::zero()
});

match with_service_mutex(|| {
let mut next = match Self::bump_service_head(&mut weight) {
Some(h) => h,
None => return weight.consumed(),
};
// The last queue that did not make any progress.
// The loop aborts as soon as it arrives at this queue again without making any progress
// on other queues in between.
let mut last_no_progress = None;

loop {
let (progressed, n) = Self::service_queue(next.clone(), &mut weight, max_weight);
next = match n {
Some(n) =>
if !progressed {
if last_no_progress == Some(n.clone()) {
break
}
if last_no_progress.is_none() {
last_no_progress = Some(next.clone())
}
n
} else {
last_no_progress = None;
n
},
None => break,
}
}
weight.consumed()
}) {
Err(()) => weight.consumed(),
Ok(w) => w,
}
fn service_queues(weight_limit: Weight) -> Weight {
Self::service_queues_impl(weight_limit, ServiceQueuesContext::ServiceQueues)
}

/// Execute a single overweight message.
Expand Down
2 changes: 1 addition & 1 deletion substrate/frame/message-queue/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ fn service_queues_low_weight_defensive() {
assert!(MessageQueue::do_integrity_test().is_err());

MessageQueue::enqueue_message(msg("weight=0"), Here);
MessageQueue::service_queues(104.into_weight());
MessageQueue::service_queues_impl(104.into_weight(), ServiceQueuesContext::OnInitialize);
});
}

Expand Down

0 comments on commit ea91db2

Please sign in to comment.