feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
[package]
|
||||
name = "pezpallet-people"
|
||||
version = "1.0.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
description = "Personhood-tracking pallet"
|
||||
readme = "README.md"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { workspace = true, features = ["derive"] }
|
||||
pezframe-benchmarking = { workspace = true, optional = true }
|
||||
pezframe-support = { workspace = true }
|
||||
pezframe-system = { workspace = true }
|
||||
log = { workspace = true }
|
||||
scale-info = { workspace = true, features = ["derive"] }
|
||||
pezsp-arithmetic = { workspace = true }
|
||||
pezsp-core = { workspace = true }
|
||||
pezsp-io = { workspace = true }
|
||||
pezsp-runtime = { workspace = true }
|
||||
verifiable = { workspace = true, features = ["small-ring"] }
|
||||
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"pezframe-benchmarking?/std",
|
||||
"pezframe-support/std",
|
||||
"pezframe-system/std",
|
||||
"log/std",
|
||||
"scale-info/std",
|
||||
"pezsp-arithmetic/std",
|
||||
"pezsp-core/std",
|
||||
"pezsp-io/std",
|
||||
"pezsp-runtime/std",
|
||||
"verifiable/std",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"pezframe-benchmarking/runtime-benchmarks",
|
||||
"pezframe-support/runtime-benchmarks",
|
||||
"pezframe-system/runtime-benchmarks",
|
||||
"pezsp-io/runtime-benchmarks",
|
||||
"pezsp-runtime/runtime-benchmarks",
|
||||
"verifiable/no-std-prover",
|
||||
]
|
||||
try-runtime = [
|
||||
"pezframe-support/try-runtime",
|
||||
"pezframe-system/try-runtime",
|
||||
"pezsp-runtime/try-runtime",
|
||||
]
|
||||
@@ -0,0 +1,98 @@
|
||||
# People Pallet
|
||||
|
||||
A pallet managing the registry of proven individuals.
|
||||
|
||||
## Overview
|
||||
|
||||
The People pallet stores and manages identifiers of individuals who have proven their personhood. It
|
||||
tracks their personal IDs, organizes their cryptographic keys into rings, and allows them to use
|
||||
contextual aliases through authentication in extensions. When transactions include cryptographic
|
||||
proofs of belonging to the people set, the pallet's transaction extension verifies these proofs
|
||||
before allowing the transaction to proceed. This enables other pallets to check if actions come from
|
||||
unique persons while preserving privacy through the ring-based structure.
|
||||
|
||||
The pallet accepts new persons after they prove their uniqueness elsewhere, stores their
|
||||
information, and supports removing persons via suspensions. While other systems (e.g., wallets)
|
||||
generate the proofs, this pallet handles the storage of all necessary data and verifies the proofs
|
||||
when used.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Stores Identity Data**: Tracks personal IDs and cryptographic keys of proven persons
|
||||
- **Organizes Keys**: Groups keys into rings to enable privacy-preserving proofs
|
||||
- **Verifies Proofs**: Checks personhood proofs attached to transactions
|
||||
- **Links Accounts**: Allows connecting blockchain accounts to contextual aliases
|
||||
- **Manages Registry**: Adds proven persons and will support removing them
|
||||
|
||||
## Interface
|
||||
|
||||
### Dispatchable Functions
|
||||
|
||||
- `set_alias_account(origin, account)`: Link an account to a contextual alias Once linked, this
|
||||
allows the account to dispatch transactions as a person with the alias origin using a regular
|
||||
signed transaction with a nonce, providing a simpler alternative to attaching full proofs.
|
||||
- `unset_alias_account(origin)`: Remove an account-alias link.
|
||||
- `merge_rings`: Merge the people in two rings into a single, new ring.
|
||||
- `force_recognize_personhood`: Recognize a set of people without any additional checks.
|
||||
- `set_personal_id_account`: Set a personal id account.
|
||||
- `unset_personal_id_account`: Unset the personal id account.
|
||||
- `migrate_included_key`: Migrate the key for a person who was onboarded and is currently included
|
||||
in a ring.
|
||||
- `migrate_onboarding_key`: Migrate the key for a person who is currently onboarding. The operation
|
||||
is instant, replacing the old key in the onboarding queue.
|
||||
- `set_onboarding_size`: Force set the onboarding size for new people. This call requires root
|
||||
privileges.
|
||||
- `build_ring_manual`: Manually build a ring root by including registered people. The transaction
|
||||
fee is refunded on a successful call.
|
||||
- `onboard_people_manual`: Manually onboard people into a ring. The transaction fee is refunded on
|
||||
a successful call.
|
||||
|
||||
### Automated tasks performed by the pallet in hooks
|
||||
|
||||
- Ring building: Build or update a ring's cryptographic commitment. This task processes queued keys
|
||||
into a ring commitment that enables proof generation and verification. Since ring construction, or
|
||||
rather adding keys to the ring, is computationally expensive, it's performed periodically in
|
||||
batches rather than processing each key immediately. The batch size needs to be reasonably large
|
||||
to enhance privacy by obscuring the exact timing of when individuals' keys were added to the ring,
|
||||
making it more difficult to correlate specific persons with their keys.
|
||||
- People onboarding: Onboard people from the onboarding queue into a ring. This task takes the
|
||||
unincluded keys of recognized people from the onboarding queue and registers them into the ring.
|
||||
People can be onboarded only in batches of at least `OnboardingSize` and when the remaining open
|
||||
slots in a ring are at least `OnboardingSize`. This does not compute the root, that is done using
|
||||
`build_ring`.
|
||||
- Cleaning of suspended people: Remove people's keys marked as suspended or inactive from rings. The
|
||||
keys are stored in the `PendingSuspensions` map and they are removed from rings and their roots
|
||||
are reset. The ring roots will subsequently be build in the ring building phase from scratch.
|
||||
sequentially.
|
||||
- Key migration: Migrate the keys for people who were onboarded and are currently included in rings.
|
||||
The migration is not instant as the key replacement and subsequent inclusion in a new ring root
|
||||
will happen only after the next mutation session.
|
||||
- Onboarding queue page merging: Merge the two pages at the front of the onboarding queue. After a
|
||||
round of suspensions, it is possible for the second page of the onboarding queue to be left with
|
||||
few members such that, if the first page also has few members, the total count is below the
|
||||
required onboarding size, thus stalling the queue. This function fixes this by moving the people
|
||||
from the first page to the front of the second page, defragmenting the queue.
|
||||
|
||||
### Transaction Extension
|
||||
|
||||
The pallet provides the `AsPerson` transaction extension that allows transactions to be dispatched
|
||||
with special origins: `PersonalIdentity` and `PersonalAlias`. These origins prove the transaction
|
||||
comes from a unique person, either through their identity or through a contextual alias. To make use
|
||||
of the personhood system, other pallets should check for these origins.
|
||||
|
||||
The extension verifies the proof of personhood during transaction validation and, if valid,
|
||||
transforms the transaction's origin into one of these special origins.
|
||||
|
||||
## Usage
|
||||
|
||||
Other pallets can verify personhood through origin checks:
|
||||
|
||||
- `EnsurePersonalIdentity`: Verifies the origin represents a specific person using their PersonalId
|
||||
- `EnsurePersonalAlias`: Verifies the origin has a valid alias for any context
|
||||
- `EnsurePersonalAliasInContext`: Verifies the origin has a valid alias for a specific context
|
||||
- `EnsureRevisedPersonalAlias`: Verifies the origin has a valid alias for any context and includes
|
||||
the revision of the member's ring
|
||||
- `EnsureRevisedPersonalAliasInContext`: Verifies the origin has a valid alias for a specific
|
||||
context and includes the revision of the member's ring
|
||||
|
||||
License: Apache-2.0
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,309 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! People transaction extensions.
|
||||
|
||||
use crate::*;
|
||||
use codec::{Decode, DecodeWithMemTracking, Encode};
|
||||
use core::fmt;
|
||||
use pezframe_support::{
|
||||
ensure, pezpallet_prelude::TransactionSource, traits::reality::Context, weights::Weight,
|
||||
CloneNoBound, DefaultNoBound, EqNoBound, PartialEqNoBound,
|
||||
};
|
||||
use pezframe_system::{CheckNonce, ValidNonceInfo};
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_core::twox_64;
|
||||
use pezsp_runtime::{
|
||||
traits::{DispatchInfoOf, TransactionExtension, ValidateResult},
|
||||
transaction_validity::{InvalidTransaction, TransactionValidityError, ValidTransaction},
|
||||
Saturating,
|
||||
};
|
||||
|
||||
/// Information required to transform an origin into a personal alias or personal identity.
|
||||
#[derive(
|
||||
Encode, Decode, TypeInfo, EqNoBound, CloneNoBound, PartialEqNoBound, DecodeWithMemTracking,
|
||||
)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub enum AsPersonInfo<T: Config + Send + Sync> {
|
||||
/// The signed origin will be transformed using account to alias.
|
||||
AsPersonalAliasWithAccount(T::Nonce),
|
||||
/// The none origin will be transformed using proof.
|
||||
///
|
||||
/// This can only dispatch the call `set_alias_account`.
|
||||
///
|
||||
/// Replay is only protected against resetting the same account during the tolerance period
|
||||
/// after `call_valid_at` parameter.
|
||||
/// If 2 transaction that set 2 different account are sent for an overlapping validity period,
|
||||
/// then those 2 transactions can be replayed indefinitely for the duration of the overlapping
|
||||
/// period.
|
||||
AsPersonalAliasWithProof(<T::Crypto as GenerateVerifiable>::Proof, RingIndex, Context),
|
||||
/// The none origin will be transformed using signature.
|
||||
///
|
||||
/// This can only dispatch the call `set_personal_id_account`.
|
||||
///
|
||||
/// Replay is only protected against resetting the same account during the tolerance period
|
||||
/// after `call_valid_at` parameter.
|
||||
/// If 2 transaction that set 2 different account are sent for an overlapping validity period,
|
||||
/// then those 2 transactions can be replayed indefinitely for the duration of the overlapping
|
||||
/// period.
|
||||
AsPersonalIdentityWithProof(<T::Crypto as GenerateVerifiable>::Signature, PersonalId),
|
||||
/// The signed origin will be transformed using account to personal id.
|
||||
AsPersonalIdentityWithAccount(T::Nonce),
|
||||
}
|
||||
|
||||
/// Transaction extension to transform an origin into a personal alias or personal identity.
|
||||
#[derive(
|
||||
Encode,
|
||||
Decode,
|
||||
TypeInfo,
|
||||
EqNoBound,
|
||||
CloneNoBound,
|
||||
PartialEqNoBound,
|
||||
DefaultNoBound,
|
||||
DecodeWithMemTracking,
|
||||
)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct AsPerson<T: Config + Send + Sync>(Option<AsPersonInfo<T>>);
|
||||
|
||||
impl<T: Config + Send + Sync> fmt::Debug for AsPerson<T> {
|
||||
#[cfg(feature = "std")]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "AsPerson")
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config + Send + Sync> AsPerson<T> {
|
||||
pub fn new(explicit: Option<AsPersonInfo<T>>) -> Self {
|
||||
Self(explicit)
|
||||
}
|
||||
}
|
||||
|
||||
/// Info returned by validate to prepare in the [`AsPerson`] transaction extension.
|
||||
pub enum Val<T: Config + Send + Sync> {
|
||||
NotUsing,
|
||||
UsingProof,
|
||||
UsingAccount(T::AccountId, T::Nonce),
|
||||
}
|
||||
|
||||
impl<T: Config + Send + Sync> TransactionExtension<<T as pezframe_system::Config>::RuntimeCall>
|
||||
for AsPerson<T>
|
||||
{
|
||||
const IDENTIFIER: &'static str = "AsPerson";
|
||||
type Implicit = ();
|
||||
|
||||
type Val = Val<T>;
|
||||
type Pre = ();
|
||||
|
||||
fn weight(&self, _call: &<T as pezframe_system::Config>::RuntimeCall) -> Weight {
|
||||
match self.0 {
|
||||
// Extension is passthrough
|
||||
None => Weight::zero(),
|
||||
// Alias with existing account
|
||||
Some(AsPersonInfo::AsPersonalAliasWithAccount(_)) =>
|
||||
T::WeightInfo::as_person_alias_with_account(),
|
||||
// Alias with proof
|
||||
Some(AsPersonInfo::AsPersonalAliasWithProof(_, _, _)) =>
|
||||
T::WeightInfo::as_person_alias_with_proof(),
|
||||
// Personal Identity with proof
|
||||
Some(AsPersonInfo::AsPersonalIdentityWithProof(_, _)) =>
|
||||
T::WeightInfo::as_person_identity_with_proof(),
|
||||
// Personal Identity with existing account
|
||||
Some(AsPersonInfo::AsPersonalIdentityWithAccount(_)) =>
|
||||
T::WeightInfo::as_person_identity_with_account(),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate(
|
||||
&self,
|
||||
origin: <T as pezframe_system::Config>::RuntimeOrigin,
|
||||
call: &<T as pezframe_system::Config>::RuntimeCall,
|
||||
_info: &DispatchInfoOf<<T as pezframe_system::Config>::RuntimeCall>,
|
||||
_len: usize,
|
||||
_self_implicit: Self::Implicit,
|
||||
inherited_implication: &impl Encode,
|
||||
_source: TransactionSource,
|
||||
) -> ValidateResult<Self::Val, <T as pezframe_system::Config>::RuntimeCall> {
|
||||
match &self.0 {
|
||||
Some(AsPersonInfo::AsPersonalAliasWithAccount(nonce)) => {
|
||||
let Some(pezframe_system::Origin::<T>::Signed(who)) = origin.as_system_ref() else {
|
||||
return Err(InvalidTransaction::BadSigner.into());
|
||||
};
|
||||
let who = who.clone();
|
||||
|
||||
let rev_ca = AccountToAlias::<T>::get(&who).ok_or(InvalidTransaction::BadSigner)?;
|
||||
ensure!(
|
||||
Root::<T>::get(rev_ca.ring)
|
||||
.is_some_and(|ring| ring.revision == rev_ca.revision),
|
||||
InvalidTransaction::BadSigner,
|
||||
);
|
||||
|
||||
let local_origin = Origin::PersonalAlias(rev_ca);
|
||||
let mut origin = origin;
|
||||
origin.set_caller_from(local_origin);
|
||||
|
||||
let ValidNonceInfo { requires, provides } =
|
||||
CheckNonce::<T>::validate_nonce_for_account(&who, *nonce)?;
|
||||
let validity = ValidTransaction { requires, provides, ..Default::default() };
|
||||
|
||||
Ok((validity, Val::UsingAccount(who, *nonce), origin))
|
||||
},
|
||||
Some(AsPersonInfo::AsPersonalIdentityWithAccount(nonce)) => {
|
||||
let Some(pezframe_system::Origin::<T>::Signed(who)) = origin.as_system_ref() else {
|
||||
return Err(InvalidTransaction::BadSigner.into());
|
||||
};
|
||||
let who = who.clone();
|
||||
|
||||
let id =
|
||||
AccountToPersonalId::<T>::get(&who).ok_or(InvalidTransaction::BadSigner)?;
|
||||
let local_origin = Origin::PersonalIdentity(id);
|
||||
let mut origin = origin;
|
||||
origin.set_caller_from(local_origin);
|
||||
|
||||
let ValidNonceInfo { requires, provides } =
|
||||
CheckNonce::<T>::validate_nonce_for_account(&who, *nonce)?;
|
||||
let validity = ValidTransaction { requires, provides, ..Default::default() };
|
||||
|
||||
Ok((validity, Val::UsingAccount(who, *nonce), origin))
|
||||
},
|
||||
Some(AsPersonInfo::AsPersonalAliasWithProof(proof, ring_index, context)) => {
|
||||
ensure!(
|
||||
matches!(origin.as_system_ref(), Some(pezframe_system::RawOrigin::None)),
|
||||
InvalidTransaction::BadSigner
|
||||
);
|
||||
|
||||
let Some(Call::<T>::set_alias_account { account, call_valid_at }) =
|
||||
call.is_sub_type()
|
||||
else {
|
||||
return Err(InvalidTransaction::Call.into());
|
||||
};
|
||||
|
||||
let ring = Root::<T>::get(ring_index).ok_or(InvalidTransaction::Call)?;
|
||||
let now = pezframe_system::Pallet::<T>::block_number();
|
||||
if now < *call_valid_at {
|
||||
return Err(InvalidTransaction::Future.into());
|
||||
}
|
||||
let time_tolerance = Pallet::<T>::account_setup_time_tolerance();
|
||||
if now > call_valid_at.saturating_add(time_tolerance) {
|
||||
return Err(InvalidTransaction::Stale.into());
|
||||
}
|
||||
|
||||
let msg = inherited_implication.using_encoded(pezsp_io::hashing::blake2_256);
|
||||
|
||||
let alias = T::Crypto::validate(proof, &ring.root, &context[..], &msg[..])
|
||||
.map_err(|_| InvalidTransaction::BadProof)?;
|
||||
|
||||
let rev_ca = RevisedContextualAlias {
|
||||
revision: ring.revision,
|
||||
ring: *ring_index,
|
||||
ca: ContextualAlias { alias, context: *context },
|
||||
};
|
||||
|
||||
// This protects again replay attack.
|
||||
if AccountToAlias::<T>::get(account)
|
||||
.is_some_and(|stored_rev_ca| stored_rev_ca == rev_ca)
|
||||
{
|
||||
return Err(InvalidTransaction::Stale.into());
|
||||
}
|
||||
|
||||
// The extrinsic provides the setup of the account for the alias.
|
||||
let provides = twox_64(&("setup", &rev_ca, &account).encode()[..]);
|
||||
let valid_transaction =
|
||||
ValidTransaction::with_tag_prefix("Ppl:Alias").and_provides(provides).into();
|
||||
|
||||
// We transmute the origin.
|
||||
let local_origin = Origin::PersonalAlias(rev_ca);
|
||||
let mut origin = origin;
|
||||
origin.set_caller_from(local_origin);
|
||||
|
||||
Ok((valid_transaction, Val::UsingProof, origin))
|
||||
},
|
||||
Some(AsPersonInfo::AsPersonalIdentityWithProof(signature, index)) => {
|
||||
ensure!(
|
||||
matches!(origin.as_system_ref(), Some(pezframe_system::RawOrigin::None)),
|
||||
InvalidTransaction::BadSigner
|
||||
);
|
||||
|
||||
let Some(Call::<T>::set_personal_id_account { account, call_valid_at }) =
|
||||
call.is_sub_type()
|
||||
else {
|
||||
return Err(InvalidTransaction::Call.into());
|
||||
};
|
||||
|
||||
let now = pezframe_system::Pallet::<T>::block_number();
|
||||
if now < *call_valid_at {
|
||||
return Err(InvalidTransaction::Future.into());
|
||||
}
|
||||
let time_tolerance = Pallet::<T>::account_setup_time_tolerance();
|
||||
if now > call_valid_at.saturating_add(time_tolerance) {
|
||||
return Err(InvalidTransaction::Stale.into());
|
||||
}
|
||||
|
||||
let key = People::<T>::get(index)
|
||||
.map(|record| record.key)
|
||||
.ok_or(InvalidTransaction::BadSigner)?;
|
||||
|
||||
let msg = inherited_implication.using_encoded(pezsp_io::hashing::blake2_256);
|
||||
|
||||
if !T::Crypto::verify_signature(signature, &msg[..], &key) {
|
||||
return Err(InvalidTransaction::BadProof.into());
|
||||
}
|
||||
|
||||
// This protects again replay attack.
|
||||
if People::<T>::get(index).is_some_and(|record| {
|
||||
record.account.is_some_and(|stored_account| stored_account == *account)
|
||||
}) {
|
||||
return Err(InvalidTransaction::Stale.into());
|
||||
}
|
||||
|
||||
// The extrinsic provides the setup of the account for the personal id.
|
||||
let provides = twox_64(&("setup", index, &account).encode()[..]);
|
||||
let valid_transaction =
|
||||
ValidTransaction::with_tag_prefix("Ppl:Id").and_provides(provides).into();
|
||||
|
||||
// We transmute the origin.
|
||||
let local_origin = Origin::PersonalIdentity(*index);
|
||||
let mut origin = origin;
|
||||
origin.set_caller_from(local_origin);
|
||||
|
||||
Ok((valid_transaction, Val::UsingProof, origin))
|
||||
},
|
||||
None => Ok((ValidTransaction::default(), Val::NotUsing, origin)),
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare(
|
||||
self,
|
||||
val: Self::Val,
|
||||
_origin: &<T as pezframe_system::Config>::RuntimeOrigin,
|
||||
_call: &<T as pezframe_system::Config>::RuntimeCall,
|
||||
_info: &DispatchInfoOf<<T as pezframe_system::Config>::RuntimeCall>,
|
||||
_len: usize,
|
||||
) -> Result<Self::Pre, TransactionValidityError> {
|
||||
match val {
|
||||
Val::UsingAccount(who, nonce) =>
|
||||
CheckNonce::<T>::prepare_nonce_for_account(&who, nonce)?,
|
||||
Val::NotUsing | Val::UsingProof => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,390 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::{
|
||||
extension::{AsPerson, AsPersonInfo},
|
||||
*,
|
||||
};
|
||||
use pezframe_support::{
|
||||
assert_ok, derive_impl, dispatch::DispatchErrorWithPostInfo, match_types, parameter_types,
|
||||
storage::with_transaction, weights::RuntimeDbWeight,
|
||||
};
|
||||
|
||||
use pezframe_system::{offchain::CreateTransactionBase, ChainContext};
|
||||
use pezsp_core::{ConstU16, ConstU32, ConstU64, H256};
|
||||
use pezsp_runtime::{
|
||||
testing::UintAuthorityId,
|
||||
traits::{Applyable, BlakeTwo256, Checkable, IdentityLookup},
|
||||
transaction_validity::{InvalidTransaction, TransactionSource, TransactionValidityError},
|
||||
BuildStorage, DispatchError, Weight,
|
||||
};
|
||||
use verifiable::demo_impls::Simple;
|
||||
|
||||
// First ring, used in testing.
|
||||
pub const RI_ZERO: RingIndex = 0;
|
||||
|
||||
const EXTENSION_VERSION: u8 = 0;
|
||||
pub type TransactionExtension = (AsPerson<Test>, pezframe_system::CheckNonce<Test>);
|
||||
pub type Header = pezsp_runtime::generic::Header<u64, pezsp_runtime::traits::BlakeTwo256>;
|
||||
pub type Block = pezsp_runtime::generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type UncheckedExtrinsic = pezsp_runtime::generic::UncheckedExtrinsic<
|
||||
u64,
|
||||
RuntimeCall,
|
||||
pezsp_runtime::testing::UintAuthorityId,
|
||||
TransactionExtension,
|
||||
>;
|
||||
|
||||
// Configure a mock runtime to test the pallet.
|
||||
pezframe_support::construct_runtime!(
|
||||
pub enum Test
|
||||
{
|
||||
System: pezframe_system,
|
||||
PeoplePallet: crate,
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const MockDbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
||||
read: 10,
|
||||
write: 20,
|
||||
};
|
||||
}
|
||||
|
||||
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
|
||||
impl pezframe_system::Config for Test {
|
||||
type BaseCallFilter = pezframe_support::traits::Everything;
|
||||
type BlockWeights = ();
|
||||
type BlockLength = ();
|
||||
type DbWeight = MockDbWeight;
|
||||
type RuntimeOrigin = RuntimeOrigin;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type Nonce = u64;
|
||||
type Hash = H256;
|
||||
type Hashing = BlakeTwo256;
|
||||
type AccountId = u64;
|
||||
type Lookup = IdentityLookup<Self::AccountId>;
|
||||
type Block = Block;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type BlockHashCount = ConstU64<250>;
|
||||
type Version = ();
|
||||
type PalletInfo = PalletInfo;
|
||||
type AccountData = ();
|
||||
type OnNewAccount = ();
|
||||
type OnKilledAccount = ();
|
||||
type SystemWeightInfo = ();
|
||||
type SS58Prefix = ConstU16<42>;
|
||||
type OnSetCode = ();
|
||||
type MaxConsumers = pezframe_support::traits::ConstU32<16>;
|
||||
}
|
||||
|
||||
pub type Extrinsic = pezsp_runtime::testing::TestXt<RuntimeCall, ()>;
|
||||
|
||||
impl CreateTransactionBase<Call<Self>> for Test {
|
||||
type Extrinsic = Extrinsic;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub static MaxRingSize: u32 = 10;
|
||||
}
|
||||
|
||||
pub const MOCK_CONTEXT: Context = *b"pop:pezkuwi.network/mock ";
|
||||
match_types! {
|
||||
pub type TestAccountContexts: impl Contains<Context> = {
|
||||
&MOCK_CONTEXT
|
||||
};
|
||||
}
|
||||
|
||||
pub struct MockWeights;
|
||||
impl crate::WeightInfo for MockWeights {
|
||||
fn under_alias() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(3, 3)
|
||||
}
|
||||
|
||||
fn set_alias_account() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(4, 4)
|
||||
}
|
||||
|
||||
fn unset_alias_account() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(5, 5)
|
||||
}
|
||||
|
||||
fn reset_root() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(6, 6)
|
||||
}
|
||||
|
||||
fn force_recognize_personhood() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(7, 7)
|
||||
}
|
||||
|
||||
fn set_personal_id_account() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(8, 8)
|
||||
}
|
||||
|
||||
fn unset_personal_id_account() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(9, 9)
|
||||
}
|
||||
|
||||
fn set_onboarding_size() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(10, 10)
|
||||
}
|
||||
|
||||
fn merge_rings() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(11, 11)
|
||||
}
|
||||
|
||||
fn migrate_included_key() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(12, 12)
|
||||
}
|
||||
|
||||
fn migrate_onboarding_key() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(13, 13)
|
||||
}
|
||||
|
||||
fn should_build_ring(n: u32) -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(n as u64 * 14, n as u64 * 14)
|
||||
}
|
||||
|
||||
fn build_ring(n: u32) -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(n as u64 * 14, n as u64 * 14)
|
||||
}
|
||||
|
||||
fn onboard_people() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(15, 15)
|
||||
}
|
||||
|
||||
fn remove_suspended_people(n: u32) -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(n as u64 * 16, n as u64 * 16)
|
||||
}
|
||||
|
||||
fn pending_suspensions_iteration() -> Weight {
|
||||
Weight::from_parts(1, 1)
|
||||
}
|
||||
|
||||
fn migrate_keys_single_included_key() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(17, 17)
|
||||
}
|
||||
|
||||
fn merge_queue_pages() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(18, 18)
|
||||
}
|
||||
|
||||
fn on_poll_base() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(19, 19)
|
||||
}
|
||||
|
||||
fn on_idle_base() -> pezsp_runtime::Weight {
|
||||
Weight::from_parts(20, 20)
|
||||
}
|
||||
|
||||
fn as_person_alias_with_account() -> Weight {
|
||||
Weight::from_parts(20, 20)
|
||||
}
|
||||
|
||||
fn as_person_identity_with_account() -> Weight {
|
||||
Weight::from_parts(21, 21)
|
||||
}
|
||||
|
||||
fn as_person_alias_with_proof() -> Weight {
|
||||
Weight::from_parts(22, 22)
|
||||
}
|
||||
|
||||
fn as_person_identity_with_proof() -> Weight {
|
||||
Weight::from_parts(23, 23)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Config for Test {
|
||||
type WeightInfo = MockWeights;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Crypto = verifiable::demo_impls::Simple;
|
||||
type AccountContexts = TestAccountContexts;
|
||||
type ChunkPageSize = ConstU32<5>;
|
||||
type MaxRingSize = MaxRingSize;
|
||||
type OnboardingQueuePageSize = ConstU32<40>;
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type BenchmarkHelper = BenchHelper;
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub struct BenchHelper {}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
impl<Chunk> BenchmarkHelper<Chunk> for BenchHelper
|
||||
where
|
||||
Chunk: From<<verifiable::demo_impls::Simple as verifiable::GenerateVerifiable>::StaticChunk>,
|
||||
{
|
||||
fn valid_account_context() -> Context {
|
||||
MOCK_CONTEXT
|
||||
}
|
||||
fn initialize_chunks() -> Vec<Chunk> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn advance_to(b: u64) {
|
||||
while System::block_number() < b {
|
||||
System::set_block_number(System::block_number() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConfigRecord;
|
||||
|
||||
pub fn new_config() -> ConfigRecord {
|
||||
ConfigRecord
|
||||
}
|
||||
|
||||
pub struct TestExt(ConfigRecord);
|
||||
#[allow(dead_code)]
|
||||
impl TestExt {
|
||||
pub(crate) fn max_ring_size(self, size: u32) -> Self {
|
||||
MaxRingSize::set(size);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self(new_config())
|
||||
}
|
||||
|
||||
pub fn execute_with<R>(self, f: impl Fn() -> R) -> R {
|
||||
new_test_ext().execute_with(f)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_test_ext() -> pezsp_io::TestExternalities {
|
||||
let chunks: Vec<<verifiable::demo_impls::Simple as GenerateVerifiable>::StaticChunk> =
|
||||
[(); 512].to_vec();
|
||||
let encoded_chunks = chunks.encode();
|
||||
|
||||
RuntimeGenesisConfig {
|
||||
system: Default::default(),
|
||||
people_pallet: crate::GenesisConfig::<Test> {
|
||||
encoded_chunks: encoded_chunks.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
.build_storage()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
/// We gather both error into a single type in order to do `assert_ok` and `assert_err` safely.
|
||||
/// Otherwise, we can easily miss the inner error in a `Resut<Resut<_, _>, _>`.
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub enum TransactionExecutionError {
|
||||
Validity(TransactionValidityError),
|
||||
// This ignores the post info.
|
||||
Dispatch(DispatchErrorWithPostInfo),
|
||||
}
|
||||
|
||||
impl From<DispatchErrorWithPostInfo> for TransactionExecutionError {
|
||||
fn from(e: DispatchErrorWithPostInfo) -> Self {
|
||||
TransactionExecutionError::Dispatch(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionValidityError> for TransactionExecutionError {
|
||||
fn from(e: TransactionValidityError) -> Self {
|
||||
TransactionExecutionError::Validity(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DispatchError> for TransactionExecutionError {
|
||||
fn from(e: DispatchError) -> Self {
|
||||
TransactionExecutionError::Dispatch(e.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InvalidTransaction> for TransactionExecutionError {
|
||||
fn from(e: InvalidTransaction) -> Self {
|
||||
TransactionExecutionError::Validity(e.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute a transaction with the given origin, call and transaction extension.
|
||||
pub fn exec_tx(
|
||||
who: Option<u64>,
|
||||
tx_ext: TransactionExtension,
|
||||
call: impl Into<RuntimeCall>,
|
||||
) -> Result<(), TransactionExecutionError> {
|
||||
let tx = match who {
|
||||
Some(who) => UncheckedExtrinsic::new_signed(call.into(), who, UintAuthorityId(who), tx_ext),
|
||||
None => UncheckedExtrinsic::new_transaction(call.into(), tx_ext),
|
||||
};
|
||||
|
||||
let info = tx.get_dispatch_info();
|
||||
let len = tx.encoded_size();
|
||||
|
||||
// Check and validate the extrinsic.
|
||||
let checked = Checkable::check(tx, &ChainContext::<Test>::default())?;
|
||||
with_transaction(|| {
|
||||
let valid = checked.validate::<Test>(TransactionSource::External, &info, len);
|
||||
pezsp_runtime::TransactionOutcome::Rollback(Result::<_, DispatchError>::Ok(valid))
|
||||
})
|
||||
.unwrap()?;
|
||||
// Finally, apply the extrinsic.
|
||||
checked.apply::<Test>(&info, len)??;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn exec_as_alias_tx(
|
||||
who: u64,
|
||||
call: impl Into<RuntimeCall>,
|
||||
) -> Result<(), TransactionExecutionError> {
|
||||
let nonce = pezframe_system::Account::<Test>::get(who).nonce;
|
||||
let tx_ext = (
|
||||
AsPerson::new(Some(AsPersonInfo::AsPersonalAliasWithAccount(nonce))),
|
||||
pezframe_system::CheckNonce::from(nonce),
|
||||
);
|
||||
|
||||
exec_tx(Some(who), tx_ext, call)
|
||||
}
|
||||
|
||||
/// Call `set_alias_account` for the given personal id and account.
|
||||
pub fn setup_alias_account(
|
||||
key: &<Simple as GenerateVerifiable>::Member,
|
||||
secret: &<Simple as GenerateVerifiable>::Secret,
|
||||
context: Context,
|
||||
account: u64,
|
||||
) {
|
||||
let id = crate::Keys::<Test>::get(key).expect("id not found");
|
||||
let record = crate::People::<Test>::get(id).expect("record not found");
|
||||
let ring_index = record.position.ring_index().expect("person not included in a ring");
|
||||
let commitment = {
|
||||
let all_keys = crate::RingKeys::<Test>::get(ring_index);
|
||||
Simple::open(key, all_keys.into_iter()).unwrap()
|
||||
};
|
||||
let call = RuntimeCall::PeoplePallet(crate::Call::set_alias_account {
|
||||
account,
|
||||
call_valid_at: pezframe_system::Pallet::<Test>::block_number(),
|
||||
});
|
||||
let other_tx_ext = (pezframe_system::CheckNonce::<Test>::from(0),);
|
||||
// Here we simply ignore implicit as they are null.
|
||||
let msg = (&EXTENSION_VERSION, &call, &other_tx_ext).using_encoded(pezsp_io::hashing::blake2_256);
|
||||
let (proof, _alias) =
|
||||
Simple::create(commitment, secret, &context, &msg).expect("proof creation failed");
|
||||
let tx_ext = (
|
||||
AsPerson::<Test>::new(Some(AsPersonInfo::AsPersonalAliasWithProof(
|
||||
proof, ring_index, context,
|
||||
))),
|
||||
other_tx_ext.0,
|
||||
);
|
||||
assert_ok!(exec_tx(None, tx_ext.clone(), call.clone()));
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,238 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Types for Proof-of-Personhood system.
|
||||
|
||||
#![allow(clippy::result_unit_err)]
|
||||
|
||||
use super::*;
|
||||
use pezframe_support::{pezpallet_prelude::*, DefaultNoBound};
|
||||
|
||||
pub type RevisionIndex = u32;
|
||||
pub type PageIndex = u32;
|
||||
pub type KeyCount = u64;
|
||||
|
||||
pub type MemberOf<T> = <<T as Config>::Crypto as GenerateVerifiable>::Member;
|
||||
pub type MembersOf<T> = <<T as Config>::Crypto as GenerateVerifiable>::Members;
|
||||
pub type IntermediateOf<T> = <<T as Config>::Crypto as GenerateVerifiable>::Intermediate;
|
||||
pub type SecretOf<T> = <<T as Config>::Crypto as GenerateVerifiable>::Secret;
|
||||
pub type SignatureOf<T> = <<T as Config>::Crypto as GenerateVerifiable>::Signature;
|
||||
pub type ChunksOf<T> = BoundedVec<
|
||||
<<T as Config>::Crypto as GenerateVerifiable>::StaticChunk,
|
||||
<T as Config>::ChunkPageSize,
|
||||
>;
|
||||
|
||||
/// The overarching state of all people rings regarding the actions that are currently allowed to be
|
||||
/// performed on them.
|
||||
#[derive(
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
RuntimeDebug,
|
||||
Encode,
|
||||
Decode,
|
||||
MaxEncodedLen,
|
||||
TypeInfo,
|
||||
DecodeWithMemTracking,
|
||||
)]
|
||||
pub enum RingMembersState {
|
||||
/// The rings can accept new people sequentially if the maximum capacity has not been reached
|
||||
/// yet. Ring building is permitted in this state by building the ring roots on top of
|
||||
/// previously computed roots. In case a ring suffered mutations that invalidated a previous
|
||||
/// ring root through the removal of an included member, the existing ring root will be removed
|
||||
/// and ring building will start from scratch.
|
||||
AppendOnly,
|
||||
/// A semaphore counting the number of entities making changes to the ring members list which
|
||||
/// require the entire ring to be rebuilt. Whenever a DIM would want to suspend
|
||||
/// people, it would first need to increment this counter and then start submitting the
|
||||
/// suspended indices. After all indices are registered, the counter is decremented. Ring
|
||||
/// merges are allowed only when no entity is allowed to suspend keys and the counter is 0.
|
||||
Mutating(u8),
|
||||
/// After mutations to the member set, any pending key migrations are enacted before the new
|
||||
/// ring roots will be built in order to reflect the latest changes in state.
|
||||
KeyMigration,
|
||||
}
|
||||
|
||||
impl Default for RingMembersState {
|
||||
fn default() -> Self {
|
||||
Self::AppendOnly
|
||||
}
|
||||
}
|
||||
|
||||
impl RingMembersState {
|
||||
/// Returns whether the state allows only incremental additions to rings and their roots.
|
||||
pub fn append_only(&self) -> bool {
|
||||
matches!(self, Self::AppendOnly)
|
||||
}
|
||||
|
||||
/// Returns whether the state allows mutating the member set of rings.
|
||||
pub fn mutating(&self) -> bool {
|
||||
matches!(self, Self::Mutating(_))
|
||||
}
|
||||
|
||||
/// Returns whether the state allows the pending key migrations to be enacted.
|
||||
pub fn key_migration(&self) -> bool {
|
||||
matches!(self, Self::KeyMigration)
|
||||
}
|
||||
|
||||
/// Move to a mutation state.
|
||||
pub fn start_mutation_session(self) -> Result<Self, ()> {
|
||||
match self {
|
||||
Self::AppendOnly => Ok(Self::Mutating(1)),
|
||||
Self::Mutating(n) => Ok(Self::Mutating(n.checked_add(1).ok_or(())?)),
|
||||
Self::KeyMigration => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Move out of a mutation state.
|
||||
pub fn end_mutation_session(self) -> Result<Self, ()> {
|
||||
match self {
|
||||
Self::AppendOnly => Err(()),
|
||||
Self::Mutating(1) => Ok(Self::KeyMigration),
|
||||
Self::Mutating(n) => Ok(Self::Mutating(n.saturating_sub(1))),
|
||||
Self::KeyMigration => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Move out of a key migration state.
|
||||
pub fn end_key_migration(self) -> Result<Self, ()> {
|
||||
match self {
|
||||
Self::KeyMigration => Ok(Self::AppendOnly),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A contextual alias [`ContextualAlias`] used in a specific ring revision.
|
||||
///
|
||||
/// The revision can be used to tell in the future if an alias may have been suspended.
|
||||
/// For instance, if a person is suspended, then ring will get revised, the revised alias with the
|
||||
/// old revision shows that the alias may not be owned by a valid person anymore.
|
||||
#[derive(
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
RuntimeDebug,
|
||||
Encode,
|
||||
Decode,
|
||||
MaxEncodedLen,
|
||||
TypeInfo,
|
||||
DecodeWithMemTracking,
|
||||
)]
|
||||
pub struct RevisedContextualAlias {
|
||||
pub revision: RevisionIndex,
|
||||
pub ring: RingIndex,
|
||||
pub ca: ContextualAlias,
|
||||
}
|
||||
|
||||
/// An alias [`Alias`] used in a specific ring revision.
|
||||
///
|
||||
/// The revision can be used to tell in the future if an alias may have been suspended.
|
||||
/// For instance, if a person is suspended, then ring will get revised, the revised alias with the
|
||||
/// old revision shows that the alias may not be owned by a valid person anymore.
|
||||
#[derive(Clone, PartialEq, Eq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||
pub struct RevisedAlias {
|
||||
pub revision: RevisionIndex,
|
||||
pub ring: RingIndex,
|
||||
pub alias: Alias,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct RingRoot<T: Config> {
|
||||
/// The ring root for the current ring.
|
||||
pub root: MembersOf<T>,
|
||||
/// The revision index of the ring.
|
||||
pub revision: RevisionIndex,
|
||||
/// An intermediate value if the ring is not full.
|
||||
pub intermediate: IntermediateOf<T>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen, DefaultNoBound,
|
||||
)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
/// Information about the current key inclusion status in a ring.
|
||||
pub struct RingStatus {
|
||||
/// The number of keys in the ring.
|
||||
pub total: u32,
|
||||
/// The number of keys that have already been baked in.
|
||||
pub included: u32,
|
||||
}
|
||||
|
||||
/// The state of a person's key within the pallet along with its position in relevant structures.
|
||||
///
|
||||
/// Differentiates between individuals included in a ring, those being onboarded and the suspended
|
||||
/// ones. For those already included, provides ring index and position in it. For those being
|
||||
/// onboarded, provides queue page index and position in the queue.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
pub enum RingPosition {
|
||||
/// Coordinates within the onboarding queue for a person that doesn't belong to a ring yet.
|
||||
Onboarding { queue_page: PageIndex },
|
||||
/// Coordinates within the rings for a person that was registered.
|
||||
Included { ring_index: RingIndex, ring_position: u32, scheduled_for_removal: bool },
|
||||
/// The person is suspended and isn't part of any ring or onboarding queue page.
|
||||
Suspended,
|
||||
}
|
||||
|
||||
impl RingPosition {
|
||||
/// Returns whether the person is suspended and has no position.
|
||||
pub fn suspended(&self) -> bool {
|
||||
matches!(self, Self::Suspended)
|
||||
}
|
||||
|
||||
/// Returns whether the person is included in a ring and is scheduled for removal.
|
||||
pub fn scheduled_for_removal(&self) -> bool {
|
||||
match &self {
|
||||
Self::Included { scheduled_for_removal, .. } => *scheduled_for_removal,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the index of the ring if this person is included.
|
||||
pub fn ring_index(&self) -> Option<RingIndex> {
|
||||
match &self {
|
||||
Self::Included { ring_index, .. } => Some(*ring_index),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Record of personhood.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
pub struct PersonRecord<Member, AccountId> {
|
||||
// The key used for the person.
|
||||
pub key: Member,
|
||||
// The position identifier of the key.
|
||||
pub position: RingPosition,
|
||||
/// An optional privileged account that can send transaction on the behalf of the person.
|
||||
pub account: Option<AccountId>,
|
||||
}
|
||||
|
||||
/// Describes the action to take after checking the first two pages of the onboarding queue for a
|
||||
/// potential merge.
|
||||
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub(crate) enum QueueMergeAction<T: Config> {
|
||||
Merge {
|
||||
initial_head: PageIndex,
|
||||
new_head: PageIndex,
|
||||
first_key_page: BoundedVec<MemberOf<T>, T::OnboardingQueuePageSize>,
|
||||
second_key_page: BoundedVec<MemberOf<T>, T::OnboardingQueuePageSize>,
|
||||
},
|
||||
NoAction,
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
// This file is part of Bizinikiwi.
|
||||
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Autogenerated weights for pezpallet_ranked_collective
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 4.0.0-dev
|
||||
//! DATE: 2022-05-19, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
|
||||
//! EXECUTION: None, WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
|
||||
|
||||
// Executed Command:
|
||||
// /Users/gav/Core/bizinikiwi/target/release/bizinikiwi
|
||||
// benchmark
|
||||
// pallet
|
||||
// --pallet
|
||||
// pezpallet-ranked-collective
|
||||
// --extrinsic=*
|
||||
// --chain=dev
|
||||
// --steps=50
|
||||
// --repeat=20
|
||||
// --output=../../../frame/ranked-collective/src/weights.rs
|
||||
// --template=../../../.maintain/frame-weight-template.hbs
|
||||
// --header=../../../HEADER-APACHE2
|
||||
// --record-proof
|
||||
|
||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||
#![allow(unused_parens)]
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
/// Weight functions needed for pezpallet_ranked_collective.
|
||||
pub trait WeightInfo {
|
||||
fn under_alias() -> Weight;
|
||||
fn set_alias_account() -> Weight;
|
||||
fn unset_alias_account() -> Weight;
|
||||
fn reset_root() -> Weight;
|
||||
fn force_recognize_personhood() -> Weight;
|
||||
fn set_personal_id_account() -> Weight;
|
||||
fn unset_personal_id_account() -> Weight;
|
||||
fn set_onboarding_size() -> Weight;
|
||||
fn merge_rings() -> Weight;
|
||||
fn migrate_included_key() -> Weight;
|
||||
fn migrate_onboarding_key() -> Weight;
|
||||
fn should_build_ring(n: u32) -> Weight;
|
||||
fn build_ring(n: u32) -> Weight;
|
||||
fn onboard_people() -> Weight;
|
||||
fn remove_suspended_people(n: u32) -> Weight;
|
||||
fn pending_suspensions_iteration() -> Weight;
|
||||
fn migrate_keys_single_included_key() -> Weight;
|
||||
fn merge_queue_pages() -> Weight;
|
||||
fn as_person_alias_with_account() -> Weight;
|
||||
fn as_person_identity_with_account() -> Weight;
|
||||
fn as_person_alias_with_proof() -> Weight;
|
||||
fn as_person_identity_with_proof() -> Weight;
|
||||
fn on_poll_base() -> Weight;
|
||||
fn on_idle_base() -> Weight;
|
||||
}
|
||||
|
||||
pub struct BizinikiwiWeight<T>(PhantomData<T>);
|
||||
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
|
||||
fn under_alias() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_alias_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn unset_alias_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn reset_root() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn force_recognize_personhood() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_personal_id_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn unset_personal_id_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_onboarding_size() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn merge_rings() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_included_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_onboarding_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn should_build_ring(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn build_ring(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn onboard_people() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn remove_suspended_people(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn pending_suspensions_iteration() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_keys_single_included_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn merge_queue_pages() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_alias_with_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_identity_with_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_alias_with_proof() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_identity_with_proof() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn on_poll_base() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn on_idle_base() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
}
|
||||
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
fn under_alias() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_alias_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn unset_alias_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn reset_root() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn force_recognize_personhood() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_personal_id_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn unset_personal_id_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn set_onboarding_size() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn merge_rings() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_included_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_onboarding_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn should_build_ring(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn build_ring(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn onboard_people() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn remove_suspended_people(_n: u32) -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn pending_suspensions_iteration() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn migrate_keys_single_included_key() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn merge_queue_pages() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_alias_with_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_identity_with_account() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_alias_with_proof() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn as_person_identity_with_proof() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn on_poll_base() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
|
||||
fn on_idle_base() -> Weight {
|
||||
Weight::zero()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user