Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9856d9e
Init pallet-account
akru Feb 7, 2023
8e049e6
Merge remote-tracking branch 'origin/polkadot-v0.9.37' into feature/p…
akru Feb 20, 2023
a909f8e
Added simple salt implementation & mocks
akru Feb 20, 2023
3619ac4
Custom origin driven pallet-account
akru Mar 7, 2023
2cec263
Merge remote-tracking branch 'origin/polkadot-v0.9.37'
akru Mar 28, 2023
d810947
proxy call implementation
akru Mar 28, 2023
6e71c60
Update frame/pallet-account/src/lib.rs
akru Apr 6, 2023
c1a740e
Update frame/pallet-account/src/pallet/mod.rs
akru Apr 6, 2023
6f5aa27
Update frame/pallet-account/src/lib.rs
akru Apr 6, 2023
ee7e727
Update frame/pallet-account/src/lib.rs
akru Apr 6, 2023
0973c5a
Update frame/pallet-account/src/lib.rs
akru Apr 6, 2023
98700fa
Temporary remove meta_call
akru Apr 6, 2023
f8149af
Rewrite origin storage to make it storage info compatible
akru Apr 6, 2023
b0c4bb0
Use workspace authors
akru Apr 7, 2023
11ec601
Added TODO for weights
akru Apr 20, 2023
eb56aa2
Fix weights setting
akru Apr 20, 2023
b494247
Fix tests
akru Apr 20, 2023
0307dcd
Added negative tests
akru Apr 20, 2023
34b2d24
Fix cargo fmt
akru Apr 20, 2023
c829786
Added benchmarking
akru Apr 24, 2023
564a2e9
Fix cargo fmt
akru Apr 24, 2023
83fa23b
Use runtime level compatible hashing
akru Apr 24, 2023
ca3bddc
Merge branch 'polkadot-v0.9.39' into feature/pallet-account
akru Apr 24, 2023
3a1ae8b
Update frame/pallet-account/src/lib.rs
akru May 30, 2023
7aca6a1
Added event checks into tests
akru May 30, 2023
81f533d
Added OnKillAccount handler & creation deposit functionality
akru May 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"frame/collator-selection",
"frame/custom-signatures",
"frame/dapps-staking",
"frame/pallet-account",
"frame/pallet-xcm",
"frame/pallet-xvm",
"frame/xc-asset-config",
Expand Down
44 changes: 44 additions & 0 deletions frame/pallet-account/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
name = "pallet-account"
authors = ["Stake Technologies"]
edition = "2021"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use workspace inheritance for relevant package info values.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

version = "0.1.0"

[dependencies]
log = { workspace = true }
serde = { workspace = true, optional = true }

# Substrate
parity-scale-codec = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
scale-info = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }

# Benchmarks
frame-benchmarking = { workspace = true, optional = true }

[dev-dependencies]
pallet-balances = { workspace = true, features = ["std"] }
assert_matches = { workspace = true }
hex-literal = { workspace = true }

[features]
default = ["std"]
std = [
"parity-scale-codec/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"serde",
"sp-core/std",
"sp-runtime/std",
"sp-std/std",
]

runtime-benchmarks = [
"frame-benchmarking",
]
try-runtime = ["frame-support/try-runtime"]
52 changes: 52 additions & 0 deletions frame/pallet-account/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar 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.

// Astar 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 Astar. If not, see <http://www.gnu.org/licenses/>.

//! # Account abstraction pallet
//!
//! ## Overview
//!
//! An accout abstraction pallet make possible to derive new blockchain based
Comment thread
akru marked this conversation as resolved.
Outdated
//! account for your existed external owned account (seed phrase based). The onchain
Comment thread
akru marked this conversation as resolved.
Outdated
//! account could be drived to multiple address spaces: H160 and SS58. For example,
Comment thread
akru marked this conversation as resolved.
Outdated
//! it makes possible predictable interaction between substrate native account and
//! EVM smart contracts.
Comment thread
akru marked this conversation as resolved.
Outdated
//!
//! ## Interface
//!
//! ### Dispatchable Function
//!
//! * new_origin() - create new origin for account
//! * proxy_call() - make proxy call with derived account as origin
//! * meta_call() - make meta call with dedicated payer account
//!

#![cfg_attr(not(feature = "std"), no_std)]

pub mod origins;
pub use origins::*;

pub mod pallet;
pub use pallet::pallet::*;

pub mod weights;
pub use weights::*;

#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
Comment thread
akru marked this conversation as resolved.
155 changes: 155 additions & 0 deletions frame/pallet-account/src/mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar 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.

// Astar 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 Astar. If not, see <http://www.gnu.org/licenses/>.

use crate as pallet_account;

use frame_support::{
construct_runtime, parameter_types, sp_io::TestExternalities, weights::Weight,
};
use hex_literal::hex;
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
AccountId32,
};

pub(crate) type AccountId = AccountId32;
pub(crate) type BlockNumber = u64;
pub(crate) type Balance = u128;

pub(crate) const ALICE: AccountId = AccountId::new([0u8; 32]);
pub(crate) const BOB: AccountId = AccountId::new([1u8; 32]);

pub(crate) const ALICE_ED25519: [u8; 32] =
hex!["88dc3417d5058ec4b4503e0c12ea1a0a89be200fe98922423d4334014fa6b0ee"];

pub(crate) const ALICE_D1_NATIVE: [u8; 32] =
hex!["9f0e444c69f77a49bd0be89db92c38fe713e0963165cca12faf5712d7657120f"];
pub(crate) const ALICE_D2_H160: [u8; 20] = hex!["5d2532e641a22a8f5e0a42652fe82dc231fd27f8"];

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<TestRuntime>;
type Block = frame_system::mocking::MockBlock<TestRuntime>;

/// Value shouldn't be less than 2 for testing purposes, otherwise we cannot test certain corner cases.
pub(crate) const EXISTENTIAL_DEPOSIT: Balance = 2;

construct_runtime!(
pub struct TestRuntime
where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system,
Balances: pallet_balances,
Account: pallet_account,
}
);

parameter_types! {
pub const BlockHashCount: u64 = 250;
pub BlockWeights: frame_system::limits::BlockWeights =
frame_system::limits::BlockWeights::simple_max(Weight::from_ref_time(1024));
}

impl frame_system::Config for TestRuntime {
type BaseCallFilter = frame_support::traits::Everything;
type BlockWeights = ();
type BlockLength = ();
type RuntimeOrigin = RuntimeOrigin;
type Index = u64;
type RuntimeCall = RuntimeCall;
type BlockNumber = BlockNumber;
type Hash = H256;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = BlockHashCount;
type DbWeight = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

parameter_types! {
pub const MaxLocks: u32 = 4;
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
}

impl pallet_balances::Config for TestRuntime {
type MaxLocks = MaxLocks;
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
}

parameter_types! {
pub const ChainMagic: u16 = 0x4200;
}

impl pallet_account::Config for TestRuntime {
type CustomOrigin = super::NativeAndEVM;
type CustomOriginKind = super::NativeAndEVMKind;
type RuntimeOrigin = RuntimeOrigin;
type RuntimeCall = RuntimeCall;
type ChainMagic = ChainMagic;
type Signer = sp_runtime::MultiSigner;
type Signature = sp_runtime::MultiSignature;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}

pub struct ExternalityBuilder;

impl ExternalityBuilder {
pub fn build() -> TestExternalities {
let mut storage = frame_system::GenesisConfig::default()
.build_storage::<TestRuntime>()
.unwrap();

// This will cause some initial issuance
pallet_balances::GenesisConfig::<TestRuntime> {
balances: vec![
(ALICE, 9000),
(ALICE_ED25519.into(), 1000),
(ALICE_D1_NATIVE.into(), 1000),
(BOB, 800),
],
}
.assimilate_storage(&mut storage)
.ok();

let mut ext = TestExternalities::from(storage);
ext.execute_with(|| System::set_block_number(1));
ext
}
}
64 changes: 64 additions & 0 deletions frame/pallet-account/src/origins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar 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.

// Astar 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 Astar. If not, see <http://www.gnu.org/licenses/>.

use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::{AccountId32, RuntimeDebug};

/// Derive new origin.
pub trait OriginDeriving<AccountId, Origin> {
/// Derive new origin depend of account and index
fn derive(&self, source: &AccountId, index: u32) -> Origin;
}

/// Origin that support native and EVM compatible options.
#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub enum NativeAndEVM {
Comment thread
akru marked this conversation as resolved.
/// Substrate native origin.
Native(AccountId32),
/// The 20-byte length Ethereum like origin.
H160(sp_core::H160),
}

impl TryInto<AccountId32> for NativeAndEVM {
type Error = ();
fn try_into(self) -> Result<AccountId32, Self::Error> {
match self {
NativeAndEVM::Native(a) => Ok(a),
_ => Err(()),
}
}
}

/// Kind for NativeAndEVM origin.
#[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub enum NativeAndEVMKind {
Native,
H160,
}
Comment on lines +60 to +63

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps adding impl Into for enum NativeAndEVM that converts into NativeAndEVMKind is a good idea - you can test the conversion & ensure it's exhaustive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably yes, but may be we can generate *Kind structure from custom origin somehow. I'll investigate later.


impl OriginDeriving<AccountId32, NativeAndEVM> for NativeAndEVMKind {
fn derive(&self, source: &AccountId32, index: u32) -> NativeAndEVM {
let salted_source = [source.as_ref(), &index.encode()[..]].concat();

@shaunxw shaunxw May 18, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can add module id as entropy, probably same to module id in pallet-utilities, to be compatible. https://github.com/paritytech/substrate/blob/f4a2e84ee5974b219f2a03cd195105060c41e3cd/frame/utility/src/lib.rs#LL506C28-L506C28

EDIT: probably not a good idea to be compatible with pallet-utilities. Compatibility with main stream derivation standard is more important

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, at first stage I prefer to give some sample of usage and no more. What’s about derivation standard, it could be easily implemented outside of the pallet.

let derived = sp_core::blake2_256(&salted_source);
match self {
NativeAndEVMKind::Native => NativeAndEVM::Native(derived.into()),
NativeAndEVMKind::H160 => NativeAndEVM::H160(sp_core::H160::from_slice(&derived[..20])),
}
}
Comment on lines +66 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dumb question: is our custom origin deriving meant to derive between H160 and Native? The impl here seems only to derive sub-accounts from their own type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to create new origin the call origin must be substrate-compatible.

}
Loading