Admin facility to move claims with council permission. (#1198)

This commit is contained in:
Gavin Wood
2020-06-09 11:09:17 +02:00
committed by GitHub
parent bb0e37f23a
commit 3e5e67855b
4 changed files with 66 additions and 3 deletions
+62 -3
View File
@@ -19,8 +19,8 @@
use sp_std::{prelude::*, fmt::Debug}; use sp_std::{prelude::*, fmt::Debug};
use sp_io::{hashing::keccak_256, crypto::secp256k1_ecdsa_recover}; use sp_io::{hashing::keccak_256, crypto::secp256k1_ecdsa_recover};
use frame_support::{ use frame_support::{
decl_event, decl_storage, decl_module, decl_error, ensure, decl_event, decl_storage, decl_module, decl_error, ensure, dispatch::IsSubType,
traits::{Currency, Get, VestingSchedule}, weights::{Pays, DispatchClass}, dispatch::IsSubType traits::{Currency, Get, VestingSchedule, EnsureOrigin}, weights::{Pays, DispatchClass}
}; };
use system::{ensure_signed, ensure_root, ensure_none}; use system::{ensure_signed, ensure_root, ensure_none};
use codec::{Encode, Decode}; use codec::{Encode, Decode};
@@ -46,6 +46,7 @@ pub trait Trait: system::Trait {
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>; type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
type VestingSchedule: VestingSchedule<Self::AccountId, Moment=Self::BlockNumber>; type VestingSchedule: VestingSchedule<Self::AccountId, Moment=Self::BlockNumber>;
type Prefix: Get<&'static [u8]>; type Prefix: Get<&'static [u8]>;
type MoveClaimOrigin: EnsureOrigin<Self::Origin>;
} }
/// The kind of a statement an account needs to make for a claim to be valid. /// The kind of a statement an account needs to make for a claim to be valid.
@@ -391,6 +392,26 @@ decl_module! {
Self::process_claim(signer, who.clone())?; Self::process_claim(signer, who.clone())?;
Preclaims::<T>::remove(&who); Preclaims::<T>::remove(&who);
} }
#[weight = (
T::DbWeight::get().reads_writes(4, 4) + 100_000_000_000,
DispatchClass::Normal,
Pays::No
)]
fn move_claim(origin,
old: EthereumAddress,
new: EthereumAddress,
maybe_preclaim: Option<T::AccountId>,
) {
T::MoveClaimOrigin::try_origin(origin).map(|_| ()).or_else(ensure_root)?;
Claims::<T>::take(&old).map(|c| Claims::<T>::insert(&new, c));
Vesting::<T>::take(&old).map(|c| Vesting::<T>::insert(&new, c));
Signing::take(&old).map(|c| Signing::insert(&new, c));
maybe_preclaim.map(|preclaim| Preclaims::<T>::mutate(&preclaim, |maybe_o|
if maybe_o.as_ref().map_or(false, |o| o == &old) { *maybe_o = Some(new) }
));
}
} }
} }
@@ -618,7 +639,8 @@ mod tests {
use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, Identity}, testing::Header}; use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup, Identity}, testing::Header};
use frame_support::{ use frame_support::{
impl_outer_origin, impl_outer_dispatch, assert_ok, assert_err, assert_noop, parameter_types, impl_outer_origin, impl_outer_dispatch, assert_ok, assert_err, assert_noop, parameter_types,
weights::{Pays, GetDispatchInfo}, traits::ExistenceRequirement, ord_parameter_types, weights::{Pays, GetDispatchInfo}, traits::ExistenceRequirement,
dispatch::DispatchError::BadOrigin,
}; };
use balances; use balances;
use super::Call as ClaimsCall; use super::Call as ClaimsCall;
@@ -693,11 +715,15 @@ mod tests {
parameter_types!{ parameter_types!{
pub Prefix: &'static [u8] = b"Pay RUSTs to the TEST account:"; pub Prefix: &'static [u8] = b"Pay RUSTs to the TEST account:";
} }
ord_parameter_types! {
pub const Six: u64 = 6;
}
impl Trait for Test { impl Trait for Test {
type Event = (); type Event = ();
type VestingSchedule = Vesting; type VestingSchedule = Vesting;
type Prefix = Prefix; type Prefix = Prefix;
type MoveClaimOrigin = system::EnsureSignedBy<Six, u64>;
} }
type System = system::Module<Test>; type System = system::Module<Test>;
type Balances = balances::Module<Test>; type Balances = balances::Module<Test>;
@@ -775,6 +801,39 @@ mod tests {
}); });
} }
#[test]
fn basic_claim_moving_works() {
new_test_ext().execute_with(|| {
assert_eq!(Balances::free_balance(42), 0);
assert_noop!(Claims::move_claim(Origin::signed(1), eth(&alice()), eth(&bob()), None), BadOrigin);
assert_ok!(Claims::move_claim(Origin::signed(6), eth(&alice()), eth(&bob()), None));
assert_noop!(Claims::claim(Origin::NONE, 42, sig::<Test>(&alice(), &42u64.encode(), &[][..])), Error::<Test>::SignerHasNoClaim);
assert_ok!(Claims::claim(Origin::NONE, 42, sig::<Test>(&bob(), &42u64.encode(), &[][..])));
assert_eq!(Balances::free_balance(&42), 100);
assert_eq!(Vesting::vesting_balance(&42), Some(50));
assert_eq!(Claims::total(), total_claims() - 100);
});
}
#[test]
fn claim_attest_moving_works() {
new_test_ext().execute_with(|| {
assert_ok!(Claims::move_claim(Origin::signed(6), eth(&dave()), eth(&bob()), None));
let s = sig::<Test>(&bob(), &42u64.encode(), StatementKind::Regular.to_text());
assert_ok!(Claims::claim_attest(Origin::NONE, 42, s, StatementKind::Regular.to_text().to_vec()));
assert_eq!(Balances::free_balance(&42), 200);
});
}
#[test]
fn attest_moving_works() {
new_test_ext().execute_with(|| {
assert_ok!(Claims::move_claim(Origin::signed(6), eth(&eve()), eth(&bob()), Some(42)));
assert_ok!(Claims::attest(Origin::signed(42), StatementKind::Saft.to_text().to_vec()));
assert_eq!(Balances::free_balance(&42), 300);
});
}
#[test] #[test]
fn claiming_does_not_bypass_signing() { fn claiming_does_not_bypass_signing() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
+1
View File
@@ -664,6 +664,7 @@ impl claims::Trait for Runtime {
type Event = Event; type Event = Event;
type VestingSchedule = Vesting; type VestingSchedule = Vesting;
type Prefix = Prefix; type Prefix = Prefix;
type MoveClaimOrigin = collective::EnsureProportionMoreThan<_1, _2, AccountId, CouncilCollective>;
} }
parameter_types! { parameter_types! {
+2
View File
@@ -709,6 +709,8 @@ impl claims::Trait for Runtime {
type Event = Event; type Event = Event;
type VestingSchedule = Vesting; type VestingSchedule = Vesting;
type Prefix = Prefix; type Prefix = Prefix;
/// At least 3/4 of the council must agree to a claim move before it can happen.
type MoveClaimOrigin = collective::EnsureProportionAtLeast<_3, _4, AccountId, CouncilCollective>;
} }
parameter_types! { parameter_types! {
+1
View File
@@ -473,6 +473,7 @@ impl claims::Trait for Runtime {
type Event = Event; type Event = Event;
type VestingSchedule = Vesting; type VestingSchedule = Vesting;
type Prefix = Prefix; type Prefix = Prefix;
type MoveClaimOrigin = system::EnsureRoot<AccountId>;
} }
parameter_types! { parameter_types! {