Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
polkadot-sdk
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
parity
Mirrored projects
polkadot-sdk
Commits
f14d98a4
Commit
f14d98a4
authored
5 years ago
by
Gavin Wood
Committed by
GitHub
5 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Identity module enhancements (#4401)
* Updates; not yet tested. * Fix and add tests * Add test * Update a few comments
parent
83711ca2
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
substrate/frame/identity/src/lib.rs
+120
-16
120 additions, 16 deletions
substrate/frame/identity/src/lib.rs
with
120 additions
and
16 deletions
substrate/frame/identity/src/lib.rs
+
120
−
16
View file @
f14d98a4
...
...
@@ -93,10 +93,12 @@ pub trait Trait: system::Trait {
/// The amount held on deposit per additional field for a registered identity.
type
FieldDeposit
:
Get
<
BalanceOf
<
Self
>>
;
/// The amount held on deposit for a registered subaccount.
/// The amount held on deposit for a registered subaccount. This should account for the fact
/// that one storage item's value will increase by the size of an account ID, and there will be
/// another trie item whose value is the size of an account ID plus 32 bytes.
type
SubAccountDeposit
:
Get
<
BalanceOf
<
Self
>>
;
/// The
amount held on deposit for a registered sub
account.
/// The
maximum number of sub-accounts allowed per identified
account.
type
MaximumSubAccounts
:
Get
<
u32
>
;
/// What to do with slashed funds.
...
...
@@ -363,11 +365,14 @@ decl_storage! {
/// Information that is pertinent to identify the entity behind an account.
pub
IdentityOf
get
(
fn
identity
):
map
T
::
AccountId
=>
Option
<
Registration
<
BalanceOf
<
T
>>>
;
/// The super-identity of an alternative "sub" identity together with its name, within that
/// context. If the account is not some other account's sub-identity, then just `None`.
pub
SuperOf
get
(
fn
super_of
):
map
T
::
AccountId
=>
Option
<
(
T
::
AccountId
,
Data
)
>
;
/// Alternative "sub" identities of this account.
///
/// The first item is the deposit, the second is a vector of the accounts together with
/// their "local" name (i.e. in the context of the identity).
pub
SubsOf
get
(
fn
subs
):
map
T
::
AccountId
=>
(
BalanceOf
<
T
>
,
Vec
<
(
T
::
AccountId
,
Data
)
>
);
/// The first item is the deposit, the second is a vector of the accounts.
pub
SubsOf
get
(
fn
subs
):
map
T
::
AccountId
=>
(
BalanceOf
<
T
>
,
Vec
<
T
::
AccountId
>
);
/// The set of registrars. Not expected to get very big as can only be added through a
/// special origin (likely a council motion).
...
...
@@ -488,14 +493,15 @@ decl_module! {
/// # <weight>
/// - `O(S)` where `S` subs-count (hard- and deposit-bounded).
/// - At most two balance operations.
/// - One storage mutation (codec `O(S)`); one storage-exists.
/// - At most O(2 * S + 1) storage mutations; codec complexity `O(1 * S + S * 1)`);
/// one storage-exists.
/// # </weight>
fn
set_subs
(
origin
,
subs
:
Vec
<
(
T
::
AccountId
,
Data
)
>
)
{
let
sender
=
ensure_signed
(
origin
)
?
;
ensure!
(
<
IdentityOf
<
T
>>
::
exists
(
&
sender
),
"not found"
);
ensure!
(
subs
.len
()
<=
T
::
MaximumSubAccounts
::
get
()
as
usize
,
"too many subs"
);
let
old_deposit
=
<
SubsOf
<
T
>>
::
get
(
&
sender
)
.0
;
let
(
old_deposit
,
old_ids
)
=
<
SubsOf
<
T
>>
::
get
(
&
sender
);
let
new_deposit
=
T
::
SubAccountDeposit
::
get
()
*
<
BalanceOf
<
T
>>
::
from
(
subs
.len
()
as
u32
);
if
old_deposit
<
new_deposit
{
...
...
@@ -506,10 +512,18 @@ decl_module! {
let
_
=
T
::
Currency
::
unreserve
(
&
sender
,
old_deposit
-
new_deposit
);
}
if
subs
.is_empty
()
{
for
s
in
old_ids
.iter
()
{
<
SuperOf
<
T
>>
::
remove
(
s
);
}
let
ids
=
subs
.into_iter
()
.map
(|(
id
,
name
)|
{
<
SuperOf
<
T
>>
::
insert
(
&
id
,
(
sender
.clone
(),
name
));
id
})
.collect
::
<
Vec
<
_
>>
();
if
ids
.is_empty
()
{
<
SubsOf
<
T
>>
::
remove
(
&
sender
);
}
else
{
<
SubsOf
<
T
>>
::
insert
(
&
sender
,
(
new_deposit
,
sub
s
));
<
SubsOf
<
T
>>
::
insert
(
&
sender
,
(
new_deposit
,
id
s
));
}
}
...
...
@@ -525,14 +539,18 @@ decl_module! {
/// # <weight>
/// - `O(R + S + X)`.
/// - One balance-reserve operation.
/// -
Two
storage
muta
tions.
/// -
`S + 2`
storage
dele
tions.
/// - One event.
/// # </weight>
fn
clear_identity
(
origin
)
{
let
sender
=
ensure_signed
(
origin
)
?
;
let
(
subs_deposit
,
sub_ids
)
=
<
SubsOf
<
T
>>
::
take
(
&
sender
);
let
deposit
=
<
IdentityOf
<
T
>>
::
take
(
&
sender
)
.ok_or
(
"not named"
)
?
.total_deposit
()
+
<
SubsOf
<
T
>>
::
take
(
&
sender
)
.0
;
+
subs_deposit
;
for
sub
in
sub_ids
.iter
()
{
<
SuperOf
<
T
>>
::
remove
(
sub
);
}
let
_
=
T
::
Currency
::
unreserve
(
&
sender
,
deposit
.clone
());
...
...
@@ -654,6 +672,33 @@ decl_module! {
)
}
/// Change the account associated with a registrar.
///
/// The dispatch origin for this call must be _Signed_ and the sender must be the account
/// of the registrar whose index is `index`.
///
/// - `index`: the index of the registrar whose fee is to be set.
/// - `new`: the new account ID.
///
/// # <weight>
/// - `O(R)`.
/// - One storage mutation `O(R)`.
/// # </weight>
#[weight
=
SimpleDispatchInfo::FixedNormal(
50_000
)]
fn
set_account_id
(
origin
,
#[compact]
index
:
RegistrarIndex
,
new
:
T
::
AccountId
,
)
->
Result
{
let
who
=
ensure_signed
(
origin
)
?
;
<
Registrars
<
T
>>
::
mutate
(|
rs
|
rs
.get_mut
(
index
as
usize
)
.and_then
(|
x
|
x
.as_mut
())
.and_then
(|
r
|
if
r
.account
==
who
{
r
.account
=
new
;
Some
(())
}
else
{
None
})
.ok_or
(
"invalid index"
)
)
}
/// Set the field information for a registrar.
///
/// The dispatch origin for this call must be _Signed_ and the sender must be the account
...
...
@@ -746,7 +791,7 @@ decl_module! {
/// # <weight>
/// - `O(R + S + X)`.
/// - One balance-reserve operation.
/// -
Two
storage mutations.
/// -
`S + 2`
storage mutations.
/// - One event.
/// # </weight>
#[weight
=
SimpleDispatchInfo::FreeOperational]
...
...
@@ -759,8 +804,12 @@ decl_module! {
// Figure out who we're meant to be clearing.
let
target
=
T
::
Lookup
::
lookup
(
target
)
?
;
// Grab their deposit (and check that they have one).
let
(
subs_deposit
,
sub_ids
)
=
<
SubsOf
<
T
>>
::
take
(
&
target
);
let
deposit
=
<
IdentityOf
<
T
>>
::
take
(
&
target
)
.ok_or
(
"not named"
)
?
.total_deposit
()
+
<
SubsOf
<
T
>>
::
take
(
&
target
)
.0
;
+
subs_deposit
;
for
sub
in
sub_ids
.iter
()
{
<
SuperOf
<
T
>>
::
remove
(
sub
);
}
// Slash their deposit from them.
T
::
Slashed
::
on_unbalanced
(
T
::
Currency
::
slash_reserved
(
&
target
,
deposit
)
.0
);
...
...
@@ -967,18 +1016,60 @@ mod tests {
assert_ok!
(
Identity
::
set_identity
(
Origin
::
signed
(
10
),
ten
()));
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
subs
.clone
()));
assert_eq!
(
Balances
::
free_balance
(
10
),
80
);
assert_eq!
(
Identity
::
subs
(
10
),
(
10
,
subs
.clone
()));
assert_eq!
(
Identity
::
subs
(
10
),
(
10
,
vec!
[
20
]));
assert_eq!
(
Identity
::
super_of
(
20
),
Some
((
10
,
Data
::
Raw
(
vec!
[
40
;
1
]))));
// push another item and re-set it.
subs
.push
((
30
,
Data
::
Raw
(
vec!
[
50
;
1
])));
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
subs
.clone
()));
assert_eq!
(
Balances
::
free_balance
(
10
),
70
);
assert_eq!
(
Identity
::
subs
(
10
),
(
20
,
vec!
[
20
,
30
]));
assert_eq!
(
Identity
::
super_of
(
20
),
Some
((
10
,
Data
::
Raw
(
vec!
[
40
;
1
]))));
assert_eq!
(
Identity
::
super_of
(
30
),
Some
((
10
,
Data
::
Raw
(
vec!
[
50
;
1
]))));
// switch out one of the items and re-set.
subs
[
0
]
=
(
40
,
Data
::
Raw
(
vec!
[
60
;
1
]));
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
subs
.clone
()));
assert_eq!
(
Balances
::
free_balance
(
10
),
70
);
// no change in the balance
assert_eq!
(
Identity
::
subs
(
10
),
(
20
,
vec!
[
40
,
30
]));
assert_eq!
(
Identity
::
super_of
(
20
),
None
);
assert_eq!
(
Identity
::
super_of
(
30
),
Some
((
10
,
Data
::
Raw
(
vec!
[
50
;
1
]))));
assert_eq!
(
Identity
::
super_of
(
40
),
Some
((
10
,
Data
::
Raw
(
vec!
[
60
;
1
]))));
// clear
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
vec!
[]));
assert_eq!
(
Balances
::
free_balance
(
10
),
90
);
assert_eq!
(
Identity
::
subs
(
10
),
(
0
,
vec!
[]));
assert_eq!
(
Identity
::
super_of
(
30
),
None
);
assert_eq!
(
Identity
::
super_of
(
40
),
None
);
subs
.push
((
30
,
Data
::
Raw
(
vec!
[
41
;
1
])));
subs
.push
((
40
,
Data
::
Raw
(
vec!
[
42
;
1
])));
subs
.push
((
20
,
Data
::
Raw
(
vec!
[
40
;
1
])));
assert_noop!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
subs
.clone
()),
"too many subs"
);
});
}
#[test]
fn
clearing_account_should_remove_subaccounts_and_refund
()
{
new_test_ext
()
.execute_with
(||
{
assert_ok!
(
Identity
::
set_identity
(
Origin
::
signed
(
10
),
ten
()));
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
vec!
[(
20
,
Data
::
Raw
(
vec!
[
40
;
1
]))]));
assert_ok!
(
Identity
::
clear_identity
(
Origin
::
signed
(
10
)));
assert_eq!
(
Balances
::
free_balance
(
10
),
100
);
assert!
(
Identity
::
super_of
(
20
)
.is_none
());
});
}
#[test]
fn
killing_account_should_remove_subaccounts_and_not_refund
()
{
new_test_ext
()
.execute_with
(||
{
assert_ok!
(
Identity
::
set_identity
(
Origin
::
signed
(
10
),
ten
()));
assert_ok!
(
Identity
::
set_subs
(
Origin
::
signed
(
10
),
vec!
[(
20
,
Data
::
Raw
(
vec!
[
40
;
1
]))]));
assert_ok!
(
Identity
::
kill_identity
(
Origin
::
ROOT
,
10
));
assert_eq!
(
Balances
::
free_balance
(
10
),
80
);
assert!
(
Identity
::
super_of
(
20
)
.is_none
());
});
}
#[test]
fn
cancelling_requested_judgement_should_work
()
{
new_test_ext
()
.execute_with
(||
{
...
...
@@ -1040,4 +1131,17 @@ mod tests {
assert_eq!
(
Balances
::
free_balance
(
10
),
70
);
});
}
#[test]
fn
setting_account_id_should_work
()
{
new_test_ext
()
.execute_with
(||
{
assert_ok!
(
Identity
::
add_registrar
(
Origin
::
signed
(
1
),
3
));
// account 4 cannot change the first registrar's identity since it's owned by 3.
assert_noop!
(
Identity
::
set_account_id
(
Origin
::
signed
(
4
),
0
,
3
),
"invalid index"
);
// account 3 can, because that's the registrar's current account.
assert_ok!
(
Identity
::
set_account_id
(
Origin
::
signed
(
3
),
0
,
4
));
// account 4 can now, because that's their new ID.
assert_ok!
(
Identity
::
set_account_id
(
Origin
::
signed
(
4
),
0
,
3
));
});
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment