Skip to content

Commit

Permalink
OmniAccount derivation (#3126)
Browse files Browse the repository at this point in the history
* add omni_account to primitives

* fix ci
  • Loading branch information
Kailai-Wang authored Oct 11, 2024
1 parent b656376 commit 2dbaa33
Show file tree
Hide file tree
Showing 25 changed files with 326 additions and 514 deletions.
2 changes: 1 addition & 1 deletion common/primitives/core/src/assertion/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Litentry. If not, see <https://www.gnu.org/licenses/>.

use crate::{CoreHash as Hash, String, Vec};
use crate::{String, Vec};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::{traits::ConstU32, BoundedVec};
Expand Down
42 changes: 19 additions & 23 deletions common/primitives/core/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use sp_core::{
use sp_io::hashing::blake2_256;
use sp_runtime::{
traits::{BlakeTwo256, ConstU32},
BoundedVec, RuntimeDebug,
BoundedVec,
};
use strum_macros::EnumIter;

Expand Down Expand Up @@ -359,21 +359,35 @@ impl Identity {
}
}

/// Currently we only support mapping from Address32/Address20 to AccountId, not opposite.
pub fn to_account_id(&self) -> Option<AccountId> {
/// map an `Identity` to a native parachain account that:
/// - has a private key for substrate and evm accounts, or any connect that can connect to parachain directly
/// - appears as origin when submitting extrinsics
///
/// this account is also used within the worker as e.g. sidechain accounts
pub fn to_native_account(&self) -> Option<AccountId> {
match self {
Identity::Substrate(address) | Identity::Solana(address) => Some(address.into()),
Identity::Substrate(address) => Some(address.into()),
Identity::Evm(address) => Some(HashedAddressMapping::into_account_id(
H160::from_slice(address.as_ref()),
)),
Identity::Bitcoin(address) => Some(blake2_256(address.as_ref()).into()),
// we use `to_omni_account` impl for non substrate/evm web3 accounts, as they
// can't connect to the parachain directly
Identity::Bitcoin(_) | Identity::Solana(_) => Some(self.to_omni_account()),
Identity::Twitter(_)
| Identity::Discord(_)
| Identity::Github(_)
| Identity::Email(_) => None,
}
}

/// derive an `OmniAccount` from `Identity` by hashing the encoded identity,
/// it should always be successful
///
/// an `OmniAccount` has no private key and can only be controlled by its MemberAccount
pub fn to_omni_account(&self) -> AccountId {
self.hash().to_fixed_bytes().into()
}

pub fn from_did(s: &str) -> Result<Self, &'static str> {
let did_prefix = String::from("did:litentry:");
if s.starts_with(&did_prefix) {
Expand Down Expand Up @@ -528,24 +542,6 @@ impl From<[u8; 33]> for Identity {
}
}

#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum MemberIdentity {
Public(Identity),
Private(Vec<u8>),
}

impl MemberIdentity {
pub fn is_public(&self) -> bool {
matches!(self, Self::Public(..))
}
}

impl From<Identity> for MemberIdentity {
fn from(identity: Identity) -> Self {
Self::Public(identity)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
8 changes: 4 additions & 4 deletions common/primitives/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ pub use assertion::Assertion;
pub mod identity;
pub use identity::*;

extern crate core;
mod omni_account;
pub use omni_account::*;

use alloc::{format, str, str::FromStr, string::String, vec, vec::Vec};
use core::hash::Hash as CoreHash;
use sp_core::H256;
use sp_runtime::{traits::ConstU32, BoundedVec};

pub use constants::*;
Expand All @@ -47,7 +47,7 @@ pub type ParameterString = BoundedVec<u8, ConstU32<64>>;

/// Common types of parachains.
mod types {
use super::H256;
use sp_core::H256;
use sp_runtime::{
traits::{IdentifyAccount, Verify},
MultiSignature,
Expand Down
78 changes: 78 additions & 0 deletions common/primitives/core/src/omni_account.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2020-2024 Trust Computing GmbH.
// This file is part of Litentry.
//
// Litentry is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Litentry is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Litentry. If not, see <https://www.gnu.org/licenses/>.

use crate::{AccountId, Hash, Identity, Vec};
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use sp_io::hashing::blake2_256;
use sp_runtime::{BoundedVec, RuntimeDebug};

#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, RuntimeDebug)]
pub enum MemberAccount {
Public(Identity),
Private(Vec<u8>, Hash),
}

impl MemberAccount {
pub fn is_public(&self) -> bool {
matches!(self, Self::Public(..))
}

pub fn hash(&self) -> Hash {
match self {
Self::Public(id) => id.hash(),
Self::Private(_, h) => *h,
}
}
}

impl From<Identity> for MemberAccount {
fn from(identity: Identity) -> Self {
Self::Public(identity)
}
}

pub trait GetAccountStoreHash {
fn hash(&self) -> Hash;
}

pub trait OmniAccountConverter {
type OmniAccount;
fn convert(identity: &Identity) -> Self::OmniAccount;
}

pub struct DefaultOmniAccountConverter;

impl OmniAccountConverter for DefaultOmniAccountConverter {
type OmniAccount = AccountId;
fn convert(identity: &Identity) -> AccountId {
identity.to_omni_account()
}
}

impl<T> GetAccountStoreHash for BoundedVec<MemberAccount, T> {
fn hash(&self) -> Hash {
let hashes: Vec<Hash> = self.iter().map(|member| member.hash()).collect();
hashes.using_encoded(blake2_256).into()
}
}

impl GetAccountStoreHash for Vec<MemberAccount> {
fn hash(&self) -> Hash {
let hashes: Vec<Hash> = self.iter().map(|member| member.hash()).collect();
hashes.using_encoded(blake2_256).into()
}
}
3 changes: 1 addition & 2 deletions common/primitives/core/src/teebag/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Litentry. If not, see <https://www.gnu.org/licenses/>.

use crate::H256;
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
use sp_core::{ed25519::Public as Ed25519Public, RuntimeDebug};
use sp_core::{ed25519::Public as Ed25519Public, RuntimeDebug, H256};
use sp_std::prelude::*;

pub type MrSigner = [u8; 32];
Expand Down
Loading

0 comments on commit 2dbaa33

Please sign in to comment.