Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nodes/rust/duniter-v2s
  • llaq/lc-core-substrate
  • pini-gh/duniter-v2s
  • vincentux/duniter-v2s
  • mildred/duniter-v2s
  • d0p1/duniter-v2s
  • bgallois/duniter-v2s
  • Nicolas80/duniter-v2s
8 results
Show changes
Showing
with 394 additions and 174 deletions
......@@ -96,12 +96,6 @@ pub fn development_chain_spec() -> Result<ChainSpec, String> {
)
},
Some(get_authority_keys_from_seed("Alice").encode()),
Some(super::gen_genesis_data::ParamsAppliedAtGenesis {
genesis_certs_expire_on: 100_000,
genesis_smith_certs_expire_on: 100_000,
genesis_memberships_expire_on: 100_000,
genesis_smith_memberships_expire_on: 100_000,
}),
)
} else {
Ok(ChainSpec::from_genesis(
......@@ -163,9 +157,15 @@ pub fn gen_live_conf() -> Result<ChainSpec, String> {
// Bootnodes
vec![],
// Telemetry
None,
Some(
sc_service::config::TelemetryEndpoints::new(vec![(
"wss://telemetry.polkadot.io/submit/".to_owned(),
0,
)])
.expect("invalid telemetry endpoints"),
),
// Protocol ID
None,
Some("gdev2"),
//Fork ID
None,
// Properties
......@@ -183,12 +183,6 @@ pub fn gen_live_conf() -> Result<ChainSpec, String> {
)
},
None,
Some(super::gen_genesis_data::ParamsAppliedAtGenesis {
genesis_certs_expire_on: 100_000,
genesis_smith_certs_expire_on: 100_000,
genesis_memberships_expire_on: 100_000,
genesis_smith_memberships_expire_on: 100_000,
}),
)
}
......@@ -312,7 +306,7 @@ fn gen_genesis_for_local_chain(
smith_cert_period: 15,
smith_cert_max_by_issuer: 8,
smith_cert_min_received_cert_to_issue_cert: 2,
smith_cert_validity_period: 1_000,
smith_cert_validity_period,
smith_membership_period,
smith_pending_membership_period: 500,
smiths_wot_first_cert_issuable_on: 20,
......@@ -387,7 +381,7 @@ fn gen_genesis_for_local_chain(
},
cert: CertConfig {
apply_cert_period_at_genesis: false,
certs_by_receiver: clique_wot(initial_identities.len(), cert_validity_period),
certs_by_receiver: clique_wot(initial_identities.len()),
},
smiths_membership: SmithsMembershipConfig {
memberships: (1..=initial_smiths_len)
......@@ -396,7 +390,7 @@ fn gen_genesis_for_local_chain(
},
smiths_cert: SmithsCertConfig {
apply_cert_period_at_genesis: false,
certs_by_receiver: clique_wot(initial_smiths_len, smith_cert_validity_period),
certs_by_receiver: clique_wot(initial_smiths_len),
},
universal_dividend: UniversalDividendConfig {
first_reeval: 100,
......
......@@ -26,7 +26,7 @@ const EXISTENTIAL_DEPOSIT: u64 = 100;
#[derive(Clone)]
pub struct GenesisData<Parameters: DeserializeOwned, SessionKeys: Decode> {
pub accounts: BTreeMap<AccountId, GenesisAccountData<u64>>,
pub certs_by_receiver: BTreeMap<u32, BTreeMap<u32, u32>>,
pub certs_by_receiver: BTreeMap<u32, BTreeMap<u32, Option<u32>>>,
pub first_ud: u64,
pub first_ud_reeval: u32,
pub identities: Vec<(String, AccountId)>,
......@@ -35,17 +35,17 @@ pub struct GenesisData<Parameters: DeserializeOwned, SessionKeys: Decode> {
pub memberships: BTreeMap<u32, MembershipData>,
pub parameters: Parameters,
pub session_keys_map: BTreeMap<AccountId, SessionKeys>,
pub smiths_certs_by_receiver: BTreeMap<u32, BTreeMap<u32, u32>>,
pub smiths_certs_by_receiver: BTreeMap<u32, BTreeMap<u32, Option<u32>>>,
pub smiths_memberships: BTreeMap<u32, MembershipData>,
pub sudo_key: Option<AccountId>,
pub technical_committee_members: Vec<AccountId>,
}
#[derive(Default)]
#[derive(Default, Deserialize, Serialize)]
pub struct ParamsAppliedAtGenesis {
pub genesis_certs_expire_on: u32,
pub genesis_smith_certs_expire_on: u32,
pub genesis_certs_min_received: u32,
pub genesis_memberships_expire_on: u32,
pub genesis_smith_certs_min_received: u32,
pub genesis_smith_memberships_expire_on: u32,
}
......@@ -53,6 +53,7 @@ pub struct ParamsAppliedAtGenesis {
struct GenesisConfig<Parameters> {
first_ud: u64,
first_ud_reeval: u32,
genesis_parameters: ParamsAppliedAtGenesis,
identities: BTreeMap<String, Idty>,
#[serde(default)]
parameters: Parameters,
......@@ -85,20 +86,12 @@ struct SmithData {
pub fn generate_genesis_data<CS, P, SK, F>(
f: F,
maybe_force_authority: Option<Vec<u8>>,
params_applied_at_genesis: Option<ParamsAppliedAtGenesis>,
) -> Result<CS, String>
where
P: Default + DeserializeOwned,
SK: Decode,
F: Fn(GenesisData<P, SK>) -> CS,
{
let ParamsAppliedAtGenesis {
genesis_certs_expire_on,
genesis_smith_certs_expire_on,
genesis_memberships_expire_on,
genesis_smith_memberships_expire_on,
} = params_applied_at_genesis.unwrap_or_default();
let genesis_timestamp: u64 =
if let Ok(genesis_timestamp) = std::env::var("DUNITER_GENESIS_TIMESTAMP") {
genesis_timestamp
......@@ -133,6 +126,13 @@ where
sudo_key,
first_ud,
first_ud_reeval,
genesis_parameters:
ParamsAppliedAtGenesis {
genesis_certs_min_received,
genesis_memberships_expire_on,
genesis_smith_certs_min_received,
genesis_smith_memberships_expire_on,
},
parameters,
identities,
smith_identities,
......@@ -233,11 +233,23 @@ where
let issuer_index = idty_index_of
.get(issuer)
.ok_or(format!("Identity '{}' not exist", issuer))?;
receiver_certs.insert(*issuer_index, genesis_certs_expire_on);
receiver_certs.insert(*issuer_index, None);
}
certs_by_receiver.insert(*issuer_index, receiver_certs);
}
// Verify certifications coherence
for (idty_index, receiver_certs) in &certs_by_receiver {
if receiver_certs.len() < genesis_certs_min_received as usize {
return Err(format!(
"Identity n°{} has received only {}/{} certifications)",
idty_index,
receiver_certs.len(),
genesis_certs_min_received
));
}
}
// SMITHS SUB-WOT //
let mut initial_authorities = BTreeMap::new();
......@@ -303,7 +315,7 @@ where
let issuer_index = idty_index_of
.get(receiver)
.ok_or(format!("Identity '{}' not exist", receiver))?;
receiver_certs.insert(*issuer_index, genesis_smith_certs_expire_on);
receiver_certs.insert(*issuer_index, None);
}
smiths_certs_by_receiver.insert(*idty_index, receiver_certs);
......@@ -316,6 +328,24 @@ where
);
}
// Verify smiths certifications coherence
if smiths_certs_by_receiver.len() < smiths_memberships.len() {
return Err(format!(
"{} smith identities has not received any smiths certifications",
smiths_memberships.len() - smiths_certs_by_receiver.len()
));
}
for (idty_index, receiver_certs) in &smiths_certs_by_receiver {
if receiver_certs.len() < genesis_smith_certs_min_received as usize {
return Err(format!(
"Identity n°{} has received only {}/{} smiths certifications)",
idty_index,
receiver_certs.len(),
genesis_smith_certs_min_received
));
}
}
if maybe_force_authority.is_none() && online_authorities_counter == 0 {
return Err("The session_keys field must be filled in for at least one smith.".to_owned());
}
......
......@@ -46,23 +46,23 @@ version = "3.1.5"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.pallet-session]
default-features = false
features = ["historical"]
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.serde]
version = "1.0.101"
......@@ -72,22 +72,22 @@ features = ["derive"]
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-staking]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......@@ -104,4 +104,4 @@ version = '1.0.119'
[dev-dependencies.sp-io]
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
......@@ -39,17 +39,17 @@ version = "3.1.5"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.serde]
version = "1.0.101"
......@@ -59,17 +59,17 @@ features = ["derive"]
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......@@ -86,4 +86,4 @@ version = '1.0.2'
[dev-dependencies.sp-io]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
......@@ -90,9 +90,11 @@ pub mod pallet {
// GENESIS STUFF //
#[pallet::genesis_config]
#[allow(clippy::type_complexity)]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
pub apply_cert_period_at_genesis: bool,
pub certs_by_receiver: BTreeMap<T::IdtyIndex, BTreeMap<T::IdtyIndex, T::BlockNumber>>,
pub certs_by_receiver:
BTreeMap<T::IdtyIndex, BTreeMap<T::IdtyIndex, Option<T::BlockNumber>>>,
}
#[cfg(feature = "std")]
......@@ -128,7 +130,8 @@ pub mod pallet {
received_count: issuers.len() as u32,
});
for (issuer, removable_on) in issuers {
let mut issuers_: Vec<_> = Vec::with_capacity(issuers.len());
for (issuer, maybe_removable_on) in issuers {
// Count issued certs
cert_meta_by_issuer
.entry(*issuer)
......@@ -139,9 +142,13 @@ pub mod pallet {
})
.issued_count += 1;
// Compute and store removable_on
let removable_on = maybe_removable_on.unwrap_or_else(T::ValidityPeriod::get);
issuers_.push((*issuer, removable_on));
// Prepare CertsRemovableOn
certs_removable_on
.entry(*removable_on)
.entry(removable_on)
.or_default()
.push((*issuer, *receiver));
......@@ -158,9 +165,8 @@ pub mod pallet {
}
// Write CertsByReceiver
let mut issuers: Vec<_> = issuers.iter().collect();
issuers.sort();
CertsByReceiver::<T, I>::insert(receiver, issuers);
issuers_.sort();
CertsByReceiver::<T, I>::insert(receiver, issuers_);
}
// Write StorageIdtyCertMeta
......
......@@ -42,8 +42,8 @@ fn test_cannot_certify_self() {
apply_cert_period_at_genesis: true,
certs_by_receiver: btreemap![
0 => btreemap![
1 => 5,
2 => 5,
1 => Some(5),
2 => Some(5),
],
],
})
......@@ -63,16 +63,16 @@ fn test_genesis_build() {
apply_cert_period_at_genesis: true,
certs_by_receiver: btreemap![
0 => btreemap![
1 => 7,
2 => 9,
1 => Some(7),
2 => Some(9),
],
1 => btreemap![
0 => 10,
2 => 3,
0 => Some(10),
2 => Some(3),
],
2 => btreemap![
0 => 5,
1 => 4,
0 => Some(5),
1 => Some(4),
],
],
})
......@@ -132,16 +132,16 @@ fn test_cert_period() {
apply_cert_period_at_genesis: true,
certs_by_receiver: btreemap![
0 => btreemap![
1 => 10,
2 => 10,
1 => Some(10),
2 => Some(10),
],
1 => btreemap![
0 => 10,
2 => 10,
0 => Some(10),
2 => Some(10),
],
2 => btreemap![
0 => 10,
1 => 10,
0 => Some(10),
1 => Some(10),
],
],
})
......
......@@ -42,27 +42,27 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.pallet-balances]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.pallet-treasury]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.serde]
version = "1.0.101"
......@@ -72,22 +72,22 @@ features = ["derive"]
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-io]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......@@ -98,7 +98,7 @@ targets = ['x86_64-unknown-linux-gnu']
[dev-dependencies.pallet-balances]
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dev-dependencies.maplit]
version = '1.0.2'
......@@ -108,4 +108,4 @@ version = '1.0.119'
[dev-dependencies.sp-io]
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
......@@ -54,7 +54,9 @@ pub mod pallet {
type AccountIdToSalt: Convert<Self::AccountId, [u8; 32]>;
/// The overarching event type.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
#[pallet::constant]
type MaxNewAccountsPerBlock: Get<u32>;
#[pallet::constant]
type NewAccountPrice: Get<Self::Balance>;
}
......
......@@ -39,32 +39,32 @@ version = "3.1.5"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-io]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......
......@@ -48,17 +48,17 @@ version = "3.1.5"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.serde]
version = "1.0.101"
......@@ -68,22 +68,22 @@ features = ["derive"]
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-io]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......@@ -96,4 +96,4 @@ version = '1.0.119'
[dev-dependencies.sp-io]
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
......@@ -17,9 +17,6 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::type_complexity)]
//pub mod traits;
mod types;
#[cfg(test)]
mod mock;
......@@ -30,14 +27,12 @@ mod tests;
mod benchmarking;*/
pub use pallet::*;
pub use types::*;
use frame_support::dispatch::UnfilteredDispatchable;
use frame_support::pallet_prelude::*;
use frame_system::RawOrigin;
use pallet_certification::traits::SetNextIssuableOn;
use pallet_identity::{IdtyEvent, IdtyStatus};
use sp_membership::traits::IsInPendingMemberships;
use sp_runtime::traits::IsMember;
type IdtyIndex = u32;
......@@ -65,9 +60,13 @@ pub mod pallet {
+ pallet_identity::Config<IdtyIndex = IdtyIndex>
+ pallet_membership::Config<I, IdtyId = IdtyIndex>
{
#[pallet::constant]
type FirstIssuableOn: Get<Self::BlockNumber>;
#[pallet::constant]
type IsSubWot: Get<bool>;
#[pallet::constant]
type MinCertForMembership: Get<u32>;
#[pallet::constant]
type MinCertForCreateIdtyRight: Get<u32>;
}
......@@ -98,32 +97,57 @@ pub mod pallet {
impl<AccountId, T: Config<I>, I: 'static> pallet_identity::traits::EnsureIdtyCallAllowed<T>
for Pallet<T, I>
where
T: frame_system::Config<AccountId = AccountId>
+ pallet_membership::Config<I, MetaData = MembershipMetaData<AccountId>>,
T: frame_system::Config<AccountId = AccountId> + pallet_membership::Config<I>,
{
fn can_create_identity(creator: IdtyIndex) -> bool {
let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator);
cert_meta.received_count >= T::MinCertForCreateIdtyRight::get()
&& cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
&& cert_meta.issued_count < T::MaxByIssuer::get()
if !T::IsSubWot::get() {
let cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(creator);
cert_meta.received_count >= T::MinCertForCreateIdtyRight::get()
&& cert_meta.next_issuable_on <= frame_system::pallet::Pallet::<T>::block_number()
&& cert_meta.issued_count < T::MaxByIssuer::get()
} else {
true
}
}
fn can_confirm_identity(idty_index: IdtyIndex, owner_key: AccountId) -> bool {
pallet_membership::Pallet::<T, I>::force_request_membership(
RawOrigin::Root.into(),
idty_index,
MembershipMetaData(owner_key),
)
.is_ok()
fn can_confirm_identity(idty_index: IdtyIndex) -> bool {
if !T::IsSubWot::get() {
pallet_membership::Pallet::<T, I>::force_request_membership(
RawOrigin::Root.into(),
idty_index,
Default::default(),
)
.is_ok()
} else {
true
}
}
fn can_validate_identity(idty_index: IdtyIndex) -> bool {
// TODO replace this code by te commented one for distance feature
/*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/
pallet_membership::Pallet::<T, I>::claim_membership(
RawOrigin::Root.into(),
Some(idty_index),
)
.is_ok()
if !T::IsSubWot::get() {
// TODO replace this code by the commented one for distance feature
/*let idty_cert_meta = pallet_certification::Pallet::<T, I>::idty_cert_meta(idty_index);
idty_cert_meta.received_count >= T::MinCertForMembership::get() as u32*/
pallet_membership::Pallet::<T, I>::claim_membership(
RawOrigin::Root.into(),
Some(idty_index),
)
.is_ok()
} else {
true
}
}
fn can_change_identity_address(idty_index: IdtyIndex) -> bool {
if T::IsSubWot::get() {
!pallet_membership::Pallet::<T, I>::is_member(&idty_index)
} else {
true
}
}
fn can_remove_identity(idty_index: IdtyIndex) -> bool {
if T::IsSubWot::get() {
!pallet_membership::Pallet::<T, I>::is_member(&idty_index)
} else {
true
}
}
}
......@@ -137,14 +161,8 @@ impl<T: Config<I>, I: 'static> pallet_certification::traits::IsCertAllowed<IdtyI
}
if let Some(receiver_data) = pallet_identity::Pallet::<T>::identity(receiver) {
match receiver_data.status {
IdtyStatus::ConfirmedByOwner => true,
IdtyStatus::ConfirmedByOwner | IdtyStatus::Validated => true,
IdtyStatus::Created => false,
IdtyStatus::Validated => {
pallet_membership::Pallet::<T, I>::is_member(&receiver)
|| pallet_membership::Pallet::<T, I>::is_in_pending_memberships(
receiver,
)
}
}
} else {
// Receiver not found
......
......@@ -122,7 +122,7 @@ impl pallet_identity::Config for Test {
type ChangeOwnerKeyPeriod = ChangeOwnerKeyPeriod;
type ConfirmPeriod = ConfirmPeriod;
type Event = Event;
type EnsureIdtyCallAllowed = DuniterWot;
type EnsureIdtyCallAllowed = (DuniterWot, SmithsSubWot);
type IdtyCreationPeriod = IdtyCreationPeriod;
type IdtyData = ();
type IdtyNameValidator = IdtyNameValidatorTestImpl;
......@@ -150,7 +150,7 @@ impl pallet_membership::Config<Instance1> for Test {
type IdtyId = IdtyIndex;
type IdtyIdOf = IdentityIndexOf<Self>;
type MembershipPeriod = MembershipPeriod;
type MetaData = crate::MembershipMetaData<u64>;
type MetaData = ();
type OnEvent = DuniterWot;
type PendingMembershipPeriod = PendingMembershipPeriod;
type RevocationPeriod = RevocationPeriod;
......@@ -206,7 +206,7 @@ impl pallet_membership::Config<Instance2> for Test {
type IdtyId = IdtyIndex;
type IdtyIdOf = IdentityIndexOf<Self>;
type MembershipPeriod = SmithsMembershipPeriod;
type MetaData = crate::MembershipMetaData<u64>;
type MetaData = ();
type OnEvent = SmithsSubWot;
type PendingMembershipPeriod = SmithsPendingMembershipPeriod;
type RevocationPeriod = SmithsRevocationPeriod;
......@@ -347,7 +347,7 @@ pub fn run_to_block(n: u64) {
fn clique_wot(
initial_identities_len: usize,
cert_validity_period: u64,
) -> BTreeMap<IdtyIndex, BTreeMap<IdtyIndex, u64>> {
) -> BTreeMap<IdtyIndex, BTreeMap<IdtyIndex, Option<u64>>> {
let mut certs_by_issuer = BTreeMap::new();
for i in 1..=initial_identities_len {
certs_by_issuer.insert(
......@@ -355,7 +355,7 @@ fn clique_wot(
(1..=initial_identities_len)
.filter_map(|j| {
if i != j {
Some((j as IdtyIndex, cert_validity_period))
Some((j as IdtyIndex, Some(cert_validity_period)))
} else {
None
}
......
......@@ -16,11 +16,15 @@
use crate::mock::*;
use crate::mock::{Identity, System};
use frame_support::assert_noop;
use frame_support::assert_ok;
use codec::Encode;
use frame_support::instances::Instance1;
use frame_support::{assert_noop, assert_ok};
use frame_system::{EventRecord, Phase};
use pallet_identity::{IdtyName, IdtyStatus};
use pallet_identity::{
IdtyName, IdtyStatus, NewOwnerKeyPayload, RevocationPayload, NEW_OWNER_KEY_PAYLOAD_PREFIX,
REVOCATION_PAYLOAD_PREFIX,
};
use sp_runtime::testing::TestSignature;
#[test]
fn test_genesis_build() {
......@@ -56,10 +60,7 @@ fn test_join_smiths() {
run_to_block(2);
// Dave shoud be able to request smith membership
assert_ok!(SmithsMembership::request_membership(
Origin::signed(4),
crate::MembershipMetaData(4)
));
assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ()));
System::assert_has_event(Event::SmithsMembership(
pallet_membership::Event::MembershipRequested(4),
));
......@@ -95,6 +96,53 @@ fn test_smith_certs_expirations_should_revoke_smith_membership() {
});
}
#[test]
fn test_smith_member_cant_change_its_idty_address() {
new_test_ext(5, 3).execute_with(|| {
run_to_block(2);
let genesis_hash = System::block_hash(0);
let new_key_payload = NewOwnerKeyPayload {
genesis_hash: &genesis_hash,
idty_index: 3u32,
old_owner_key: &3u64,
};
// Identity 3 can't change it's address
assert_noop!(
Identity::change_owner_key(
Origin::signed(3),
13,
TestSignature(13, (NEW_OWNER_KEY_PAYLOAD_PREFIX, new_key_payload).encode())
),
pallet_identity::Error::<Test>::NotAllowedToChangeIdtyAddress
);
});
}
#[test]
fn test_smith_member_cant_revoke_its_idty() {
new_test_ext(5, 3).execute_with(|| {
run_to_block(2);
let revocation_payload = RevocationPayload {
idty_index: 3u32,
genesis_hash: System::block_hash(0),
};
// Identity 3 can't change it's address
assert_noop!(
Identity::revoke_identity(
Origin::signed(3),
3,
3,
TestSignature(3, (REVOCATION_PAYLOAD_PREFIX, revocation_payload).encode())
),
pallet_identity::Error::<Test>::NotAllowedToRemoveIdty
);
});
}
#[test]
fn test_revoke_smiths_them_rejoin() {
new_test_ext(5, 4).execute_with(|| {
......@@ -109,16 +157,13 @@ fn test_revoke_smiths_them_rejoin() {
// Dave should not be able to re-request membership before the RevocationPeriod end
run_to_block(3);
assert_noop!(
SmithsMembership::request_membership(Origin::signed(4), crate::MembershipMetaData(4)),
SmithsMembership::request_membership(Origin::signed(4), ()),
pallet_membership::Error::<Test, crate::Instance2>::MembershipRevokedRecently
);
// At block #6, Dave shoud be able to request smith membership
run_to_block(6);
assert_ok!(SmithsMembership::request_membership(
Origin::signed(4),
crate::MembershipMetaData(4)
));
assert_ok!(SmithsMembership::request_membership(Origin::signed(4), ()));
// Then, Alice should be able to send a smith cert to Dave
assert_ok!(SmithsCert::add_cert(Origin::signed(1), 1, 4));
......
......@@ -41,33 +41,33 @@ serde = { version = "1.0.101", features = ["derive"], optional = true }
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dev-dependencies]
serde = '1.0.119'
sp-io = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.23' }
sp-io = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.26' }
......@@ -70,8 +70,10 @@ pub mod pallet {
type ChangeOwnerKeyPeriod: Get<Self::BlockNumber>;
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// Management of the authorizations of the different calls. (The default implementation only allows root)
/// Management of the authorizations of the different calls.
/// The default implementation allows everything.
type EnsureIdtyCallAllowed: EnsureIdtyCallAllowed<Self>;
#[pallet::constant]
/// Minimum duration between the creation of 2 identities by the same creator
type IdtyCreationPeriod: Get<Self::BlockNumber>;
/// Custom data to store in each identity
......@@ -339,7 +341,7 @@ pub mod pallet {
if <IdentitiesNames<T>>::contains_key(&idty_name) {
return Err(Error::<T>::IdtyNameAlreadyExist.into());
}
if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index, who.clone()) {
if !T::EnsureIdtyCallAllowed::can_confirm_identity(idty_index) {
return Err(Error::<T>::NotAllowedToConfirmIdty.into());
}
......@@ -401,6 +403,7 @@ pub mod pallet {
new_key: T::AccountId,
new_key_sig: T::NewOwnerKeySignature,
) -> DispatchResultWithPostInfo {
// verification phase
let who = ensure_signed(origin)?;
let idty_index =
......@@ -413,13 +416,26 @@ pub mod pallet {
Error::<T>::OwnerKeyAlreadyUsed
);
ensure!(
T::EnsureIdtyCallAllowed::can_change_identity_address(idty_index),
Error::<T>::NotAllowedToChangeIdtyAddress
);
let block_number = frame_system::Pallet::<T>::block_number();
if let Some((_, last_change)) = idty_value.old_owner_key {
ensure!(
block_number >= last_change + T::ChangeOwnerKeyPeriod::get(),
Error::<T>::OwnerKeyAlreadyRecentlyChanged
);
}
let maybe_old_old_owner_key =
if let Some((old_owner_key, last_change)) = idty_value.old_owner_key {
ensure!(
block_number >= last_change + T::ChangeOwnerKeyPeriod::get(),
Error::<T>::OwnerKeyAlreadyRecentlyChanged
);
ensure!(
old_owner_key != new_key,
Error::<T>::ProhibitedToRevertToAnOldKey
);
Some(old_owner_key)
} else {
None
};
let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
let new_key_payload = NewOwnerKeyPayload {
......@@ -434,9 +450,15 @@ pub mod pallet {
Error::<T>::InvalidNewOwnerKeySig
);
// Apply phase
if let Some(old_old_owner_key) = maybe_old_old_owner_key {
frame_system::Pallet::<T>::dec_sufficients(&old_old_owner_key);
}
IdentityIndexOf::<T>::remove(&idty_value.owner_key);
idty_value.old_owner_key = Some((idty_value.owner_key.clone(), block_number));
idty_value.owner_key = new_key.clone();
frame_system::Pallet::<T>::inc_sufficients(&idty_value.owner_key);
IdentityIndexOf::<T>::insert(&idty_value.owner_key, idty_index);
Identities::<T>::insert(idty_index, idty_value);
Self::deposit_event(Event::IdtyChangedOwnerKey {
......@@ -481,6 +503,11 @@ pub mod pallet {
Error::<T>::InvalidRevocationKey
);
ensure!(
T::EnsureIdtyCallAllowed::can_remove_identity(idty_index),
Error::<T>::NotAllowedToRemoveIdty
);
let genesis_hash = frame_system::Pallet::<T>::block_hash(T::BlockNumber::zero());
let revocation_payload = RevocationPayload {
genesis_hash,
......@@ -526,6 +553,23 @@ pub mod pallet {
Ok(().into())
}
#[pallet::weight(1_000_000_000)]
pub fn fix_sufficients(
origin: OriginFor<T>,
owner_key: T::AccountId,
inc: bool,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
if inc {
frame_system::Pallet::<T>::inc_sufficients(&owner_key);
} else {
frame_system::Pallet::<T>::dec_sufficients(&owner_key);
}
Ok(().into())
}
}
// ERRORS //
......@@ -564,8 +608,12 @@ pub mod pallet {
InvalidRevocationKey,
/// Revocation payload signature is invalid
InvalidRevocationSig,
/// Identity not allowed to change address
NotAllowedToChangeIdtyAddress,
/// Not allowed to confirm identity
NotAllowedToConfirmIdty,
/// Not allowed to remove identity
NotAllowedToRemoveIdty,
/// Not allowed to validate identity
NotAllowedToValidateIdty,
/// Identity creation period is not respected
......@@ -576,6 +624,8 @@ pub mod pallet {
OwnerKeyAlreadyRecentlyChanged,
/// Owner key already used
OwnerKeyAlreadyUsed,
/// Prohibited to revert to an old key
ProhibitedToRevertToAnOldKey,
/// Right already added
RightAlreadyAdded,
/// Right does not exist
......@@ -600,6 +650,9 @@ pub mod pallet {
// Identity should be removed after the consumers of the identity
Identities::<T>::remove(idty_index);
frame_system::Pallet::<T>::dec_sufficients(&idty_val.owner_key);
if let Some((old_owner_key, _last_change)) = idty_val.old_owner_key {
frame_system::Pallet::<T>::dec_sufficients(&old_owner_key);
}
Self::deposit_event(Event::IdtyRemoved { idty_index });
T::OnIdtyChange::on_idty_change(
idty_index,
......
......@@ -117,6 +117,7 @@ pub fn new_test_ext(gen_conf: pallet_identity::GenesisConfig<Test>) -> sp_io::Te
frame_support::BasicExternalities::execute_with_storage(&mut t, || {
// Some dedicated test account
frame_system::Pallet::<Test>::inc_sufficients(&1);
frame_system::Pallet::<Test>::inc_providers(&2);
frame_system::Pallet::<Test>::inc_providers(&3);
});
......
......@@ -198,7 +198,7 @@ fn test_change_owner_key() {
.execute_with(|| {
let genesis_hash = System::block_hash(0);
let old_owner_key = 1u64;
let new_key_payload = NewOwnerKeyPayload {
let mut new_key_payload = NewOwnerKeyPayload {
genesis_hash: &genesis_hash,
idty_index: 1u64,
old_owner_key: &old_owner_key,
......@@ -207,7 +207,11 @@ fn test_change_owner_key() {
// We need to initialize at least one block before any call
run_to_block(1);
// Caller should have an asoociated identity
// Verify genesis data
assert_eq!(System::sufficients(&1), 1);
assert_eq!(System::sufficients(&10), 0);
// Caller should have an associated identity
assert_err!(
Identity::change_owner_key(
Origin::signed(42),
......@@ -264,10 +268,15 @@ fn test_change_owner_key() {
status: crate::IdtyStatus::Validated,
})
);
// Alice still sufficient
assert_eq!(System::sufficients(&1), 1);
// New owner key should become a sufficient account
assert_eq!(System::sufficients(&10), 1);
run_to_block(2);
// Alice can't re-change her owner key too early
new_key_payload.old_owner_key = &10;
assert_err!(
Identity::change_owner_key(
Origin::signed(10),
......@@ -279,6 +288,45 @@ fn test_change_owner_key() {
),
Error::<Test>::OwnerKeyAlreadyRecentlyChanged
);
// Alice can re-change her owner key after ChangeOwnerKeyPeriod blocs
run_to_block(2 + <Test as crate::Config>::ChangeOwnerKeyPeriod::get());
assert_ok!(Identity::change_owner_key(
Origin::signed(10),
100,
TestSignature(
100,
(NEW_OWNER_KEY_PAYLOAD_PREFIX, new_key_payload).encode()
)
));
// Old old owner key should not be sufficient anymore
assert_eq!(System::sufficients(&1), 0);
// Old owner key should still sufficient
assert_eq!(System::sufficients(&10), 1);
// New owner key should become a sufficient account
assert_eq!(System::sufficients(&100), 1);
// Revoke identity 1
assert_ok!(Identity::revoke_identity(
Origin::signed(42),
1,
100,
TestSignature(
100,
(
REVOCATION_PAYLOAD_PREFIX,
RevocationPayload {
idty_index: 1u64,
genesis_hash: System::block_hash(0),
}
)
.encode()
)
));
// Old owner key should not be sufficient anymore
assert_eq!(System::sufficients(&10), 0);
// Last owner key should not be sufficient anymore
assert_eq!(System::sufficients(&100), 0);
});
}
......@@ -327,9 +375,17 @@ fn test_idty_revocation() {
));
let events = System::events();
assert_eq!(events.len(), 1);
assert_eq!(events.len(), 2);
assert_eq!(
events[0],
EventRecord {
phase: Phase::Initialization,
event: Event::System(frame_system::Event::KilledAccount { account: 1 }),
topics: vec![],
}
);
assert_eq!(
events[1],
EventRecord {
phase: Phase::Initialization,
event: Event::Identity(crate::Event::IdtyRemoved { idty_index: 1 }),
......
......@@ -21,18 +21,33 @@ use sp_runtime::traits::Saturating;
pub trait EnsureIdtyCallAllowed<T: Config> {
fn can_create_identity(creator: T::IdtyIndex) -> bool;
fn can_confirm_identity(idty_index: T::IdtyIndex, owner_key: T::AccountId) -> bool;
fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool;
fn can_validate_identity(idty_index: T::IdtyIndex) -> bool;
fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool;
fn can_remove_identity(idty_index: T::IdtyIndex) -> bool;
}
impl<T: Config> EnsureIdtyCallAllowed<T> for () {
fn can_create_identity(_: T::IdtyIndex) -> bool {
#[impl_for_tuples(5)]
#[allow(clippy::let_and_return)]
impl<T: Config> EnsureIdtyCallAllowed<T> for Tuple {
fn can_create_identity(creator: T::IdtyIndex) -> bool {
for_tuples!( #( if !Tuple::can_create_identity(creator) { return false; } )* );
true
}
fn can_confirm_identity(idty_index: T::IdtyIndex) -> bool {
for_tuples!( #( if !Tuple::can_confirm_identity(idty_index) { return false; } )* );
true
}
fn can_validate_identity(idty_index: T::IdtyIndex) -> bool {
for_tuples!( #( if !Tuple::can_validate_identity(idty_index) { return false; } )* );
true
}
fn can_confirm_identity(_: T::IdtyIndex, _: T::AccountId) -> bool {
fn can_change_identity_address(idty_index: T::IdtyIndex) -> bool {
for_tuples!( #( if !Tuple::can_change_identity_address(idty_index) { return false; } )* );
true
}
fn can_validate_identity(_: T::IdtyIndex) -> bool {
fn can_remove_identity(idty_index: T::IdtyIndex) -> bool {
for_tuples!( #( if !Tuple::can_remove_identity(idty_index) { return false; } )* );
true
}
}
......
......@@ -41,17 +41,17 @@ version = "3.1.5"
default-features = false
git = 'https://github.com/duniter/substrate'
optional = true
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-support]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.frame-system]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.serde]
version = "1.0.101"
......@@ -61,17 +61,17 @@ features = ["derive"]
[dependencies.sp-core]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
[dependencies.sp-std]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
### DOC ###
......@@ -88,4 +88,4 @@ version = '1.0.2'
[dev-dependencies.sp-io]
default-features = false
git = 'https://github.com/duniter/substrate'
branch = 'duniter-substrate-v0.9.23'
branch = 'duniter-substrate-v0.9.26'
......@@ -72,7 +72,7 @@ pub mod pallet {
/// Something that give the IdtyId on an account id
type IdtyIdOf: Convert<Self::AccountId, Option<Self::IdtyId>>;
/// Optional metadata
type MetaData: Parameter + Validate<Self::AccountId>;
type MetaData: Default + Parameter + Validate<Self::AccountId>;
#[pallet::constant]
/// Maximum life span of a non-renewable membership (in number of blocks)
type MembershipPeriod: Get<Self::BlockNumber>;
......