mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 00:57:57 +00:00
[FRAME] Make MQ pallet re-entrancy safe (#2356)
Closes https://github.com/paritytech/polkadot-sdk/issues/2319 Changes: - Ensure that only `enqueue_message(s)` is callable from within the message processor. This prevents messed up storage that can currently happen when the pallet is called into recursively. - Use `H256` instead of `[u8; 32]` for clearer API. ## Details The re-entracy check is done with the `environmental` crate by adding a `with_service_mutex(f)` function that runs the closure exclusively. This works since the MQ pallet is not instantiable. --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
This commit is contained in:
committed by
GitHub
parent
95c3ee10bc
commit
7e7fe99047
@@ -108,7 +108,10 @@ impl MockedWeightInfo {
|
||||
|
||||
impl crate::weights::WeightInfo for MockedWeightInfo {
|
||||
fn reap_page() -> Weight {
|
||||
WeightForCall::get().get("reap_page").copied().unwrap_or_default()
|
||||
WeightForCall::get()
|
||||
.get("reap_page")
|
||||
.copied()
|
||||
.unwrap_or(DefaultWeightForCall::get())
|
||||
}
|
||||
fn execute_overweight_page_updated() -> Weight {
|
||||
WeightForCall::get()
|
||||
@@ -207,6 +210,10 @@ impl ProcessMessage for RecordingMessageProcessor {
|
||||
let required = Weight::from_parts(weight, weight);
|
||||
|
||||
if meter.try_consume(required).is_ok() {
|
||||
if let Some(p) = message.strip_prefix(&b"callback="[..]) {
|
||||
let s = String::from_utf8(p.to_vec()).expect("Need valid UTF8");
|
||||
Callback::get()(&origin, s.parse().expect("Expected an u32"));
|
||||
}
|
||||
let mut m = MessagesProcessed::get();
|
||||
m.push((message.to_vec(), origin));
|
||||
MessagesProcessed::set(m);
|
||||
@@ -217,6 +224,10 @@ impl ProcessMessage for RecordingMessageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub static Callback: Box<fn (&MessageOrigin, u32)> = Box::new(|_, _| {});
|
||||
}
|
||||
|
||||
/// Processed a mocked message. Messages that end with `badformat`, `corrupt`, `unsupported` or
|
||||
/// `yield` will fail with an error respectively.
|
||||
fn processing_message(msg: &[u8], origin: &MessageOrigin) -> Result<(), ProcessMessageError> {
|
||||
@@ -264,6 +275,10 @@ impl ProcessMessage for CountingMessageProcessor {
|
||||
let required = Weight::from_parts(1, 1);
|
||||
|
||||
if meter.try_consume(required).is_ok() {
|
||||
if let Some(p) = message.strip_prefix(&b"callback="[..]) {
|
||||
let s = String::from_utf8(p.to_vec()).expect("Need valid UTF8");
|
||||
Callback::get()(&origin, s.parse().expect("Expected an u32"));
|
||||
}
|
||||
NumMessagesProcessed::set(NumMessagesProcessed::get() + 1);
|
||||
Ok(true)
|
||||
} else {
|
||||
@@ -372,3 +387,16 @@ pub fn num_overweight_enqueued_events() -> u32 {
|
||||
pub fn fp(pages: u32, count: u64, size: u64) -> QueueFootprint {
|
||||
QueueFootprint { storage: Footprint { count, size }, pages }
|
||||
}
|
||||
|
||||
/// A random seed that can be overwritten with `MQ_SEED`.
|
||||
pub fn gen_seed() -> u64 {
|
||||
use rand::Rng;
|
||||
let seed = if let Ok(seed) = std::env::var("MQ_SEED") {
|
||||
seed.parse().expect("Need valid u64 as MQ_SEED env variable")
|
||||
} else {
|
||||
rand::thread_rng().gen::<u64>()
|
||||
};
|
||||
|
||||
println!("Using seed: {}", seed);
|
||||
seed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user