Skip to content

Commit 8ecf782

Browse files
conr2dJungyong Um
andauthored
feat: Use AccountId32 for account identifier (#65)
* feat: Add recovering key from p256 signature * wip: Add serde feature to UniversalAddress * chore: Disable node & runtime build * feat: Add p256 recovery to runtime * feat: Replace UniversalSigner with UniversalAddress * refactor: Remove unused dependency * build: Re-enable runtime * build: Re-enable node * fix: Fix build errors * Override substrate types * Separate Ethereum RPC server * fix: Allow only low-s signature for p256 * refactor: Improve check_origin in webauthn signature * feat: Re-enable webauthn signature scheme * style: Use tabs for indent * refactor: Clean up types * feat: Add cosmos rpc server * chore: Bump version to 0.3.0-dev * test: Fix broken tests * fix: Fix invalid recovery id with p256 signature --------- Co-authored-by: Jungyong Um <[email protected]>
1 parent 5812378 commit 8ecf782

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+4347
-1180
lines changed

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,32 @@ members = [
1515
authors = ["Haderech Pte. Ltd."]
1616
edition = "2021"
1717
repository = "https://github.com/noirhq/noir/"
18-
version = "0.2.0"
18+
version = "0.3.0-dev"
1919

2020
[workspace.dependencies]
2121
array-bytes = "6.2.2"
2222
async-trait = "0.1.66"
2323
base64ct = { version = "1.6.0", default-features = false }
2424
clap = { version = "4.1.8", features = ["derive"] }
25+
ecdsa = "0.16.8"
2526
ethereum = { version = "0.15.0", default-features = false, features = ["with-codec"] }
2627
futures = { version = "0.3.26", features = ["thread-pool"] }
2728
hmac = { version = "0.12.1", default-features = false }
2829
jsonrpsee = { version = "0.22.5", features = ["server"] }
2930
lazy_static = { version = "1.4.0", default-features = false }
3031
log = "0.4.17"
3132
parity-scale-codec = { version = "3.4.0", default-features = false, features = ["derive"] }
32-
p256 = { version = "0.13.0", default-features = false, features = ["ecdsa", "alloc"] }
33+
p256 = { version = "0.13.2", default-features = false, features = ["ecdsa", "alloc"] }
3334
regex = "1.7.1"
3435
scale-info = { version = "2.3.1", default-features = false, features = ["derive"] }
3536
secp256k1 = { version = "0.28.1", default-features = false, features = ["alloc"] }
3637
serde = { version = "1.0.152", default-features = false, features = ["derive"] }
3738
serde_json = { version = "1.0.94", default-features = false }
3839
sha2 = { version = "0.10.6", default-features = false }
3940
substrate-bip39 = { version = "0.4.4" }
41+
thiserror = "1.0.61"
4042
tiny-bip39 = "1.0.0"
43+
url = "2.5.0"
4144
zeroize = { version = "1.5.7", default-features = false }
4245

4346
# noir

core-primitives/src/lib.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ use sp_runtime::traits::{IdentifyAccount, Verify};
2424

2525
/// An index to a block.
2626
pub type BlockNumber = u32;
27+
/// An instant or duration in time.
28+
pub type Moment = u64;
2729
/// Block header type as expected by this runtime.
2830
pub type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;
2931
/// Block type as expected by this runtime.
@@ -33,13 +35,20 @@ pub type Hash = sp_core::H256;
3335
/// Balance of an account.
3436
pub type Balance = u128;
3537
/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
36-
pub type Signature = np_runtime::UniversalSignature;
38+
pub type Signature = np_runtime::AuthenticationProof;
3739
/// Some way of identifying an account on the chain. We intentionally make it equivalent
3840
/// to the public key of our transaction signing scheme.
3941
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
4042
/// Index of a transaction in the chain.
4143
pub type Nonce = u32;
4244
/// The type for looking up accounts.
43-
pub type AccountIndex = u128;
45+
pub type AccountIndex = ();
4446
/// The address format for describing accounts.
4547
pub type Address = sp_runtime::MultiAddress<AccountId, AccountIndex>;
48+
49+
/// Basic currency unit.
50+
pub const DOLLARS: Balance = 1_000_000_000_000_000_000;
51+
/// Decimals of currency.
52+
pub const DECIMALS: u8 = 18;
53+
/// Symbol of currency.
54+
pub const SYMBOL: &str = "CDT";

frame/alias/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ std = [
3333
"sp-runtime/std",
3434
"sp-std/std",
3535
]
36+
try-runtime = []

frame/alias/src/lib.rs

Lines changed: 31 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,26 @@
2222

2323
pub mod weights;
2424

25+
pub use pallet::*;
26+
2527
use crate::weights::WeightInfo;
2628
use np_crypto::ecdsa::EcdsaExt;
27-
use np_runtime::AccountName;
28-
pub use pallet::*;
2929
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
3030
use scale_info::TypeInfo;
31-
use sp_runtime::{
32-
traits::{LookupError, StaticLookup},
33-
DispatchError, MultiAddress,
34-
};
35-
use sp_std::prelude::*;
36-
37-
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
38-
39-
/// A generator for tag number that discriminates the same name accounts.
40-
pub trait TagGenerator<T: Config> {
41-
fn tag(id: &T::AccountId, name: &str) -> Result<u16, ()>;
42-
}
31+
use sp_runtime::{BoundedBTreeSet, DispatchError};
32+
use sp_std::{collections::btree_set::BTreeSet, prelude::*};
4333

4434
#[cfg_attr(feature = "std", derive(Hash))]
4535
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Encode, Decode, MaxEncodedLen, TypeInfo)]
4636
pub enum AccountAlias {
47-
AccountName(AccountName),
4837
EthereumAddress([u8; 20]),
4938
CosmosAddress([u8; 20]),
5039
}
5140

5241
#[frame_support::pallet]
5342
pub mod pallet {
54-
5543
use super::*;
5644
use frame_support::pallet_prelude::*;
57-
use frame_system::pallet_prelude::*;
5845

5946
/// The module's config trait.
6047
#[pallet::config]
@@ -63,126 +50,14 @@ pub mod pallet {
6350
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
6451
/// Weight information for extrinsics in this pallet.
6552
type WeightInfo: WeightInfo;
66-
/// The generator for tag number that discriminates the same name accounts.
67-
type TagGenerator: TagGenerator<Self>;
6853
}
6954

7055
#[pallet::pallet]
71-
pub struct Pallet<T>(PhantomData<T>);
72-
73-
#[pallet::call]
74-
impl<T: Config> Pallet<T>
75-
where
76-
T::AccountId: EcdsaExt,
77-
{
78-
#[pallet::call_index(0)]
79-
#[pallet::weight(T::WeightInfo::create_account_name())]
80-
pub fn create_account_name(origin: OriginFor<T>, name: Vec<u8>) -> DispatchResult {
81-
let who = ensure_signed(origin)?;
82-
ensure!(AccountNameOf::<T>::get(&who).is_none(), Error::<T>::AlreadyExists);
83-
let name =
84-
sp_std::str::from_utf8(&name[..]).map_err(|_| Error::<T>::InvalidNameFormat)?;
85-
let tag =
86-
T::TagGenerator::tag(&who, name).map_err(|_| Error::<T>::TagGenerationFailed)?;
87-
let account_name =
88-
AccountName::new(&name, tag).map_err(|_| Error::<T>::InvalidNameFormat)?;
89-
AccountIdOf::<T>::try_mutate(
90-
AccountAlias::AccountName(account_name),
91-
|maybe_value| -> DispatchResult {
92-
ensure!(maybe_value.is_none(), Error::<T>::InUse);
93-
*maybe_value = Some(who.clone());
94-
Ok(())
95-
},
96-
)?;
97-
AccountNameOf::<T>::insert(&who, account_name);
98-
Self::deposit_event(Event::<T>::AccountNameUpdated {
99-
who,
100-
name: account_name,
101-
deleted: None,
102-
});
103-
Ok(())
104-
}
105-
106-
#[pallet::call_index(1)]
107-
#[pallet::weight(T::WeightInfo::update_account_name())]
108-
pub fn update_account_name(origin: OriginFor<T>, new_name: Vec<u8>) -> DispatchResult {
109-
let who = ensure_signed(origin)?;
110-
let account_name = AccountNameOf::<T>::get(&who).ok_or(Error::<T>::NotExists)?;
111-
let new_name =
112-
sp_std::str::from_utf8(&new_name[..]).map_err(|_| Error::<T>::InvalidNameFormat)?;
113-
let tag = T::TagGenerator::tag(&who, new_name)
114-
.map_err(|_| Error::<T>::TagGenerationFailed)?;
115-
let new_account_name =
116-
AccountName::new(&new_name, tag).map_err(|_| Error::<T>::InvalidNameFormat)?;
117-
AccountIdOf::<T>::try_mutate(
118-
AccountAlias::AccountName(new_account_name),
119-
|maybe_value| -> DispatchResult {
120-
ensure!(maybe_value.is_none(), Error::<T>::InUse);
121-
*maybe_value = Some(who.clone());
122-
Ok(())
123-
},
124-
)?;
125-
AccountIdOf::<T>::remove(AccountAlias::AccountName(account_name));
126-
AccountNameOf::<T>::insert(&who, new_account_name);
127-
Self::deposit_event(Event::<T>::AccountNameUpdated {
128-
who,
129-
name: new_account_name,
130-
deleted: Some(account_name),
131-
});
132-
Ok(())
133-
}
134-
135-
#[pallet::call_index(2)]
136-
#[pallet::weight(T::WeightInfo::connect_aliases())]
137-
pub fn connect_aliases(origin: OriginFor<T>) -> DispatchResult {
138-
let who = ensure_signed(origin)?;
139-
Self::connect_aliases_secp256k1(&who)?;
140-
Ok(())
141-
}
142-
143-
#[pallet::call_index(3)]
144-
#[pallet::weight(T::WeightInfo::force_set_account_name())]
145-
pub fn force_set_account_name(
146-
origin: OriginFor<T>,
147-
dest: AccountIdLookupOf<T>,
148-
name: Vec<u8>,
149-
tag: u16,
150-
) -> DispatchResult {
151-
ensure_root(origin)?;
152-
let dest = T::Lookup::lookup(dest)?;
153-
let name =
154-
sp_std::str::from_utf8(&name[..]).map_err(|_| Error::<T>::InvalidNameFormat)?;
155-
let new_account_name =
156-
AccountName::new(&name, tag).map_err(|_| Error::<T>::InvalidNameFormat)?;
157-
AccountIdOf::<T>::try_mutate(
158-
AccountAlias::AccountName(new_account_name),
159-
|maybe_value| -> DispatchResult {
160-
ensure!(maybe_value.is_none(), Error::<T>::InUse);
161-
*maybe_value = Some(dest.clone());
162-
Ok(())
163-
},
164-
)?;
165-
166-
let past_name = AccountNameOf::<T>::get(&dest);
167-
match past_name {
168-
Some(past_name) => AccountIdOf::<T>::remove(AccountAlias::AccountName(past_name)),
169-
None => (),
170-
};
171-
AccountNameOf::<T>::insert(&dest, new_account_name);
172-
Self::deposit_event(Event::<T>::AccountNameUpdated {
173-
who: dest,
174-
name: new_account_name,
175-
deleted: past_name,
176-
});
177-
Ok(())
178-
}
179-
}
56+
pub struct Pallet<T>(_);
18057

18158
#[pallet::event]
18259
#[pallet::generate_deposit(pub(super) fn deposit_event)]
18360
pub enum Event<T: Config> {
184-
/// An account name was updated.
185-
AccountNameUpdated { who: T::AccountId, name: AccountName, deleted: Option<AccountName> },
18661
/// An ethereum address was published.
18762
EthereumAddressPublished { who: T::AccountId, address: [u8; 20] },
18863
/// An cosmos address was published.
@@ -191,83 +66,66 @@ pub mod pallet {
19166

19267
#[pallet::error]
19368
pub enum Error<T> {
194-
/// The account name already exists.
195-
AlreadyExists,
196-
/// The account name does not exists.
197-
NotExists,
198-
/// The account name is not available.
199-
InUse,
200-
/// Invalid name foramt.
201-
InvalidNameFormat,
202-
/// Tag generation failed.
203-
TagGenerationFailed,
20469
/// Ethereum address conversion failed.
20570
EthereumAddressConversionFailed,
20671
/// Cosmos address conversion failed.
20772
CosmosAddressConversionFailed,
20873
}
20974

21075
#[pallet::storage]
76+
#[pallet::getter(fn accountid)]
21177
pub type AccountIdOf<T: Config> = StorageMap<_, Blake2_128Concat, AccountAlias, T::AccountId>;
78+
21279
#[pallet::storage]
213-
pub type AccountNameOf<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, AccountName>;
80+
#[pallet::getter(fn aliases)]
81+
pub type AccountAliases<T: Config> =
82+
StorageMap<_, Blake2_128Concat, T::AccountId, BoundedBTreeSet<AccountAlias, ConstU32<2>>>;
21483
}
21584

21685
impl<T: Config> Pallet<T>
21786
where
21887
T::AccountId: EcdsaExt,
21988
{
220-
// PUBLIC IMMUTABLES
221-
22289
/// Lookup an AccountAlias to get an Id, if exists.
22390
pub fn lookup(alias: &AccountAlias) -> Option<T::AccountId> {
22491
AccountIdOf::<T>::get(alias).map(|x| x)
22592
}
22693

227-
pub fn connect_aliases_secp256k1(who: &T::AccountId) -> Result<(), DispatchError> {
228-
let ethereum_address = who
94+
pub fn alias_secp256k1(who: &T::AccountId) -> Result<(), DispatchError> {
95+
let mut aliases = BTreeSet::new();
96+
let eth = who
22997
.to_eth_address()
23098
.map(|x| x.into())
23199
.ok_or(Error::<T>::EthereumAddressConversionFailed)?;
232-
if AccountIdOf::<T>::get(AccountAlias::EthereumAddress(ethereum_address)).is_none() {
233-
AccountIdOf::<T>::insert(AccountAlias::EthereumAddress(ethereum_address), who);
100+
let eth_alias = AccountAlias::EthereumAddress(eth);
101+
if AccountIdOf::<T>::get(eth_alias).is_none() {
102+
AccountIdOf::<T>::insert(eth_alias, who.clone());
103+
aliases.insert(eth_alias);
234104
Self::deposit_event(Event::<T>::EthereumAddressPublished {
235105
who: who.clone(),
236-
address: ethereum_address,
106+
address: eth,
237107
});
238108
}
239-
let cosmos_address = who
109+
let cosm = who
240110
.to_cosm_address()
241111
.map(|x| x.into())
242112
.ok_or(Error::<T>::CosmosAddressConversionFailed)?;
243-
if AccountIdOf::<T>::get(AccountAlias::CosmosAddress(cosmos_address)).is_none() {
244-
AccountIdOf::<T>::insert(AccountAlias::CosmosAddress(cosmos_address), who);
113+
let cosm_alias = AccountAlias::CosmosAddress(cosm);
114+
if AccountIdOf::<T>::get(cosm_alias).is_none() {
115+
AccountIdOf::<T>::insert(cosm_alias, who.clone());
116+
aliases.insert(cosm_alias);
245117
Self::deposit_event(Event::<T>::CosmosAddressPublished {
246118
who: who.clone(),
247-
address: cosmos_address,
119+
address: cosm,
248120
});
249121
}
250-
Ok(())
251-
}
252-
}
253-
254-
impl<T: Config> StaticLookup for Pallet<T>
255-
where
256-
T::AccountId: EcdsaExt,
257-
{
258-
type Source = MultiAddress<T::AccountId, AccountName>;
259-
type Target = T::AccountId;
260-
261-
fn lookup(a: Self::Source) -> Result<Self::Target, LookupError> {
262-
match a {
263-
MultiAddress::Id(id) => Ok(id),
264-
MultiAddress::Index(name) =>
265-
Self::lookup(&AccountAlias::AccountName(name)).ok_or(LookupError),
266-
_ => Err(LookupError),
122+
if !aliases.is_empty() {
123+
AccountAliases::<T>::insert(
124+
who,
125+
BoundedBTreeSet::try_from(aliases)
126+
.map_err(|_| DispatchError::Other("Too many aliases"))?,
127+
);
267128
}
268-
}
269-
270-
fn unlookup(a: Self::Target) -> Self::Source {
271-
MultiAddress::Id(a)
129+
Ok(())
272130
}
273131
}

frame/alias/src/weights.rs

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,17 @@ use frame_support::{traits::Get, weights::Weight};
2525

2626
/// Weight functions needed for pallet_alias.
2727
pub trait WeightInfo {
28-
fn create_account_name() -> Weight;
29-
fn update_account_name() -> Weight;
30-
fn connect_aliases() -> Weight;
31-
fn force_set_account_name() -> Weight;
28+
fn alias() -> Weight;
3229
}
3330

3431
/// Weights for pallet_alias using the Substrate node and recommended hardware.
3532
pub struct SubstrateWeight<T>(PhantomData<T>);
3633
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
3734
// Storage: AccountIdOf (r:1 w:1), AccountNameOf (r:1 w:1)
38-
fn create_account_name() -> Weight {
39-
// Base fee
40-
Weight::from_parts(50_000_000, 0)
41-
.saturating_add(T::DbWeight::get().reads(2 as u64))
42-
.saturating_add(T::DbWeight::get().writes(2 as u64))
43-
}
44-
// Storage: AccountIdOf (r:1 w:2), AccountNameOf (r:1 w:1)
45-
fn update_account_name() -> Weight {
46-
// Base fee
47-
Weight::from_parts(100_000_000 as u64, 0)
48-
.saturating_add(T::DbWeight::get().reads(2 as u64))
49-
.saturating_add(T::DbWeight::get().writes(3 as u64))
50-
}
51-
// Storage: AccountIdOf (r:1 w:1), AccountNameOf (r:1 w:1)
52-
fn connect_aliases() -> Weight {
35+
fn alias() -> Weight {
5336
// Base fee
5437
Weight::from_parts(50_000_000, 0)
5538
.saturating_add(T::DbWeight::get().reads(1 as u64))
5639
.saturating_add(T::DbWeight::get().writes(1 as u64))
5740
}
58-
// Storage: AccountIdOf (r:1 w:2), AccountNameOf (r:1 w:1)
59-
fn force_set_account_name() -> Weight {
60-
// Base fee
61-
Weight::from_parts(50_000_000, 0)
62-
.saturating_add(T::DbWeight::get().reads(2 as u64))
63-
.saturating_add(T::DbWeight::get().writes(3 as u64))
64-
}
6541
}

0 commit comments

Comments
 (0)