Skip to content

Commit

Permalink
A0-3393: add proxy to runtime (#1484)
Browse files Browse the repository at this point in the history
# Description

Add pallet proxy to runtime with 3 proxy type available:
* Any - proxy can make any call
* Staking - proxy can make calls related to staking (bond, nominate etc)
* Nontrasfer - calls that do not make any transfer of funds

## Type of change

Please delete options that are not relevant.

- New feature (non-breaking change which adds functionality)

# Checklist:

<!-- delete when not applicable to your PR -->

- I have added tests
  • Loading branch information
kostekIV authored Nov 29, 2023
1 parent 496599b commit 4db27b0
Show file tree
Hide file tree
Showing 11 changed files with 3,420 additions and 609 deletions.
42 changes: 42 additions & 0 deletions .github/workflows/_run-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -534,3 +534,45 @@ jobs:
test-case: committee_split::split_test_success_with_all_non_reserved_dead
follow-up-finalization-check: true
node-count: 7

run-e2e-any-proxy:
name: Run any proxy test
needs: [run-e2e-finalization-test]
runs-on: ubuntu-20.04
steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Run e2e test
uses: ./.github/actions/run-e2e-test
with:
test-case: any_proxy_works
follow-up-finalization-check: true

run-e2e-staking-proxy:
name: Run staking proxy test
needs: [run-e2e-finalization-test]
runs-on: ubuntu-20.04
steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Run e2e test
uses: ./.github/actions/run-e2e-test
with:
test-case: staking_proxy_works
follow-up-finalization-check: true

run-e2e-non-transfer-proxy:
name: Run non-transfer proxy test
needs: [run-e2e-finalization-test]
runs-on: ubuntu-20.04
steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Run e2e test
uses: ./.github/actions/run-e2e-test
with:
test-case: non_transfer_proxy_works
follow-up-finalization-check: true
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/Cardina
pallet-treasury = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0", default-features = false }
pallet-utility = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0", default-features = false }
pallet-vesting = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0", default-features = false }
pallet-proxy = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0", default-features = false }

sc-basic-authorship = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0" }
sc-block-builder = { git = "https://github.com/Cardinal-Cryptography/polkadot-sdk.git", branch = "aleph-v1.2.0" }
Expand Down
1,766 changes: 1,461 additions & 305 deletions aleph-client/src/aleph_zero.rs

Large diffs are not rendered by default.

1,763 changes: 1,462 additions & 301 deletions aleph-client/src/aleph_zero_liminal.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions aleph-client/src/pallets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub mod elections;
pub mod fee;
/// Pallet multisig API
pub mod multisig;
/// Pallet Proxy API
pub mod proxy;
/// Pallet session API
pub mod session;
/// Pallet staking API
Expand Down
79 changes: 79 additions & 0 deletions aleph-client/src/pallets/proxy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use subxt::utils::MultiAddress;

use crate::{
aleph_runtime::{ProxyType, RuntimeCall},
api, AccountId, SignedConnectionApi, TxInfo, TxStatus,
};

/// any object that implements pallet proxy api
#[async_trait::async_trait]
pub trait ProxyUserApi {
/// API for [`proxy`](https://paritytech.github.io/polkadot-sdk/master/pallet_proxy/pallet/struct.Pallet.html#method.proxy) call.
async fn proxy(
&self,
real: AccountId,
call: RuntimeCall,
status: TxStatus,
) -> anyhow::Result<TxInfo>;

/// API for [`add_proxy`](https://paritytech.github.io/polkadot-sdk/master/pallet_proxy/pallet/struct.Pallet.html#method.add_proxy) call.
async fn add_proxy(
&self,
delegate: AccountId,
proxy_type: ProxyType,
delay: u32,
status: TxStatus,
) -> anyhow::Result<TxInfo>;

/// API for [`remove_proxy`](https://paritytech.github.io/polkadot-sdk/master/pallet_proxy/pallet/struct.Pallet.html#method.remove_proxy) call.
async fn remove_proxy(
&self,
delegate: AccountId,
proxy_type: ProxyType,
delay: u32,
status: TxStatus,
) -> anyhow::Result<TxInfo>;
}

#[async_trait::async_trait]
impl<S: SignedConnectionApi> ProxyUserApi for S {
async fn proxy(
&self,
real: AccountId,
call: RuntimeCall,
status: TxStatus,
) -> anyhow::Result<TxInfo> {
let tx = api::tx()
.proxy()
.proxy(MultiAddress::Id(real.into()), None, call);

self.send_tx(tx, status).await
}
async fn add_proxy(
&self,
delegate: AccountId,
proxy_type: ProxyType,
delay: u32,
status: TxStatus,
) -> anyhow::Result<TxInfo> {
let tx = api::tx()
.proxy()
.add_proxy(MultiAddress::Id(delegate.into()), proxy_type, delay);

self.send_tx(tx, status).await
}
async fn remove_proxy(
&self,
delegate: AccountId,
proxy_type: ProxyType,
delay: u32,
status: TxStatus,
) -> anyhow::Result<TxInfo> {
let tx =
api::tx()
.proxy()
.remove_proxy(MultiAddress::Id(delegate.into()), proxy_type, delay);

self.send_tx(tx, status).await
}
}
3 changes: 3 additions & 0 deletions bin/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pallet-aleph = { workspace = true }
pallet-committee-management= { workspace = true }
pallet-elections = { workspace = true }
primitives = { workspace = true }
pallet-proxy = { workspace = true }

# Liminal-related dependencies
baby-liminal-extension = { workspace = true, features = ["runtime"], optional = true }
Expand Down Expand Up @@ -97,6 +98,7 @@ std = [
"pallet-treasury/std",
"pallet-vesting/std",
"pallet-multisig/std",
"pallet-proxy/std",
"pallet-utility/std",
"sp-api/std",
"sp-block-builder/std",
Expand Down Expand Up @@ -148,6 +150,7 @@ try-runtime = [
"pallet-multisig/try-runtime",
"pallet-utility/try-runtime",
"pallet-committee-management/try-runtime",
"pallet-proxy/try-runtime"
]
enable_treasury_proposals = []
runtime-benchmarks = [
Expand Down
97 changes: 94 additions & 3 deletions bin/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ pub use frame_support::{
use frame_support::{
sp_runtime::Perquintill,
traits::{
ConstBool, ConstU32, EqualPrivilegeOnly, EstimateNextSessionRotation, SortedMembers,
WithdrawReasons,
ConstBool, ConstU32, EqualPrivilegeOnly, EstimateNextSessionRotation, InstanceFilter,
SortedMembers, WithdrawReasons,
},
weights::constants::WEIGHT_REF_TIME_PER_MILLIS,
PalletId,
Expand All @@ -37,6 +37,7 @@ use pallet_committee_management::SessionAndEraManager;
use pallet_session::QueuedKeys;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use primitives::{
staking::MAX_NOMINATORS_REWARDED_PER_VALIDATOR, wrap_methods, ApiError as AlephApiError,
AuraId, AuthorityId as AlephId, Block as AlephBlock, BlockId as AlephBlockId,
Expand All @@ -58,7 +59,7 @@ use sp_runtime::{
AccountIdLookup, BlakeTwo256, Block as BlockT, Bounded, ConvertInto, One, OpaqueKeys,
},
transaction_validity::{TransactionSource, TransactionValidity},
ApplyExtrinsicResult, FixedU128,
ApplyExtrinsicResult, FixedU128, RuntimeDebug,
};
pub use sp_runtime::{FixedPointNumber, Perbill, Permill};
use sp_staking::{currency_to_vote::U128CurrencyToVote, EraIndex};
Expand Down Expand Up @@ -765,6 +766,94 @@ impl pallet_identity::Config for Runtime {
type RegistrarOrigin = EnsureRoot<AccountId>;
type WeightInfo = pallet_identity::weights::SubstrateWeight<Self>;
}
parameter_types! {
// Key size = 32, value size = 8
pub const ProxyDepositBase: Balance = 40 * LEGACY_DEPOSIT_PER_BYTE;
// One storage item (32) plus `ProxyType` (1) encode len.
pub const ProxyDepositFactor: Balance = 33 * LEGACY_DEPOSIT_PER_BYTE;
// Key size = 32, value size 8
pub const AnnouncementDepositBase: Balance = 40 * LEGACY_DEPOSIT_PER_BYTE;
// AccountId, Hash and BlockNumber sum up to 68
pub const AnnouncementDepositFactor: Balance = 68 * LEGACY_DEPOSIT_PER_BYTE;
}
#[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Encode,
Decode,
RuntimeDebug,
MaxEncodedLen,
scale_info::TypeInfo,
)]
pub enum ProxyType {
Any = 0,
NonTransfer = 1,
Staking = 2,
}
impl Default for ProxyType {
fn default() -> Self {
Self::Any
}
}
impl InstanceFilter<RuntimeCall> for ProxyType {
fn filter(&self, c: &RuntimeCall) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => matches!(
c,
RuntimeCall::Staking(..)
| RuntimeCall::Session(..)
| RuntimeCall::Treasury(..)
| RuntimeCall::Vesting(pallet_vesting::Call::vest { .. })
| RuntimeCall::Vesting(pallet_vesting::Call::vest_other { .. })
| RuntimeCall::Vesting(pallet_vesting::Call::merge_schedules { .. })
| RuntimeCall::Utility(..)
| RuntimeCall::Multisig(..)
| RuntimeCall::NominationPools(..)
| RuntimeCall::Identity(..)
),
ProxyType::Staking => {
matches!(
c,
RuntimeCall::Staking(..)
| RuntimeCall::Session(..)
| RuntimeCall::Utility(..)
| RuntimeCall::NominationPools(..)
)
}
}
}
fn is_superset(&self, o: &Self) -> bool {
// ProxyType::Staking ⊆ ProxyType::NonTransfer ⊆ ProxyType::Any
match (self, o) {
(ProxyType::Any, _) => true,
(_, ProxyType::Any) => false,
(ProxyType::NonTransfer, ProxyType::Staking) => true,
(ProxyType::Staking, ProxyType::NonTransfer) => false,
(ProxyType::Staking, ProxyType::Staking) => true,
(ProxyType::NonTransfer, ProxyType::NonTransfer) => true,
}
}
}

impl pallet_proxy::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type ProxyType = ProxyType;
type ProxyDepositBase = ProxyDepositBase;
type ProxyDepositFactor = ProxyDepositFactor;
type MaxProxies = ConstU32<32>;
type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
type MaxPending = ConstU32<32>;
type CallHasher = BlakeTwo256;
type AnnouncementDepositBase = AnnouncementDepositBase;
type AnnouncementDepositFactor = AnnouncementDepositFactor;
}

// Create the runtime by composing the FRAME pallets that were previously configured.
#[cfg(not(feature = "liminal"))]
Expand Down Expand Up @@ -792,6 +881,7 @@ construct_runtime!(
NominationPools: pallet_nomination_pools,
Identity: pallet_identity,
CommitteeManagement: pallet_committee_management,
Proxy: pallet_proxy,
}
);

Expand Down Expand Up @@ -821,6 +911,7 @@ construct_runtime!(
Identity: pallet_identity,
CommitteeManagement: pallet_committee_management,
BabyLiminal: pallet_baby_liminal,
Proxy: pallet_proxy,
}
);

Expand Down
1 change: 1 addition & 0 deletions e2e-tests/src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod finalization;
mod helpers;
mod high_latency;
mod lenient_threshold;
mod proxy;
mod rewards;
mod staking;
mod sync;
Expand Down
Loading

0 comments on commit 4db27b0

Please sign in to comment.