From 47b75efcbd99a01026178437a841c6dbb73bdf5c Mon Sep 17 00:00:00 2001 From: Ashutosh Varma Date: Sun, 15 Oct 2023 22:48:46 +0530 Subject: [PATCH] feat: add unified account chain extension --- Cargo.lock | 33 ++++++++ Cargo.toml | 3 + .../types/unified-accounts/Cargo.toml | 27 ++++++ .../types/unified-accounts/src/lib.rs | 35 ++++++++ chain-extensions/unified-accounts/Cargo.toml | 44 ++++++++++ chain-extensions/unified-accounts/src/lib.rs | 84 +++++++++++++++++++ runtime/local/Cargo.toml | 2 + runtime/local/src/chain_extensions.rs | 7 +- runtime/local/src/lib.rs | 6 ++ runtime/shibuya/Cargo.toml | 2 + runtime/shibuya/src/chain_extensions.rs | 7 +- runtime/shibuya/src/lib.rs | 1 - 12 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 chain-extensions/types/unified-accounts/Cargo.toml create mode 100644 chain-extensions/types/unified-accounts/src/lib.rs create mode 100644 chain-extensions/unified-accounts/Cargo.toml create mode 100644 chain-extensions/unified-accounts/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2f81d10f4c..b1b0802922 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5994,6 +5994,7 @@ dependencies = [ "pallet-block-reward", "pallet-chain-extension-assets", "pallet-chain-extension-dapps-staking", + "pallet-chain-extension-unified-accounts", "pallet-chain-extension-xvm", "pallet-collective", "pallet-contracts", @@ -7461,6 +7462,26 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-chain-extension-unified-accounts" +version = "0.1.0" +dependencies = [ + "astar-primitives", + "frame-support", + "frame-system", + "log", + "num-traits", + "pallet-contracts", + "pallet-contracts-primitives", + "pallet-unified-accounts", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", + "sp-std", + "unified-accounts-chain-extension-types", +] + [[package]] name = "pallet-chain-extension-xvm" version = "0.1.1" @@ -13069,6 +13090,7 @@ dependencies = [ "pallet-block-reward", "pallet-chain-extension-assets", "pallet-chain-extension-dapps-staking", + "pallet-chain-extension-unified-accounts", "pallet-chain-extension-xvm", "pallet-collator-selection", "pallet-collective", @@ -15247,6 +15269,17 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unified-accounts-chain-extension-types" +version = "0.1.0" +dependencies = [ + "num_enum 0.5.11", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-runtime", +] + [[package]] name = "universal-hash" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index c5828cc529..6536eb17f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ members = [ "chain-extensions/dapps-staking", "chain-extensions/pallet-assets", "chain-extensions/xvm", + "chain-extensions/unified-accounts", "chain-extensions/types/*", "vendor/evm-tracing", @@ -294,10 +295,12 @@ pallet-evm-precompile-batch = { path = "./precompiles/batch", default-features = pallet-chain-extension-dapps-staking = { path = "./chain-extensions/dapps-staking", default-features = false } pallet-chain-extension-xvm = { path = "./chain-extensions/xvm", default-features = false } pallet-chain-extension-assets = { path = "./chain-extensions/pallet-assets", default-features = false } +pallet-chain-extension-unified-accounts = { path = "./chain-extensions/unified-accounts", default-features = false } dapps-staking-chain-extension-types = { path = "./chain-extensions/types/dapps-staking", default-features = false } xvm-chain-extension-types = { path = "./chain-extensions/types/xvm", default-features = false } assets-chain-extension-types = { path = "./chain-extensions/types/assets", default-features = false } +unified-accounts-chain-extension-types = { path = "./chain-extensions/types/unified-accounts", default-features = false } precompile-utils = { path = "./precompiles/utils", default-features = false } diff --git a/chain-extensions/types/unified-accounts/Cargo.toml b/chain-extensions/types/unified-accounts/Cargo.toml new file mode 100644 index 0000000000..340f7195ee --- /dev/null +++ b/chain-extensions/types/unified-accounts/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "unified-accounts-chain-extension-types" +version = "0.1.0" +description = "Types definitions for contracts using Unified Accounts chain-extension." +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +num_enum = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } + +#substarte +sp-core = { workspace = true } +sp-runtime = { workspace = true } + +[features] +default = ["std"] +std = [ + "num_enum/std", + "parity-scale-codec/std", + "scale-info/std", + "sp-core/std", + "sp-runtime/std", +] diff --git a/chain-extensions/types/unified-accounts/src/lib.rs b/chain-extensions/types/unified-accounts/src/lib.rs new file mode 100644 index 0000000000..a629a53708 --- /dev/null +++ b/chain-extensions/types/unified-accounts/src/lib.rs @@ -0,0 +1,35 @@ +// 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 . + +#![cfg_attr(not(feature = "std"), no_std)] + +use num_enum::{IntoPrimitive, TryFromPrimitive}; +use parity_scale_codec::{Decode, Encode}; + +#[repr(u16)] +#[derive(TryFromPrimitive, IntoPrimitive, Decode, Encode)] +pub enum Command { + /// Get the mapped Evm address if any + GetEvmAddress = 0, + /// Get the mapped Evm address if any otheriwse default associated Evm address + GetEvmAddressOrDefault = 1, + /// Get the mapped Native address if any + GetNativeAddress = 2, + /// Get the mapped Native address if any otheriwse default associated Native address + GetNativeAddressOrDefault = 3, +} diff --git a/chain-extensions/unified-accounts/Cargo.toml b/chain-extensions/unified-accounts/Cargo.toml new file mode 100644 index 0000000000..f2ae7ff9e7 --- /dev/null +++ b/chain-extensions/unified-accounts/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "pallet-chain-extension-unified-accounts" +version = "0.1.0" +description = "Chain extension for AU" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +frame-support = { workspace = true } +frame-system = { workspace = true } +log = { workspace = true } +num-traits = { workspace = true } +pallet-contracts = { workspace = true } +pallet-contracts-primitives = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +# Astar +astar-primitives = { workspace = true } +pallet-unified-accounts = { workspace = true } +unified-accounts-chain-extension-types = { workspace = true } + +[features] +default = ["std"] +std = [ + "parity-scale-codec/std", + "frame-support/std", + "frame-system/std", + "num-traits/std", + "pallet-contracts/std", + "pallet-contracts-primitives/std", + "scale-info/std", + "sp-std/std", + "sp-core/std", + "sp-runtime/std", + # Astar + "astar-primitives/std", + "pallet-unified-accounts/std", +] diff --git a/chain-extensions/unified-accounts/src/lib.rs b/chain-extensions/unified-accounts/src/lib.rs new file mode 100644 index 0000000000..4e79cfd179 --- /dev/null +++ b/chain-extensions/unified-accounts/src/lib.rs @@ -0,0 +1,84 @@ +// 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 . + +#![cfg_attr(not(feature = "std"), no_std)] + +use astar_primitives::evm::{EvmAddress, UnifiedAddressMapper}; +use core::marker::PhantomData; +use sp_runtime::DispatchError; + +use frame_support::{traits::Get, DefaultNoBound}; +use pallet_contracts::chain_extension::{ + ChainExtension, Environment, Ext, InitState, Result as DispatchResult, RetVal, +}; +use parity_scale_codec::Encode; +pub use unified_accounts_chain_extension_types::Command::{self, *}; + +#[derive(DefaultNoBound)] +pub struct UnifiedAccountsExtension(PhantomData<(T, UA)>); + +impl ChainExtension for UnifiedAccountsExtension +where + T: pallet_contracts::Config + pallet_unified_accounts::Config, + UA: UnifiedAddressMapper, +{ + fn call(&mut self, env: Environment) -> DispatchResult + where + E: Ext, + { + let mut env = env.buf_in_buf_out(); + match env.func_id().try_into().map_err(|_| { + DispatchError::Other("Unsupported func id in Unified Accounts Chain Extension") + })? { + GetEvmAddress => { + let account_id: T::AccountId = env.read_as()?; + + let base_weight = ::DbWeight::get().reads(1); + env.charge_weight(base_weight)?; + // write to buffer + UA::to_h160(&account_id).using_encoded(|r| env.write(r, false, None))?; + } + GetEvmAddressOrDefault => { + let account_id: T::AccountId = env.read_as()?; + + let base_weight = ::DbWeight::get().reads(1); + env.charge_weight(base_weight)?; + // write to buffer + UA::to_h160_or_default(&account_id).using_encoded(|r| env.write(r, false, None))?; + } + GetNativeAddress => { + let evm_address: EvmAddress = env.read_as()?; + + let base_weight = ::DbWeight::get().reads(1); + env.charge_weight(base_weight)?; + // write to buffer + UA::to_account_id(&evm_address).using_encoded(|r| env.write(r, false, None))?; + } + GetNativeAddressOrDefault => { + let evm_address: EvmAddress = env.read_as()?; + + let base_weight = ::DbWeight::get().reads(1); + env.charge_weight(base_weight)?; + // write to buffer + UA::to_account_id_or_default(&evm_address) + .using_encoded(|r| env.write(r, false, None))?; + } + }; + Ok(RetVal::Converging(0)) + } +} diff --git a/runtime/local/Cargo.toml b/runtime/local/Cargo.toml index 2dc340bcc6..df5e1a3a7e 100644 --- a/runtime/local/Cargo.toml +++ b/runtime/local/Cargo.toml @@ -68,6 +68,7 @@ pallet-transaction-payment-rpc-runtime-api = { workspace = true } astar-primitives = { workspace = true } pallet-block-reward = { workspace = true } pallet-chain-extension-dapps-staking = { workspace = true } +pallet-chain-extension-unified-accounts = { workspace = true } pallet-chain-extension-xvm = { workspace = true } pallet-dapps-staking = { workspace = true } pallet-dynamic-evm-base-fee = { workspace = true } @@ -116,6 +117,7 @@ std = [ "pallet-contracts-primitives/std", "pallet-chain-extension-dapps-staking/std", "pallet-chain-extension-xvm/std", + "pallet-chain-extension-unified-accounts/std", "pallet-dapps-staking/std", "pallet-dynamic-evm-base-fee/std", "pallet-ethereum/std", diff --git a/runtime/local/src/chain_extensions.rs b/runtime/local/src/chain_extensions.rs index 9bd7609c5f..917baff1e2 100644 --- a/runtime/local/src/chain_extensions.rs +++ b/runtime/local/src/chain_extensions.rs @@ -16,13 +16,14 @@ // You should have received a copy of the GNU General Public License // along with Astar. If not, see . -use super::{Runtime, Xvm}; +use super::{Runtime, UnifiedAccounts, Xvm}; /// Registered WASM contracts chain extensions. pub use pallet_chain_extension_assets::AssetsExtension; use pallet_contracts::chain_extension::RegisteredChainExtension; pub use pallet_chain_extension_dapps_staking::DappsStakingExtension; +pub use pallet_chain_extension_unified_accounts::UnifiedAccountsExtension; pub use pallet_chain_extension_xvm::XvmExtension; // Following impls defines chain extension IDs. @@ -40,3 +41,7 @@ impl RegisteredChainExten { const ID: u16 = 02; } + +impl RegisteredChainExtension for UnifiedAccountsExtension { + const ID: u16 = 03; +} diff --git a/runtime/local/src/lib.rs b/runtime/local/src/lib.rs index b372b6bdbf..37020c8644 100644 --- a/runtime/local/src/lib.rs +++ b/runtime/local/src/lib.rs @@ -507,12 +507,18 @@ impl pallet_utility::Config for Runtime { type WeightInfo = pallet_utility::weights::SubstrateWeight; } +parameter_types! { + pub const AccountMappingStorageFee: u128 = deposit(2, 84); +} + impl pallet_unified_accounts::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type DefaultEvmToNative = pallet_evm::HashedAddressMapping; type DefaultNativeToEvm = HashedAccountMapping; + type AccountMappingStorageFee = AccountMappingStorageFee; type ChainId = ChainId; + type WeightInfo = pallet_unified_accounts::weights::SubstrateWeight; } diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 86fbdc5a57..5330385f16 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -97,6 +97,7 @@ orml-xtokens = { workspace = true } astar-primitives = { workspace = true } pallet-block-reward = { workspace = true } pallet-chain-extension-dapps-staking = { workspace = true } +pallet-chain-extension-unified-accounts = { workspace = true } pallet-chain-extension-xvm = { workspace = true } pallet-collator-selection = { workspace = true } pallet-dapps-staking = { workspace = true } @@ -166,6 +167,7 @@ std = [ "pallet-contracts-primitives/std", "pallet-chain-extension-dapps-staking/std", "pallet-chain-extension-xvm/std", + "pallet-chain-extension-unified-accounts/std", "pallet-dynamic-evm-base-fee/std", "pallet-ethereum/std", "pallet-preimage/std", diff --git a/runtime/shibuya/src/chain_extensions.rs b/runtime/shibuya/src/chain_extensions.rs index 9bd7609c5f..917baff1e2 100644 --- a/runtime/shibuya/src/chain_extensions.rs +++ b/runtime/shibuya/src/chain_extensions.rs @@ -16,13 +16,14 @@ // You should have received a copy of the GNU General Public License // along with Astar. If not, see . -use super::{Runtime, Xvm}; +use super::{Runtime, UnifiedAccounts, Xvm}; /// Registered WASM contracts chain extensions. pub use pallet_chain_extension_assets::AssetsExtension; use pallet_contracts::chain_extension::RegisteredChainExtension; pub use pallet_chain_extension_dapps_staking::DappsStakingExtension; +pub use pallet_chain_extension_unified_accounts::UnifiedAccountsExtension; pub use pallet_chain_extension_xvm::XvmExtension; // Following impls defines chain extension IDs. @@ -40,3 +41,7 @@ impl RegisteredChainExten { const ID: u16 = 02; } + +impl RegisteredChainExtension for UnifiedAccountsExtension { + const ID: u16 = 03; +} diff --git a/runtime/shibuya/src/lib.rs b/runtime/shibuya/src/lib.rs index 16aa3b0209..2cc06c9c6f 100644 --- a/runtime/shibuya/src/lib.rs +++ b/runtime/shibuya/src/lib.rs @@ -1204,7 +1204,6 @@ impl pallet_xc_asset_config::Config for Runtime { } parameter_types! { - /// pub const AccountMappingStorageFee: u128 = deposit(2, 84); }