Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

frame-session: Introduce a proper proof of key ownership #1739

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4a45248
Start
bkchr Sep 17, 2023
7f9a455
Merge remote-tracking branch 'origin/master' into bkchr-set-keys-proof
bkchr Sep 25, 2023
2ecdeb3
Fixes
bkchr Sep 25, 2023
d004457
Fix more tests
bkchr Sep 25, 2023
cca49bf
Remove new RPC and fix up some comments
bkchr Sep 28, 2023
69fa5fc
Merge remote-tracking branch 'origin/master' into bkchr-set-keys-proof
bkchr Sep 28, 2023
11d5099
Remove unused type.
bkchr Sep 28, 2023
654dec7
".git/.scripts/commands/fmt/fmt.sh"
Sep 28, 2023
da937d9
Fix compilation
bkchr Sep 28, 2023
eda0139
Revert "Remove new RPC and fix up some comments"
bkchr Oct 2, 2023
412e63b
Revert "Remove unused type."
bkchr Oct 2, 2023
bfba5cd
Merge remote-tracking branch 'origin/master' into bkchr-set-keys-proof
bkchr Oct 3, 2023
5a2c397
Update docs
bkchr Oct 3, 2023
c52c6c3
Fix tests
bkchr Oct 4, 2023
59f6886
Fix docs
bkchr Oct 4, 2023
371b1cb
Fixes
bkchr Oct 10, 2023
cdf9887
Fix compilation
bkchr Oct 11, 2023
a33ab45
FMT
bkchr Oct 11, 2023
b14b399
Make clippy happy..
bkchr Oct 11, 2023
0d30e18
CLIPPY
bkchr Oct 11, 2023
a6c5d25
Merge remote-tracking branch 'origin/master' into bkchr-set-keys-proof
bkchr Oct 11, 2023
b361b48
Fix collator selection benchmarking
bkchr Oct 11, 2023
ceb2add
Fix warning
bkchr Oct 11, 2023
b219dc8
Format features
bkchr Oct 11, 2023
1c3c8c5
Merge remote-tracking branch 'refs/remotes/origin/master'
bkchr Jul 30, 2024
3fc2ea5
Fix error
bkchr Aug 14, 2024
0479cd0
Merge remote-tracking branch 'origin/master' into bkchr-set-keys-proof
bkchr Aug 14, 2024
770b471
Remove old files
bkchr Aug 14, 2024
1cd8589
Fix issues
bkchr Aug 15, 2024
165eadb
Fix warning
bkchr Aug 15, 2024
0e8af35
More warnings..
bkchr Aug 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cumulus/pallets/collator-selection/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pallet-balances = { workspace = true }
pallet-session = { workspace = true }

frame-benchmarking = { optional = true, workspace = true }
cumulus-pallet-session-benchmarking = { default-features = false, optional = true, workspace = true }

[dev-dependencies]
sp-core = { workspace = true, default-features = true }
Expand All @@ -43,6 +44,7 @@ pallet-aura = { workspace = true, default-features = true }
[features]
default = ["std"]
runtime-benchmarks = [
"cumulus-pallet-session-benchmarking/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
Expand All @@ -53,6 +55,7 @@ runtime-benchmarks = [
]
std = [
"codec/std",
"cumulus-pallet-session-benchmarking?/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
Expand Down
69 changes: 26 additions & 43 deletions cumulus/pallets/collator-selection/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ use crate::Pallet as CollatorSelection;
use alloc::vec::Vec;
use codec::Decode;
use core::cmp;
use cumulus_pallet_session_benchmarking as session_benchmarking;
use frame_benchmarking::{account, v2::*, whitelisted_caller, BenchmarkError};
use frame_support::traits::{Currency, EnsureOrigin, Get, ReservableCurrency};
use frame_system::{pallet_prelude::BlockNumberFor, EventRecord, RawOrigin};
use pallet_authorship::EventHandler;
use pallet_session::{self as session, SessionManager};

pub type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
<<T as super::Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

const SEED: u32 = 0;

fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
fn assert_last_event<T: Config>(generic_event: <T as super::Config>::RuntimeEvent) {
let events = frame_system::Pallet::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
Expand All @@ -54,35 +55,23 @@ fn create_funded_user<T: Config>(
user
}

fn keys<T: Config + session::Config>(c: u32) -> <T as session::Config>::Keys {
use rand::{RngCore, SeedableRng};
fn validator<T: Config + session_benchmarking::Config>(
c: u32,
) -> (T::AccountId, <T as session::Config>::Keys, Vec<u8>) {
let validator = create_funded_user::<T>("candidate", c, 1000);
let (keys, proof) = T::generate_session_keys_and_proof(validator.clone());

let keys = {
let mut keys = [0u8; 128];

if c > 0 {
let mut rng = rand::rngs::StdRng::seed_from_u64(c as u64);
rng.fill_bytes(&mut keys);
}

keys
};

Decode::decode(&mut &keys[..]).unwrap()
(validator, keys, proof)
}

fn validator<T: Config + session::Config>(c: u32) -> (T::AccountId, <T as session::Config>::Keys) {
(create_funded_user::<T>("candidate", c, 1000), keys::<T>(c))
}

fn register_validators<T: Config + session::Config>(count: u32) -> Vec<T::AccountId> {
fn register_validators<T: Config + session_benchmarking::Config>(count: u32) -> Vec<T::AccountId> {
let validators = (0..count).map(|c| validator::<T>(c)).collect::<Vec<_>>();

for (who, keys) in validators.clone() {
<session::Pallet<T>>::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new()).unwrap();
for (who, keys, proof) in validators.clone() {
<session::Pallet<T>>::set_keys(RawOrigin::Signed(who).into(), keys, proof).unwrap();
}

validators.into_iter().map(|(who, _)| who).collect()
validators.into_iter().map(|(who, _, _)| who).collect()
}

fn register_candidates<T: Config>(count: u32) {
Expand Down Expand Up @@ -110,7 +99,7 @@ fn min_invulnerables<T: Config>() -> u32 {
min_collators.saturating_sub(candidates_length)
}

#[benchmarks(where T: pallet_authorship::Config + session::Config)]
#[benchmarks(where T: pallet_authorship::Config + session_benchmarking::Config)]
mod benchmarks {
use super::*;

Expand Down Expand Up @@ -151,15 +140,14 @@ mod benchmarks {
// add one more to the list. should not be in `b` (invulnerables) because it's the account
// we will _add_ to invulnerables. we want it to be in `candidates` because we need the
// weight associated with removing it.
let (new_invulnerable, new_invulnerable_keys) = validator::<T>(b.max(c) + 1);
candidates.push((new_invulnerable.clone(), new_invulnerable_keys));
let (new_invulnerable, new_invulnerable_keys, new_proof) = validator::<T>(b.max(c) + 1);
candidates.push((new_invulnerable.clone(), new_invulnerable_keys, new_proof));
// set their keys ...
for (who, keys) in candidates.clone() {
<session::Pallet<T>>::set_keys(RawOrigin::Signed(who).into(), keys, Vec::new())
.unwrap();
for (who, keys, proof) in candidates.clone() {
<session::Pallet<T>>::set_keys(RawOrigin::Signed(who).into(), keys, proof).unwrap();
}
// ... and register them.
for (who, _) in candidates.iter() {
for (who, _, _) in candidates.iter() {
let deposit = CandidacyBond::<T>::get();
T::Currency::make_free_balance_be(who, deposit * 1000_u32.into());
CandidateList::<T>::try_mutate(|list| {
Expand Down Expand Up @@ -293,13 +281,10 @@ mod benchmarks {
let caller: T::AccountId = whitelisted_caller();
let bond: BalanceOf<T> = T::Currency::minimum_balance() * 2u32.into();
T::Currency::make_free_balance_be(&caller, bond);
let (keys, proof) = T::generate_session_keys_and_proof(caller.clone());

<session::Pallet<T>>::set_keys(
RawOrigin::Signed(caller.clone()).into(),
keys::<T>(c + 1),
Vec::new(),
)
.unwrap();
<session::Pallet<T>>::set_keys(RawOrigin::Signed(caller.clone()).into(), keys, proof)
.unwrap();

#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
Expand All @@ -321,12 +306,10 @@ mod benchmarks {
let bond: BalanceOf<T> = T::Currency::minimum_balance() * 10u32.into();
T::Currency::make_free_balance_be(&caller, bond);

<session::Pallet<T>>::set_keys(
RawOrigin::Signed(caller.clone()).into(),
keys::<T>(c + 1),
Vec::new(),
)
.unwrap();
let (keys, proof) = T::generate_session_keys_and_proof(caller.clone());

<session::Pallet<T>>::set_keys(RawOrigin::Signed(caller.clone()).into(), keys, proof)
.unwrap();

let target = CandidateList::<T>::get().iter().last().unwrap().who.clone();

Expand Down
11 changes: 11 additions & 0 deletions cumulus/pallets/collator-selection/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ impl Config for Test {
type WeightInfo = ();
}

#[cfg(feature = "runtime-benchmarks")]
impl cumulus_pallet_session_benchmarking::Config for Test {
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
use codec::Encode;

let keys = MockSessionKeys::generate(&owner.encode(), None);

(keys.keys, keys.proof.encode())
}
}

pub fn new_test_ext() -> sp_io::TestExternalities {
sp_tracing::try_init_simple();
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
Expand Down
8 changes: 7 additions & 1 deletion cumulus/pallets/collator-selection/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::{
mock::*, CandidacyBond, CandidateInfo, CandidateList, DesiredCandidates, Error, Invulnerables,
LastAuthoredBlock,
};
use codec::Encode;
use frame_support::{
assert_noop, assert_ok,
traits::{Currency, OnInitialize},
Expand Down Expand Up @@ -124,7 +125,12 @@ fn invulnerable_limit_works() {
if ii > 5 {
Balances::make_free_balance_be(&ii, 100);
let key = MockSessionKeys { aura: UintAuthorityId(ii) };
Session::set_keys(RuntimeOrigin::signed(ii).into(), key, Vec::new()).unwrap();
Session::set_keys(
RuntimeOrigin::signed(ii).into(),
key.clone(),
key.create_ownership_proof(&ii.encode()).unwrap().encode(),
)
.unwrap();
}
assert_eq!(Balances::free_balance(ii), 100);
if ii < 21 {
Expand Down
15 changes: 11 additions & 4 deletions cumulus/pallets/session-benchmarking/src/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,35 @@

//! Benchmarking setup for pallet-session.

use alloc::{vec, vec::Vec};
use alloc::vec::Vec;

use codec::Decode;
use frame_benchmarking::{benchmarks, whitelisted_caller};
use frame_system::RawOrigin;
use pallet_session::*;
pub struct Pallet<T: Config>(pallet_session::Pallet<T>);
pub trait Config: pallet_session::Config {}
pub trait Config: pallet_session::Config {
/// Generate a session key and a proof of ownership.
///
/// The given `owner` is the account that will call `set_keys` using the returned session keys
/// and proof. This means that the proof should prove the ownership of `owner` over the private
/// keys associated to the session keys.
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>);
}

benchmarks! {
set_keys {
let caller: T::AccountId = whitelisted_caller();
frame_system::Pallet::<T>::inc_providers(&caller);
let keys = T::Keys::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).unwrap();
let proof: Vec<u8> = vec![0,1,2,3];
let (keys, proof) = T::generate_session_keys_and_proof(caller.clone());
}: _(RawOrigin::Signed(caller), keys, proof)

purge_keys {
let caller: T::AccountId = whitelisted_caller();
frame_system::Pallet::<T>::inc_providers(&caller);
let keys = T::Keys::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()).unwrap();
let proof: Vec<u8> = vec![0,1,2,3];
let (keys, proof) = T::generate_session_keys_and_proof(caller.clone());
let _t = pallet_session::Pallet::<T>::set_keys(RawOrigin::Signed(caller.clone()).into(), keys, proof);
}: _(RawOrigin::Signed(caller))
}
12 changes: 9 additions & 3 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use sp_runtime::{
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, Permill,
};
use sp_session::OpaqueGeneratedSessionKeys;
use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork;

#[cfg(feature = "std")]
Expand Down Expand Up @@ -1216,8 +1217,8 @@ impl_runtime_apis! {
}

impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> OpaqueGeneratedSessionKeys {
SessionKeys::generate(&owner, seed).into()
}

fn decode_session_keys(
Expand Down Expand Up @@ -1468,7 +1469,12 @@ impl_runtime_apis! {
}

use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
impl cumulus_pallet_session_benchmarking::Config for Runtime {
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
let keys = SessionKeys::generate(&owner.encode(), None);
(keys.keys, keys.proof.encode())
}
}

use pallet_xcm_bridge_hub_router::benchmarking::{
Pallet as XcmBridgeHubRouterBench,
Expand Down
11 changes: 8 additions & 3 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,8 +1266,8 @@ impl_runtime_apis! {
}

impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
SessionKeys::generate(&owner, seed).into()
}

fn decode_session_keys(
Expand Down Expand Up @@ -1564,7 +1564,12 @@ impl_runtime_apis! {
}

use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
impl cumulus_pallet_session_benchmarking::Config for Runtime {
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
let keys = SessionKeys::generate(&owner.encode(), None);
(keys.keys, keys.proof.encode())
}
}

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -910,8 +910,8 @@ impl_runtime_apis! {
}

impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> sp_session::OpaqueGeneratedSessionKeys {
SessionKeys::generate(&owner, seed).into()
}

fn decode_session_keys(
Expand Down Expand Up @@ -1199,6 +1199,7 @@ impl_runtime_apis! {
) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
use sp_storage::TrackedStorageKey;
use codec::Encode;

use frame_system_benchmarking::Pallet as SystemBench;
impl frame_system_benchmarking::Config for Runtime {
Expand All @@ -1213,7 +1214,12 @@ impl_runtime_apis! {
}

use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
impl cumulus_pallet_session_benchmarking::Config for Runtime {
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
let keys = SessionKeys::generate(&owner.encode(), None);
(keys.keys, keys.proof.encode())
}
}

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use sp_runtime::{
ApplyExtrinsicResult,
};

use sp_session::OpaqueGeneratedSessionKeys;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
Expand Down Expand Up @@ -677,8 +678,8 @@ impl_runtime_apis! {
}

impl sp_session::SessionKeys<Block> for Runtime {
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
SessionKeys::generate(seed)
fn generate_session_keys(owner: Vec<u8>, seed: Option<Vec<u8>>) -> OpaqueGeneratedSessionKeys {
SessionKeys::generate(&owner, seed).into()
}

fn decode_session_keys(
Expand Down Expand Up @@ -921,6 +922,7 @@ impl_runtime_apis! {
) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {
use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
use sp_storage::TrackedStorageKey;
use codec::Encode;

use frame_system_benchmarking::Pallet as SystemBench;
impl frame_system_benchmarking::Config for Runtime {
Expand All @@ -935,7 +937,12 @@ impl_runtime_apis! {
}

use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
impl cumulus_pallet_session_benchmarking::Config for Runtime {
fn generate_session_keys_and_proof(owner: Self::AccountId) -> (Self::Keys, Vec<u8>) {
let keys = SessionKeys::generate(&owner.encode(), None);
(keys.keys, keys.proof.encode())
}
}

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
Expand Down
Loading
Loading