diff --git a/.vscode/launch.json b/.vscode/launch.json index aed710a..c7e9403 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,8 +11,8 @@ "cargo": { "args": [ "build", - "--bin=mathchain", - "--package=mathchain" + // "--bin=mathchain", + // "--package=mathchain" ], "filter": { "name": "mathchain", diff --git a/Cargo.lock b/Cargo.lock index 65e75e7..9e6895d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5447,9 +5447,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" dependencies = [ "aho-corasick", "memchr", diff --git a/pallets/account-service/src/lib.rs b/pallets/account-service/src/lib.rs index 438a7ed..9673c6c 100644 --- a/pallets/account-service/src/lib.rs +++ b/pallets/account-service/src/lib.rs @@ -42,6 +42,7 @@ use frame_support::{ traits::{EnsureOrigin, Get}, }; use frame_system::{ensure_signed, ensure_root}; +use core::primitive::str; use codec::{Encode, Decode, Codec}; @@ -65,7 +66,8 @@ pub struct MultiAddressDetails< Info: Codec, > { nickname: Info, - ethereum: Info + ethereum: Info, + twitter: Info, } #[derive(Encode, Decode, PartialEq, Eq, Clone, Debug)] @@ -74,6 +76,8 @@ pub enum AccountServiceEnum { Nickname(Vec), /// Its a 20 byte representation. Ethereum([u8; 20]), + /// It's a twitter nickname. + Twitter(Vec), } decl_storage! { @@ -83,6 +87,7 @@ decl_storage! { >>; FromNickname get(fn from_nick_name): map hasher(blake2_128_concat) AccountServiceEnum => ::AccountId; FromEthereum get(fn from_ethereum): map hasher(blake2_128_concat) AccountServiceEnum => ::AccountId; + FromTwitter get(fn from_twitter): map hasher(blake2_128_concat) AccountServiceEnum => ::AccountId; AccountRoot get(fn account_root) config(): ::AccountId; } } @@ -113,6 +118,8 @@ decl_error! { AlreadyTaked, /// Not allow to bind NotAllowed, + /// WrongFormat + WrongFormat, } } @@ -148,32 +155,29 @@ decl_module! { #[weight = 50_000_000] fn bind(origin, account_service: AccountServiceEnum) { let sender = ensure_signed(origin)?; + ensure!(false, Error::::NotAllowed); + // Don't allow any one bind for there self now. let info = account_service.clone(); - match info { - AccountServiceEnum::Nickname(_) => { + let account_info = account_service.clone(); + match account_info { + AccountServiceEnum::Nickname(nickname) => { ensure!(!FromNickname::::contains_key(info.clone()), Error::::AlreadyTaked); + ensure!(!nickname.contains(&"@".as_bytes()[0]), Error::::WrongFormat); let id = match >::get(&sender) { Some(mut id) => { id.nickname = info.clone(); id } - None => MultiAddressDetails { nickname: info.clone(), ethereum: AccountServiceEnum::Ethereum([0u8; 20])}, + None => MultiAddressDetails { nickname: info.clone(), ethereum: AccountServiceEnum::Ethereum([0u8; 20]), twitter: AccountServiceEnum::Twitter(vec![0]) }, }; >::insert(&sender, id); >::insert(info.clone(), &sender); }, AccountServiceEnum::Ethereum(_) => { ensure!(false, Error::::NotAllowed); - // ensure!(!FromEthereum::::contains_key(info.clone()), Error::::AlreadyTaked); - // let id = match >::get(&sender) { - // Some(mut id) => { - // id.ethereum = info.clone(); - // id - // } - // None => MultiAddressDetails { nickname: AccountService::Nickname(vec![0]), ethereum: info.clone()}, - // }; - // >::insert(&sender, id); - // >::insert(info.clone(), &sender); + }, + AccountServiceEnum::Twitter(_) => { + ensure!(false, Error::::NotAllowed); } } Self::deposit_event(RawEvent::NameChanged(sender.clone(), info.clone())); @@ -197,15 +201,17 @@ decl_module! { let sender = ensure_signed(origin)?; ensure!(sender == Self::account_root(), Error::::NotAllowed); let info = account_service.clone(); - match info { - AccountServiceEnum::Nickname(_) => { + let account_info = info.clone(); + match account_info { + AccountServiceEnum::Nickname(nickname) => { ensure!(!FromNickname::::contains_key(info.clone()), Error::::AlreadyTaked); + ensure!(!nickname.contains(&"@".as_bytes()[0]), Error::::WrongFormat); let id = match >::get(&dest) { Some(mut id) => { id.nickname = info.clone(); id } - None => MultiAddressDetails { nickname: info.clone(), ethereum: AccountServiceEnum::Ethereum([0u8; 20])}, + None => MultiAddressDetails { nickname: info.clone(), ethereum: AccountServiceEnum::Ethereum([0u8; 20]), twitter: AccountServiceEnum::Twitter(vec![0]) }, }; >::insert(&dest, id); >::insert(info.clone(), &dest); @@ -218,10 +224,26 @@ decl_module! { id.ethereum = info.clone(); id } - None => MultiAddressDetails { nickname: AccountServiceEnum::Nickname(vec![0]), ethereum: info.clone()}, + None => MultiAddressDetails { nickname: AccountServiceEnum::Nickname(vec![0]), ethereum: info.clone(), twitter: AccountServiceEnum::Twitter(vec![0]) }, }; >::insert(&dest, id); >::insert(info.clone(), &dest); + }, + AccountServiceEnum::Twitter(twitter) => { + ensure!(!FromTwitter::::contains_key(info.clone()), Error::::AlreadyTaked); + ensure!(twitter.len() > 8, Error::::WrongFormat); + let words = "@twitter".as_bytes(); + let end_words = &twitter[(twitter.len() - 8)..(twitter.len())]; + ensure!(end_words == words, Error::::WrongFormat); + let id = match >::get(&dest) { + Some(mut id) => { + id.twitter = info.clone(); + id + } + None => MultiAddressDetails { nickname: AccountServiceEnum::Nickname(vec![0]), ethereum: AccountServiceEnum::Ethereum([0u8; 20]), twitter: info.clone() }, + }; + >::insert(&dest, id); + >::insert(info.clone(), &dest); } } Self::deposit_event(RawEvent::NameChanged(dest.clone(), info.clone())); @@ -261,163 +283,3 @@ decl_module! { } } } - -// #[cfg(test)] -// mod tests { -// use super::*; - -// use frame_support::{ -// assert_ok, assert_noop, impl_outer_origin, parameter_types, -// ord_parameter_types -// }; -// use sp_core::H256; -// use frame_system::EnsureSignedBy; -// use sp_runtime::{ -// testing::Header, traits::{BlakeTwo256, IdentityLookup, BadOrigin}, -// }; - -// impl_outer_origin! { -// pub enum Origin for Test where system = frame_system {} -// } - -// #[derive(Clone, Eq, PartialEq)] -// pub struct Test; -// parameter_types! { -// pub const BlockHashCount: u64 = 250; -// pub BlockWeights: frame_system::limits::BlockWeights = -// frame_system::limits::BlockWeights::simple_max(1024); -// } -// impl frame_system::Config for Test { -// type BaseCallFilter = (); -// type BlockWeights = (); -// type BlockLength = (); -// type DbWeight = (); -// type Origin = Origin; -// type Index = u64; -// type BlockNumber = u64; -// type Hash = H256; -// type Call = (); -// type Hashing = BlakeTwo256; -// type AccountId = u64; -// type Lookup = IdentityLookup; -// type Header = Header; -// type Event = (); -// type BlockHashCount = BlockHashCount; -// type Version = (); -// type PalletInfo = (); -// type AccountData = pallet_balances::AccountData; -// type OnNewAccount = (); -// type OnKilledAccount = (); -// type SystemWeightInfo = (); -// } -// parameter_types! { -// pub const ExistentialDeposit: u64 = 1; -// } -// impl pallet_balances::Config for Test { -// type MaxLocks = (); -// type Balance = u64; -// type Event = (); -// type DustRemoval = (); -// type ExistentialDeposit = ExistentialDeposit; -// type AccountStore = System; -// type WeightInfo = (); -// } -// parameter_types! { -// pub const ReservationFee: u64 = 2; -// pub const MinLength: usize = 3; -// pub const MaxLength: usize = 16; -// } -// ord_parameter_types! { -// pub const One: u64 = 1; -// } -// impl Config for Test { -// type Event = (); -// type Currency = Balances; -// type ReservationFee = ReservationFee; -// type Slashed = (); -// type ForceOrigin = EnsureSignedBy; -// type MinLength = MinLength; -// type MaxLength = MaxLength; -// } -// type System = frame_system::Module; -// type Balances = pallet_balances::Module; -// type Nicks = Module; - -// fn new_test_ext() -> sp_io::TestExternalities { -// let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); -// pallet_balances::GenesisConfig:: { -// balances: vec![ -// (1, 10), -// (2, 10), -// ], -// }.assimilate_storage(&mut t).unwrap(); -// t.into() -// } - -// #[test] -// fn kill_name_should_work() { -// new_test_ext().execute_with(|| { -// assert_ok!(Nicks::set_name(Origin::signed(2), b"Dave".to_vec())); -// assert_eq!(Balances::total_balance(&2), 10); -// assert_ok!(Nicks::kill_name(Origin::signed(1), 2)); -// assert_eq!(Balances::total_balance(&2), 8); -// assert_eq!(>::get(2), None); -// }); -// } - -// #[test] -// fn force_name_should_work() { -// new_test_ext().execute_with(|| { -// assert_noop!( -// Nicks::set_name(Origin::signed(2), b"Dr. David Brubeck, III".to_vec()), -// Error::::TooLong, -// ); - -// assert_ok!(Nicks::set_name(Origin::signed(2), b"Dave".to_vec())); -// assert_eq!(Balances::reserved_balance(2), 2); -// assert_ok!(Nicks::force_name(Origin::signed(1), 2, b"Dr. David Brubeck, III".to_vec())); -// assert_eq!(Balances::reserved_balance(2), 2); -// assert_eq!(>::get(2).unwrap(), (b"Dr. David Brubeck, III".to_vec(), 2)); -// }); -// } - -// #[test] -// fn normal_operation_should_work() { -// new_test_ext().execute_with(|| { -// assert_ok!(Nicks::set_name(Origin::signed(1), b"Gav".to_vec())); -// assert_eq!(Balances::reserved_balance(1), 2); -// assert_eq!(Balances::free_balance(1), 8); -// assert_eq!(>::get(1).unwrap().0, b"Gav".to_vec()); - -// assert_ok!(Nicks::set_name(Origin::signed(1), b"Gavin".to_vec())); -// assert_eq!(Balances::reserved_balance(1), 2); -// assert_eq!(Balances::free_balance(1), 8); -// assert_eq!(>::get(1).unwrap().0, b"Gavin".to_vec()); - -// assert_ok!(Nicks::clear_name(Origin::signed(1))); -// assert_eq!(Balances::reserved_balance(1), 0); -// assert_eq!(Balances::free_balance(1), 10); -// }); -// } - -// #[test] -// fn error_catching_should_work() { -// new_test_ext().execute_with(|| { -// assert_noop!(Nicks::clear_name(Origin::signed(1)), Error::::Unnamed); - -// assert_noop!( -// Nicks::set_name(Origin::signed(3), b"Dave".to_vec()), -// pallet_balances::Error::::InsufficientBalance -// ); - -// assert_noop!(Nicks::set_name(Origin::signed(1), b"Ga".to_vec()), Error::::TooShort); -// assert_noop!( -// Nicks::set_name(Origin::signed(1), b"Gavin James Wood, Esquire".to_vec()), -// Error::::TooLong -// ); -// assert_ok!(Nicks::set_name(Origin::signed(1), b"Dave".to_vec())); -// assert_noop!(Nicks::kill_name(Origin::signed(2), 1), BadOrigin); -// assert_noop!(Nicks::force_name(Origin::signed(2), 1, b"Whatever".to_vec()), BadOrigin); -// }); -// } -// } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 7f48b7d..6622982 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -180,6 +180,36 @@ where account }) }, + sp_runtime::MultiAddress::Raw(i) => { + if i.len() < 1 { + Err(LookupError) + } else if i.len() > 0 && i.len() < 9 { + let account = AccountService::from_nick_name(&AccountServiceEnum::Nickname(i)); + if account == AccountId32::new([0u8; 32]) { + Err(LookupError) + } else { + Ok(account.into()) + } + } else if i.len() > 8 && i.len() < 21 { + if &i[(i.len() - 8)..(i.len())] == "@twitter".as_bytes() { + let account = AccountService::from_twitter(&AccountServiceEnum::Twitter(i)); + if account == AccountId32::new([0u8; 32]) { + Err(LookupError) + } else { + Ok(account.into()) + } + } else { + let account = AccountService::from_nick_name(&AccountServiceEnum::Nickname(i)); + if account == AccountId32::new([0u8; 32]) { + Err(LookupError) + } else { + Ok(account.into()) + } + } + } else { + Err(LookupError) + } + }, _ => Err(LookupError), } }