Skip to content

Commit a7c759b

Browse files
authored
Merge pull request #1210 from PolymathNetwork/testnet_v4.0.1
Testnet v4.1.1
2 parents ced8e15 + 6904639 commit a7c759b

File tree

20 files changed

+251
-60
lines changed

20 files changed

+251
-60
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "polymesh"
3-
version = "4.1.0"
3+
version = "4.1.1"
44
authors = ["Polymath"]
55
build = "build.rs"
66
edition = "2018"

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ A guide to running an operator node can be found at:
7070

7171
Further details on Polymesh concepts and networks can be found at:
7272

73-
<https://developers.polymesh.live/>
73+
<https://developers.polymesh.network/>
7474

7575
Code documentation can be found at:
7676

@@ -123,7 +123,7 @@ You can start a development chain with:
123123
Detailed logs may be shown by running the node with the following environment variables set:
124124
`RUST_LOG=debug RUST_BACKTRACE=1 ./target/release/polymesh --dev`.
125125

126-
[Web Interface]: https://app.polymesh.live/#/explorer
126+
[Web Interface]: https://mainnet-app.polymesh.network/#/explorer
127127

128128
To access the Polymesh Chain using the [Web Interface] do the following:
129129

pallets/bridge/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,11 @@ decl_module! {
411411
///
412412
/// ## Errors
413413
/// - `BadAdmin` if `origin` is not `Self::admin()` account.
414-
#[weight = (500_000_000, DispatchClass::Operational, Pays::Yes)]
414+
#[weight =(
415+
500_000_000 + 7_000_000 * u64::try_from(exempted.len()).unwrap_or_default(),
416+
DispatchClass::Operational,
417+
Pays::Yes
418+
)]
415419
pub fn change_bridge_exempted(origin, exempted: Vec<(IdentityId, bool)>) -> DispatchResult {
416420
Self::base_change_bridge_exempted(origin, exempted)
417421
}

pallets/common/src/traits/compliance_manager.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515

1616
use core::result::Result;
1717
use frame_support::{dispatch::DispatchError, weights::Weight};
18-
use polymesh_primitives::{compliance_manager::AssetComplianceResult, Balance, IdentityId, Ticker};
18+
use polymesh_primitives::{
19+
compliance_manager::{AssetComplianceResult, ComplianceRequirement},
20+
condition::{conditions_total_counts, Condition},
21+
Balance, IdentityId, Ticker,
22+
};
1923

2024
pub trait Config {
2125
fn verify_restriction(
@@ -42,4 +46,33 @@ pub trait WeightInfo {
4246
fn change_compliance_requirement(s: u32, r: u32) -> Weight;
4347
fn replace_asset_compliance(c: u32) -> Weight;
4448
fn reset_asset_compliance() -> Weight;
49+
50+
fn condition_costs(conditions: u32, claims: u32, issuers: u32, claim_types: u32) -> Weight;
51+
52+
fn add_compliance_requirement_full(sender: &[Condition], receiver: &[Condition]) -> Weight {
53+
let (_, claims, issuers, claim_types) =
54+
conditions_total_counts(sender.iter().chain(receiver.iter()));
55+
Self::add_compliance_requirement(sender.len() as u32, receiver.len() as u32)
56+
.saturating_add(Self::condition_costs(0, claims, issuers, claim_types))
57+
}
58+
59+
fn change_compliance_requirement_full(req: &ComplianceRequirement) -> Weight {
60+
let (_, claims, issuers, claim_types) = req.counts();
61+
Self::change_compliance_requirement(
62+
req.sender_conditions.len() as u32,
63+
req.receiver_conditions.len() as u32,
64+
)
65+
.saturating_add(Self::condition_costs(0, claims, issuers, claim_types))
66+
}
67+
68+
fn replace_asset_compliance_full(reqs: &[ComplianceRequirement]) -> Weight {
69+
let (conditions, claims, issuers, claim_types) =
70+
conditions_total_counts(reqs.iter().flat_map(|req| req.conditions()));
71+
Self::replace_asset_compliance(reqs.len() as u32).saturating_add(Self::condition_costs(
72+
conditions,
73+
claims,
74+
issuers,
75+
claim_types,
76+
))
77+
}
4578
}

pallets/compliance-manager/src/benchmarking.rs

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,55 @@ use polymesh_common_utilities::{
2121
benchs::{AccountIdOf, User, UserBuilder},
2222
TestUtilsFn,
2323
};
24-
use polymesh_primitives::{asset::AssetType, TrustedFor, TrustedIssuer};
24+
use polymesh_primitives::{asset::AssetType, ClaimType, Scope, TrustedFor, TrustedIssuer};
25+
use sp_std::convert::TryFrom;
2526

2627
const MAX_DEFAULT_TRUSTED_CLAIM_ISSUERS: u32 = 3;
2728
const MAX_TRUSTED_ISSUER_PER_CONDITION: u32 = 3;
2829
const MAX_SENDER_CONDITIONS_PER_COMPLIANCE: u32 = 3;
2930
const MAX_RECEIVER_CONDITIONS_PER_COMPLIANCE: u32 = 3;
3031
const MAX_COMPLIANCE_REQUIREMENTS: u32 = 2;
3132

33+
const MAX_CONDITIONS: u32 = 10;
34+
const MAX_CONDITION_TYPE_CLAIMS: u32 = 10;
35+
const MAX_CONDITION_ISSUERS: u32 = 10;
36+
const MAX_CONDITION_ISSUER_CLAIM_TYPES: u32 = 10;
37+
38+
const CLAIM_TYPES: &[ClaimType] = &[
39+
ClaimType::Accredited,
40+
ClaimType::Affiliate,
41+
ClaimType::BuyLockup,
42+
ClaimType::SellLockup,
43+
ClaimType::CustomerDueDiligence,
44+
ClaimType::KnowYourCustomer,
45+
ClaimType::Jurisdiction,
46+
ClaimType::Exempted,
47+
ClaimType::Blocked,
48+
ClaimType::InvestorUniqueness,
49+
ClaimType::NoType,
50+
ClaimType::InvestorUniquenessV2,
51+
];
52+
3253
/// Create a token issuer trusted for `Any`.
33-
pub fn make_issuer<T: IdentityConfig + TestUtilsFn<AccountIdOf<T>>>(id: u32) -> TrustedIssuer {
54+
pub fn make_issuer<T: IdentityConfig + TestUtilsFn<AccountIdOf<T>>>(
55+
id: u32,
56+
claim_type_len: Option<usize>,
57+
) -> TrustedIssuer {
3458
let u = UserBuilder::<T>::default()
3559
.generate_did()
3660
.seed(id)
3761
.build("ISSUER");
3862
TrustedIssuer {
3963
issuer: IdentityId::from(u.did.unwrap()),
40-
trusted_for: TrustedFor::Any,
64+
trusted_for: match claim_type_len {
65+
None => TrustedFor::Any,
66+
Some(len) => TrustedFor::Specific(
67+
(0..len)
68+
.into_iter()
69+
.map(|idx| CLAIM_TYPES[idx % CLAIM_TYPES.len()])
70+
.collect(),
71+
),
72+
},
4173
}
4274
}
4375

@@ -46,16 +78,29 @@ pub fn make_issuer<T: IdentityConfig + TestUtilsFn<AccountIdOf<T>>>(id: u32) ->
4678
/// - It could have more complexity if `TrustedIssuer::trusted_for` is a vector but not on
4779
/// benchmarking of add/remove. That could be useful for benchmarking executions/evaluation of
4880
/// complience requiriments.
49-
pub fn make_issuers<T: IdentityConfig + TestUtilsFn<AccountIdOf<T>>>(s: u32) -> Vec<TrustedIssuer> {
50-
(0..s).map(|i| make_issuer::<T>(i)).collect::<Vec<_>>()
81+
pub fn make_issuers<T: IdentityConfig + TestUtilsFn<AccountIdOf<T>>>(
82+
s: u32,
83+
claim_type_len: Option<usize>,
84+
) -> Vec<TrustedIssuer> {
85+
(0..s)
86+
.map(|i| make_issuer::<T>(i, claim_type_len))
87+
.collect()
5188
}
5289

5390
/// Create simple conditions with a variable number of `issuers`.
54-
pub fn make_conditions(s: u32, issuers: &Vec<TrustedIssuer>) -> Vec<Condition> {
91+
pub fn make_conditions(s: u32, claims: Option<usize>, issuers: &[TrustedIssuer]) -> Vec<Condition> {
5592
(0..s)
5693
.map(|_| Condition {
57-
condition_type: ConditionType::IsPresent(Claim::NoData),
58-
issuers: issuers.clone(),
94+
condition_type: match claims {
95+
None => ConditionType::IsPresent(Claim::NoData),
96+
Some(len) => ConditionType::IsAnyOf(
97+
(0..len)
98+
.into_iter()
99+
.map(|_| Claim::Blocked(Scope::Custom(vec![0])))
100+
.collect(),
101+
),
102+
},
103+
issuers: issuers.to_vec(),
59104
})
60105
.collect()
61106
}
@@ -103,7 +148,7 @@ struct ComplianceRequirementInfo<T: Config> {
103148

104149
impl<T: Config + TestUtilsFn<AccountIdOf<T>>> ComplianceRequirementInfo<T> {
105150
pub fn add_default_trusted_claim_issuer(self: &Self, i: u32) {
106-
make_issuers::<T>(i).into_iter().for_each(|issuer| {
151+
make_issuers::<T>(i, None).into_iter().for_each(|issuer| {
107152
Module::<T>::add_default_trusted_claim_issuer(
108153
self.owner.origin.clone().into(),
109154
self.ticker.clone(),
@@ -130,9 +175,9 @@ impl<T: Config + TestUtilsFn<AccountIdOf<T>>> ComplianceRequirementBuilder<T> {
130175
let ticker = make_token::<T>(&owner, b"1".to_vec());
131176

132177
// Create issuers (i) and conditions(s & r).
133-
let issuers = make_issuers::<T>(trusted_issuer_count);
134-
let sender_conditions = make_conditions(sender_conditions_count, &issuers);
135-
let receiver_conditions = make_conditions(receiver_conditions_count, &issuers);
178+
let issuers = make_issuers::<T>(trusted_issuer_count, None);
179+
let sender_conditions = make_conditions(sender_conditions_count, None, &issuers);
180+
let receiver_conditions = make_conditions(receiver_conditions_count, None, &issuers);
136181

137182
let info = ComplianceRequirementInfo {
138183
owner,
@@ -168,9 +213,40 @@ impl<T: Config> ComplianceRequirementBuilder<T> {
168213
}
169214
}
170215

216+
fn setup_conditions_bench<T: Config + TestUtilsFn<AccountIdOf<T>>>(
217+
conditions: u32,
218+
claims: u32,
219+
issuers: u32,
220+
claim_types: u32,
221+
) -> Vec<Condition> {
222+
let issuers = make_issuers::<T>(issuers, Some(claim_types as usize));
223+
let conditions = make_conditions(conditions, Some(claims as usize), &issuers);
224+
conditions
225+
}
226+
227+
fn conditions_bench(conditions: Vec<Condition>) {
228+
let encoded = conditions.encode();
229+
let decoded = Vec::<Condition>::decode(&mut encoded.as_slice())
230+
.expect("This shouldn't fail since we just encoded a `Vec<Condition>` value.");
231+
if !conditions.eq(&decoded) {
232+
panic!("This shouldn't fail.");
233+
}
234+
}
235+
171236
benchmarks! {
172237
where_clause { where T: TestUtilsFn<AccountIdOf<T>> }
173238

239+
condition_costs {
240+
let a in 1..MAX_CONDITIONS;
241+
let b in 1..MAX_CONDITION_TYPE_CLAIMS;
242+
let c in 1..MAX_CONDITION_ISSUERS;
243+
let d in 1..MAX_CONDITION_ISSUER_CLAIM_TYPES;
244+
245+
let conditions = setup_conditions_bench::<T>(a, b, c, d);
246+
}: {
247+
conditions_bench(conditions);
248+
}
249+
174250
add_compliance_requirement {
175251
// INTERNAL: This benchmark only evaluate the adding operation. Its execution should be measured in another module.
176252
let s in 1..MAX_SENDER_CONDITIONS_PER_COMPLIANCE;
@@ -237,7 +313,7 @@ benchmarks! {
237313
d.add_default_trusted_claim_issuer(MAX_DEFAULT_TRUSTED_CLAIM_ISSUERS -1);
238314

239315
// Add one more for benchmarking.
240-
let new_issuer = make_issuer::<T>(MAX_DEFAULT_TRUSTED_CLAIM_ISSUERS);
316+
let new_issuer = make_issuer::<T>(MAX_DEFAULT_TRUSTED_CLAIM_ISSUERS, None);
241317
}: _(d.owner.origin, d.ticker, new_issuer.clone())
242318
verify {
243319
let trusted_issuers = Module::<T>::trusted_claim_issuer(d.ticker);
@@ -300,9 +376,9 @@ benchmarks! {
300376
MAX_RECEIVER_CONDITIONS_PER_COMPLIANCE)
301377
.add_compliance_requirement().build();
302378

303-
let issuers = make_issuers::<T>(MAX_TRUSTED_ISSUER_PER_CONDITION);
304-
let sender_conditions = make_conditions(MAX_SENDER_CONDITIONS_PER_COMPLIANCE, &issuers);
305-
let receiver_conditions = make_conditions(MAX_RECEIVER_CONDITIONS_PER_COMPLIANCE, &issuers);
379+
let issuers = make_issuers::<T>(MAX_TRUSTED_ISSUER_PER_CONDITION, None);
380+
let sender_conditions = make_conditions(MAX_SENDER_CONDITIONS_PER_COMPLIANCE, None, &issuers);
381+
let receiver_conditions = make_conditions(MAX_RECEIVER_CONDITIONS_PER_COMPLIANCE, None, &issuers);
306382

307383
// Add more requirements to the asset, if `c > 1`.
308384
(1..c).for_each( |_i| {

pallets/compliance-manager/src/lib.rs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,7 @@ use polymesh_primitives::{
103103
proposition, storage_migration_ver, Balance, Claim, Condition, ConditionType, Context,
104104
IdentityId, Ticker, TrustedFor, TrustedIssuer,
105105
};
106-
use sp_std::{
107-
convert::{From, TryFrom},
108-
prelude::*,
109-
};
106+
use sp_std::{convert::From, prelude::*};
110107

111108
type ExternalAgents<T> = pallet_external_agents::Module<T>;
112109
type Identity<T> = pallet_identity::Module<T>;
@@ -190,7 +187,7 @@ decl_module! {
190187
///
191188
/// # Permissions
192189
/// * Asset
193-
#[weight = <T as Config>::WeightInfo::add_compliance_requirement(sender_conditions.len() as u32, receiver_conditions.len() as u32)]
190+
#[weight = <T as Config>::WeightInfo::add_compliance_requirement_full(&sender_conditions, &receiver_conditions)]
194191
pub fn add_compliance_requirement(origin, ticker: Ticker, sender_conditions: Vec<Condition>, receiver_conditions: Vec<Condition>) {
195192
let did = <ExternalAgents<T>>::ensure_perms(origin, ticker)?;
196193

@@ -257,7 +254,7 @@ decl_module! {
257254
///
258255
/// # Permissions
259256
/// * Asset
260-
#[weight = <T as Config>::WeightInfo::replace_asset_compliance(asset_compliance.len() as u32)]
257+
#[weight = <T as Config>::WeightInfo::replace_asset_compliance_full(&asset_compliance)]
261258
pub fn replace_asset_compliance(origin, ticker: Ticker, asset_compliance: Vec<ComplianceRequirement>) {
262259
let did = <ExternalAgents<T>>::ensure_perms(origin, ticker)?;
263260

@@ -392,10 +389,7 @@ decl_module! {
392389
///
393390
/// # Permissions
394391
/// * Asset
395-
#[weight = <T as Config>::WeightInfo::change_compliance_requirement(
396-
new_req.sender_conditions.len() as u32,
397-
new_req.receiver_conditions.len() as u32,
398-
)]
392+
#[weight = <T as Config>::WeightInfo::change_compliance_requirement_full(&new_req)]
399393
pub fn change_compliance_requirement(origin, ticker: Ticker, new_req: ComplianceRequirement) {
400394
let did = <ExternalAgents<T>>::ensure_perms(origin, ticker)?;
401395

@@ -601,17 +595,15 @@ impl<T: Config> Module<T> {
601595
let complexity = asset_compliance
602596
.iter()
603597
.flat_map(|req| req.conditions())
604-
.fold(0usize, |complexity, condition| {
605-
let (claims, issuers) = condition.complexity();
606-
complexity.saturating_add(claims.saturating_mul(match issuers {
607-
0 => default_issuer_count,
608-
_ => issuers,
609-
}))
610-
});
611-
if let Ok(complexity_u32) = u32::try_from(complexity) {
612-
if complexity_u32 <= T::MaxConditionComplexity::get() {
613-
return Ok(());
614-
}
598+
.fold(0u32, |total, condition| {
599+
let complexity = condition.complexity(default_issuer_count);
600+
total.saturating_add(complexity)
601+
})
602+
// NB: If the compliance requirements are empty (0 complexity),
603+
// then use the count of requirements.
604+
.max(asset_compliance.len() as u32);
605+
if complexity <= T::MaxConditionComplexity::get() {
606+
return Ok(());
615607
}
616608
Err(Error::<T>::ComplianceRequirementTooComplex.into())
617609
}

pallets/relayer/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ decl_module! {
125125
/// - `AuthorizationError::Expired` if `auth_id` the authorization has expired.
126126
/// - `AuthorizationError::BadType` if `auth_id` was not a `AddRelayerPayingKey` authorization.
127127
/// - `NotAuthorizedForUserKey` if `origin` is not authorized to accept the authorization for the `user_key`.
128-
/// - `NotAuthorizedForPayingKey` if the authorization was created by a signer that isn't authorized by the `paying_key`.
128+
/// - `NotAuthorizedForPayingKey` if the authorization was created an identity different from the `paying_key`'s identity.
129129
/// - `UserKeyCddMissing` if the `user_key` is not attached to a CDD'd identity.
130130
/// - `PayingKeyCddMissing` if the `paying_key` is not attached to a CDD'd identity.
131131
/// - `UnauthorizedCaller` if `origin` is not authorized to call this extrinsic.
@@ -236,15 +236,18 @@ impl<T: Config> Module<T> {
236236
}
237237

238238
fn base_accept_paying_key(origin: T::Origin, auth_id: u64) -> DispatchResult {
239-
let user_key = ensure_signed(origin)?;
239+
let caller_key = ensure_signed(origin)?;
240240
let user_did =
241-
<Identity<T>>::get_identity(&user_key).ok_or(Error::<T>::UserKeyCddMissing)?;
242-
let signer = Signatory::Account(user_key);
241+
<Identity<T>>::get_identity(&caller_key).ok_or(Error::<T>::UserKeyCddMissing)?;
242+
let signer = Signatory::Account(caller_key.clone());
243243

244244
<Identity<T>>::accept_auth_with(&signer, auth_id, |data, auth_by| -> DispatchResult {
245245
let (user_key, paying_key, polyx_limit) =
246246
extract_auth!(data, AddRelayerPayingKey(user_key, paying_key, polyx_limit));
247247

248+
// Allow: `origin == user_key`.
249+
ensure!(user_key == caller_key, Error::<T>::NotAuthorizedForUserKey);
250+
248251
Self::auth_accept_paying_key(
249252
user_did,
250253
auth_by,

pallets/runtime/ci/src/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
6161
// and set impl_version to 0. If only runtime
6262
// implementation changes and behavior does not, then leave spec_version as
6363
// is and increment impl_version.
64-
spec_version: 3002,
64+
spec_version: 3010,
6565
impl_version: 0,
6666
apis: RUNTIME_API_VERSIONS,
6767
transaction_version: 2,

pallets/runtime/develop/src/runtime.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
5959
// and set impl_version to 0. If only runtime
6060
// implementation changes and behavior does not, then leave spec_version as
6161
// is and increment impl_version.
62-
spec_version: 3002,
62+
spec_version: 3010,
6363
impl_version: 0,
6464
apis: RUNTIME_API_VERSIONS,
6565
transaction_version: 2,

0 commit comments

Comments
 (0)