From 5238546bbdb0b64c0cef404db230963e6d58c7c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Pestana?= Date: Tue, 12 Dec 2023 11:47:17 +0100 Subject: [PATCH 1/2] Adds a round check in the signed submission of the solution --- .../election-provider-multi-phase/src/lib.rs | 3 ++ .../election-provider-multi-phase/src/mock.rs | 9 +++++ .../src/signed.rs | 35 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index 05f9b24f8f9c..41284f6c78b1 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -1024,6 +1024,7 @@ pub mod pallet { // ensure solution is timely. ensure!(Self::current_phase().is_signed(), Error::::PreDispatchEarlySubmission); + ensure!(raw_solution.round == Self::round(), Error::::PreDispatchDifferentRound); // NOTE: this is the only case where having separate snapshot would have been better // because could do just decode_len. But we can create abstractions to do this. @@ -1197,6 +1198,8 @@ pub mod pallet { BoundNotMet, /// Submitted solution has too many winners TooManyWinners, + /// Sumission was prepared for a different round. + PreDispatchDifferentRound, } #[pallet::validate_unsigned] diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index 7bdd329d9b04..abad7db037e7 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -112,6 +112,15 @@ pub fn roll_to_with_ocw(n: BlockNumber) { } } +pub fn roll_to_round(n: u32) { + assert!(MultiPhase::round() <= n); + + while MultiPhase::round() != n { + roll_to_signed(); + assert_ok!(MultiPhase::elect()); + } +} + pub struct TrimHelpers { pub voters: Vec>, pub assignments: Vec>, diff --git a/substrate/frame/election-provider-multi-phase/src/signed.rs b/substrate/frame/election-provider-multi-phase/src/signed.rs index 7e4b029ff8c8..c54b16d824cd 100644 --- a/substrate/frame/election-provider-multi-phase/src/signed.rs +++ b/substrate/frame/election-provider-multi-phase/src/signed.rs @@ -571,6 +571,41 @@ mod tests { use frame_support::{assert_noop, assert_ok, assert_storage_noop}; use sp_runtime::Percent; + #[test] + fn cannot_submit_on_different_round() { + ExtBuilder::default().build_and_execute(|| { + // roll to a few rounds ahead. + roll_to_round(5); + assert_eq!(MultiPhase::round(), 5); + + roll_to_signed(); + assert_eq!(MultiPhase::current_phase(), Phase::Signed); + + // create a temp snapshot only for this test. + MultiPhase::create_snapshot().unwrap(); + let mut solution = raw_solution(); + + // try a solution prepared in a previous round. + solution.round = MultiPhase::round() - 1; + + assert_noop!( + MultiPhase::submit(RuntimeOrigin::signed(10), Box::new(solution)), + Error::::PreDispatchDifferentRound, + ); + + // try a solution prepared in a later round (not expected to happen, but in any case). + MultiPhase::create_snapshot().unwrap(); + let mut solution = raw_solution(); + solution.round = MultiPhase::round() + 1; + + assert_noop!( + MultiPhase::submit(RuntimeOrigin::signed(10), Box::new(solution)), + Error::::PreDispatchDifferentRound, + ); + + }) + } + #[test] fn cannot_submit_too_early() { ExtBuilder::default().build_and_execute(|| { From 38955380762d141def803910ae05cfa66b618286 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Tue, 12 Dec 2023 11:16:57 +0000 Subject: [PATCH 2/2] ".git/.scripts/commands/fmt/fmt.sh" --- substrate/frame/election-provider-multi-phase/src/signed.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/substrate/frame/election-provider-multi-phase/src/signed.rs b/substrate/frame/election-provider-multi-phase/src/signed.rs index c54b16d824cd..ae830ed0382d 100644 --- a/substrate/frame/election-provider-multi-phase/src/signed.rs +++ b/substrate/frame/election-provider-multi-phase/src/signed.rs @@ -602,7 +602,6 @@ mod tests { MultiPhase::submit(RuntimeOrigin::signed(10), Box::new(solution)), Error::::PreDispatchDifferentRound, ); - }) }