Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Runtime] Enable feeless, walletless transactions on selected accounts #428

Merged
merged 12 commits into from
Oct 30, 2024
Merged
Changes from all commits
Commits
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
516 changes: 339 additions & 177 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -50,9 +50,14 @@ kusama-runtime-constants = { default-features = false, path = "runtime/kusama-ru
runtime-common = { default-features = false, path = "runtime/common" }

# Frame Contrib
fc-traits-memberships = { git = "https://github.com/virto-network/frame-contrib", branch = "main", default-features = false }
fc-traits-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "main", default-features = false }
pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", branch = "main", package = "fc-pallet-referenda-tracks", default-features = false }
fc-traits-authn = { git = "https://github.com/virto-network/frame-contrib", default-features = false }
fc-traits-gas-tank = { git = "https://github.com/virto-network/frame-contrib", default-features = false }
fc-traits-memberships = { git = "https://github.com/virto-network/frame-contrib", default-features = false }
fc-traits-tracks = { git = "https://github.com/virto-network/frame-contrib", default-features = false }
pallet-gas-transaction-payment = { git = "https://github.com/virto-network/frame-contrib", package = "fc-pallet-gas-transaction-payment", default-features = false }
pallet-pass = { git = "https://github.com/virto-network/frame-contrib", package = "fc-pallet-pass", default-features = false }
pallet-referenda-tracks = { git = "https://github.com/virto-network/frame-contrib", package = "fc-pallet-referenda-tracks", default-features = false }
pass-webauthn = { git = "https://github.com/virto-network/webauthn", default-features = false }

# Substrate std
pallet-transaction-payment-rpc = { git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
@@ -113,6 +118,7 @@ pallet-referenda = { default-features = false, git = "https://github.com/virto-n
pallet-remark = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-scheduler = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-session = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-skip-feeless-payment = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-sudo = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-timestamp = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
pallet-transaction-payment = { default-features = false, git = "https://github.com/virto-network/polkadot-sdk", branch = "release-virto-stable2409" }
2 changes: 1 addition & 1 deletion chain-spec-generator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ homepage.workspace = true
license.workspace = true
name = "chain-spec-generator"
repository.workspace = true
version = "0.13.3"
version = "0.14.0"

[dependencies]
clap = { workspace = true, features = ["derive"] }
Original file line number Diff line number Diff line change
@@ -6,8 +6,8 @@
"telemetryEndpoints": null,
"protocolId": "kreivo",
"properties": {
"ss58Format": 42,
"tokenDecimals": 12,
"ss58Format": 1,
"tokenDecimals": 10,
"tokenSymbol": "PAS"
},
"relay_chain": "paseo",
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ bump mode="minor":
#!/usr/bin/env nu
let ver = '{{ ver }}' | inc --{{ mode }}
open -r runtime/kreivo/Cargo.toml | str replace -m '^version = "(.+)"$' $'version = "($ver)"' | save -f runtime/kreivo/Cargo.toml
open -r node/Cargo.toml | str replace -m '^version = "(.+)"$' $'version = "($ver)"' | save -f node/Cargo.toml
open -r chain-spec-generator/Cargo.toml | str replace -m '^version = "(.+)"$' $'version = "($ver)"' | save -f chain-spec-generator/Cargo.toml
# bump spec version
const SRC = 'runtime/kreivo/src/lib.rs'
let src = open $SRC
22 changes: 21 additions & 1 deletion runtime/kreivo/Cargo.toml
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ homepage.workspace = true
license.workspace = true
name = "kreivo-runtime"
repository.workspace = true
version = "0.13.3"
version = "0.14.0"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
@@ -56,6 +56,7 @@ pallet-ranked-collective.workspace = true
pallet-referenda.workspace = true
pallet-scheduler.workspace = true
pallet-session.workspace = true
pallet-skip-feeless-payment.workspace = true
pallet-sudo.workspace = true
pallet-timestamp.workspace = true
pallet-transaction-payment.workspace = true
@@ -105,8 +106,13 @@ parachain-info.workspace = true
parachains-common.workspace = true

# Frame Contrib
fc-traits-authn.workspace = true
fc-traits-gas-tank.workspace = true
fc-traits-memberships.workspace = true
pallet-gas-transaction-payment.workspace = true
pallet-pass.workspace = true
pallet-referenda-tracks.workspace = true
pass-webauthn = { workspace = true, features = ["runtime"] }

[features]
default = ["std"]
@@ -129,6 +135,8 @@ std = [
"frame-system-rpc-runtime-api/std",
"frame-try-runtime/std",
"frame-system/std",
"fc-traits-authn/std",
"fc-traits-gas-tank/std",
"fc-traits-memberships/std",
"log/std",
"kusama-runtime-constants/std",
@@ -142,9 +150,11 @@ std = [
"pallet-communities-manager/std",
"pallet-communities/std",
"pallet-collator-selection/std",
"pallet-gas-transaction-payment/std",
"pallet-message-queue/std",
"pallet-multisig/std",
"pallet-nfts/std",
"pallet-pass/std",
"pallet-payments/std",
"pallet-preimage/std",
"pallet-proxy/std",
@@ -153,6 +163,7 @@ std = [
"pallet-referenda-tracks/std",
"pallet-scheduler/std",
"pallet-session/std",
"pallet-skip-feeless-payment/std",
"pallet-sudo/std",
"pallet-timestamp/std",
"pallet-transaction-payment-rpc-runtime-api/std",
@@ -164,6 +175,7 @@ std = [
"parachain-info/std",
"parachains-common/std",
"parity-scale-codec/std",
"pass-webauthn/std",
"polkadot-core-primitives/std",
"polkadot-parachain-primitives/std",
"polkadot-runtime-common/std",
@@ -209,22 +221,26 @@ runtime-benchmarks = [
"pallet-communities-manager/runtime-benchmarks",
"pallet-communities/runtime-benchmarks",
"pallet-collator-selection/runtime-benchmarks",
"pallet-gas-transaction-payment/runtime-benchmarks",
"pallet-message-queue/runtime-benchmarks",
"pallet-multisig/runtime-benchmarks",
"pallet-nfts/runtime-benchmarks",
"pallet-payments/runtime-benchmarks",
"pallet-pass/runtime-benchmarks",
"pallet-preimage/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
"pallet-ranked-collective/runtime-benchmarks",
"pallet-referenda/runtime-benchmarks",
"pallet-referenda-tracks/runtime-benchmarks",
"pallet-scheduler/runtime-benchmarks",
"pallet-skip-feeless-payment/runtime-benchmarks",
"pallet-sudo/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-treasury/runtime-benchmarks",
"pallet-utility/runtime-benchmarks",
"pallet-xcm-benchmarks/runtime-benchmarks",
"pallet-xcm/runtime-benchmarks",
"pass-webauthn/runtime-benchmarks",
"parachains-common/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-runtime-common/runtime-benchmarks",
@@ -254,9 +270,11 @@ try-runtime = [
"pallet-communities-manager/try-runtime",
"pallet-communities/try-runtime",
"pallet-collator-selection/try-runtime",
"pallet-gas-transaction-payment/try-runtime",
"pallet-message-queue/try-runtime",
"pallet-nfts/try-runtime",
"pallet-multisig/try-runtime",
"pallet-pass/try-runtime",
"pallet-payments/try-runtime",
"pallet-preimage/try-runtime",
"pallet-proxy/try-runtime",
@@ -265,12 +283,14 @@ try-runtime = [
"pallet-referenda-tracks/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-session/try-runtime",
"pallet-skip-feeless-payment/try-runtime",
"pallet-sudo/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-treasury/try-runtime",
"pallet-utility/try-runtime",
"pallet-xcm/try-runtime",
"pass-webauthn/try-runtime",
"parachain-info/try-runtime",
"polkadot-runtime-common/try-runtime",
"runtime-common/try-runtime",
12 changes: 12 additions & 0 deletions runtime/kreivo/src/configuration/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Configure FRAME pallets to include in runtime.

use super::*;

pub mod monetary_stuff;
pub mod system_support;

pub use monetary_stuff::{
ExistentialDeposit, KreivoAssetsCall, KreivoAssetsInstance, MetadataDepositBase, MetadataDepositPerByte,
TransactionByteFee,
};
pub use system_support::RuntimeBlockWeights;
142 changes: 142 additions & 0 deletions runtime/kreivo/src/configuration/monetary_stuff.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use super::*;

use fc_traits_gas_tank::NonFungibleGasBurner;

use pallet_asset_tx_payment::FungiblesAdapter;
use pallet_assets::BalanceToAssetBalance;
use pallet_transaction_payment::FungibleAdapter;
use runtime_common::impls::AssetsToBlockAuthor;

// #[runtime::pallet_index(10)]
// pub type Balances
parameter_types! {
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
}

impl pallet_balances::Config for Runtime {
type MaxLocks = ConstU32<50>;
/// The type for recording an account's balance.
type Balance = Balance;
/// The ubiquitous event type.
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<256>;
type RuntimeFreezeReason = RuntimeFreezeReason;
}

// #[runtime::pallet_index(11)]
// pub type TransactionPayment
parameter_types! {
/// Relay Chain `TransactionByteFee` / 10
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}

impl pallet_transaction_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnChargeTransaction = FungibleAdapter<Balances, ResolveTo<TreasuryAccount, Balances>>;
type WeightToFee = WeightToFee;
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
type OperationalFeeMultiplier = ConstU8<5>;
}

// #[runtime::pallet_index(12)]
// pub type AssetsFreezer
impl pallet_assets_freezer::Config<KreivoAssetsInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeFreezeReason = RuntimeFreezeReason;
}

// #[runtime::pallet_index(13)]
// pub type Assets
parameter_types! {
pub const AssetDeposit: Balance = UNITS / 10; // 1 / 10 UNITS deposit to create asset
pub const AssetAccountDeposit: Balance = deposit(1, 16);
pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
pub const AssetsStringLimit: u32 = 50;
/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
pub const MetadataDepositBase: Balance = deposit(1, 68);
pub const MetadataDepositPerByte: Balance = deposit(0, 1);
}

/// We allow root to execute privileged asset operations.
pub type AssetsForceOrigin = EnsureRoot<AccountId>;
pub type KreivoAssetsInstance = pallet_assets::Instance1;
pub type KreivoAssetsCall = pallet_assets::Call<Runtime, KreivoAssetsInstance>;

impl pallet_assets::Config<KreivoAssetsInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type AssetId = FungibleAssetLocation;
type AssetIdParameter = FungibleAssetLocation;
type Currency = Balances;
/// Only root can create assets and force state changes.
type CreateOrigin = AsEnsureOriginWithArg<NeverEnsureOrigin<AccountId>>;
type ForceOrigin = AssetsForceOrigin;
type AssetDeposit = AssetDeposit;
type MetadataDepositBase = MetadataDepositBase;
type MetadataDepositPerByte = MetadataDepositPerByte;
type ApprovalDeposit = ApprovalDeposit;
type StringLimit = AssetsStringLimit;
type Freezer = AssetsFreezer;
type Extra = ();
type WeightInfo = weights::pallet_assets::WeightInfo<Runtime>;
type CallbackHandle = ();
type AssetAccountDeposit = AssetAccountDeposit;
type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
type MaxHolds = frame_support::traits::ConstU32<50>;
type RuntimeHoldReason = RuntimeHoldReason;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}

// #[runtime::pallet_index(14)]
// pub type AssetsTxPayment
impl pallet_asset_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Fungibles = Assets;
type OnChargeAssetTransaction = FungiblesAdapter<
BalanceToAssetBalance<Balances, Runtime, ConvertInto, KreivoAssetsInstance>,
AssetsToBlockAuthor<Runtime, KreivoAssetsInstance>,
>;
}

// #[runtime::pallet_index(15)]
// pub type Vesting
parameter_types! {
pub const MinVestedTransfer: Balance = 100 * CENTS;
pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
}

impl pallet_vesting::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type BlockNumberToBalance = ConvertInto;
type MinVestedTransfer = MinVestedTransfer;
type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
type BlockNumberProvider = System;
const MAX_VESTING_SCHEDULES: u32 = 28;
}

// #[runtime::pallet_index(16)]
// pub type SkipFeeless
impl pallet_skip_feeless_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

// #[runtime::pallet_index(17)]
// pub type GasTxPayment
impl pallet_gas_transaction_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type GasBurner = NonFungibleGasBurner<Runtime, CommunityMemberships, pallet_nfts::ItemConfig>;
}
243 changes: 243 additions & 0 deletions runtime/kreivo/src/configuration/system_support.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
//! System support stuff.
use fc_traits_authn::{composite_authenticator, util::AuthorityFromPalletId, Challenge, Challenger};
use frame_support::{traits::EnsureOrigin, PalletId};
use frame_system::EnsureRootWithSuccess;
use pallet_communities::origin::AsSignedByCommunity;
use polkadot_core_primitives::HashT;

use super::*;

// #[runtime::pallet_index(0)]
// pub type System
parameter_types! {
pub const Version: RuntimeVersion = VERSION;

// This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
// The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
// `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
// the lazy contract deletion.
pub RuntimeBlockLength: BlockLength =
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
.base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = ExtrinsicBaseWeight::get();
})
.for_class(DispatchClass::Normal, |weights| {
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
})
.for_class(DispatchClass::Operational, |weights| {
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
// Operational transactions have some extra reserved space, so that they
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
weights.reserved = Some(
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
);
})
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic();
pub const SS58Prefix: u16 = 2;
}

pub struct CommunityLookup;
impl StaticLookup for CommunityLookup {
type Source = Address;
type Target = AccountId;
fn lookup(s: Self::Source) -> Result<Self::Target, LookupError> {
match s {
MultiAddress::Id(i) => Ok(i),
MultiAddress::Index(i) => Ok(Communities::community_account(&i)),
_ => Err(LookupError),
}
}
fn unlookup(t: Self::Target) -> Self::Source {
MultiAddress::Id(t)
}
}

#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)]
impl frame_system::Config for Runtime {
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
type Lookup = CommunityLookup;
/// The type for hashing blocks and tries.
type Hash = Hash;
type Block = Block;
type Nonce = Nonce;
/// Maximum number of block number to block hash mappings to keep (oldest
/// pruned first).
type BlockHashCount = BlockHashCount;
/// Runtime version.
type Version = Version;
/// The data to be stored in an account.
type AccountData = pallet_balances::AccountData<Balance>;
/// The weight of database operations that the runtime can invoke.
type DbWeight = RocksDbWeight;
/// Block & extrinsics weights: base values and limits.
type BlockWeights = RuntimeBlockWeights;
/// The maximum length of a block (in bytes).
type BlockLength = RuntimeBlockLength;
/// This is used as an identifier of the chain. 42 is the generic substrate
/// prefix.
type SS58Prefix = SS58Prefix;
/// The action to take on a Runtime Upgrade
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

// #[runtime::pallet_index(1)]
// pub type ParachainSystem
parameter_types! {
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
}

impl cumulus_pallet_parachain_system::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
type SelfParaId = parachain_info::Pallet<Runtime>;
type OutboundXcmpMessageSource = XcmpQueue;
type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
type ReservedDmpWeight = ReservedDmpWeight;
type XcmpMessageHandler = XcmpQueue;
type ReservedXcmpWeight = ReservedXcmpWeight;
type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
type ConsensusHook = ConsensusHook;
}

// #[runtime::pallet_index(2)]
// pub type Timestamp
impl pallet_timestamp::Config for Runtime {
/// A timestamp: milliseconds since the unix epoch.
type Moment = u64;
type OnTimestampSet = Aura;
type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
type WeightInfo = ();
}

// #[runtime::pallet_index(3)]
// pub type ParachainInfo
impl parachain_info::Config for Runtime {}

// #[runtime::pallet_index(4)]
// pub type Origins
impl pallet_custom_origins::Config for Runtime {}

// #[runtime::pallet_index(6)]
// pub type Pass
parameter_types! {
pub PassPalletId: PalletId = PalletId(*b"kreivo_p");
pub NeverPays: Option<pallet_pass::DepositInformation<Runtime>> = None;
}

pub struct UnincludedBlockChallenger;

impl Challenger for UnincludedBlockChallenger {
type Context = BlockNumber;

fn check_challenge(cx: &Self::Context, challenge: &[u8]) -> Option<()> {
(*cx >= System::block_number().saturating_sub(3)).then_some(())?;
Self::generate(cx).eq(challenge).then_some(())
}

fn generate(cx: &Self::Context) -> Challenge {
BlakeTwo256::hash(&cx.to_le_bytes()).0
}
}

pub type WebAuthn = pass_webauthn::Authenticator<UnincludedBlockChallenger, AuthorityFromPalletId<PassPalletId>>;
pub type Dummy = fc_traits_authn::util::dummy::Dummy<AuthorityFromPalletId<PassPalletId>>;

#[cfg(not(feature = "runtime-benchmarks"))]
composite_authenticator!(
pub Pass<AuthorityFromPalletId<PassPalletId>> {
WebAuthn,
}
);

#[cfg(feature = "runtime-benchmarks")]
composite_authenticator!(
pub Pass<AuthorityFromPalletId<PassPalletId>> {
WebAuthn,
Dummy,
}
);

/// Communities don't need to pay deposit fees to create a `pass` account
pub struct CommunitiesDontDeposit;

impl<OuterOrigin> EnsureOriginWithArg<OuterOrigin, HashedUserId> for CommunitiesDontDeposit
where
OuterOrigin: frame_support::traits::OriginTrait
+ From<frame_system::RawOrigin<AccountId>>
+ From<pallet_communities::Origin<Runtime>>
+ Clone
+ Into<Result<frame_system::RawOrigin<AccountId>, OuterOrigin>>
+ Into<Result<pallet_communities::Origin<Runtime>, OuterOrigin>>,
{
type Success = Option<pallet_pass::DepositInformation<Runtime>>;

fn try_origin(o: OuterOrigin, _: &HashedUserId) -> Result<Self::Success, OuterOrigin> {
AsSignedByCommunity::<Runtime>::try_origin(o)?;
Ok(None)
}

#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin(_: &HashedUserId) -> Result<OuterOrigin, ()> {
use pallet_communities::BenchmarkHelper;
let community_id = crate::communities::CommunityBenchmarkHelper::community_id();
Ok(
frame_system::RawOrigin::Signed(pallet_communities::Pallet::<Runtime>::community_account(&community_id))
.into(),
)
}
}

impl pallet_pass::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type WeightInfo = pallet_pass::SubstrateWeight<Self>;
type Authenticator = PassAuthenticator; // WebAuthn;
type PalletsOrigin = OriginCaller;
type PalletId = PassPalletId;
type MaxSessionDuration = ConstU32<{ 15 * MINUTES }>;
type RegisterOrigin = EitherOf<
// Root never pays
EnsureRootWithSuccess<Self::AccountId, NeverPays>,
EitherOf<
// // Communities never pay
CommunitiesDontDeposit,
// Signed users must deposit ED for creating a pass account
pallet_pass::EnsureSignedPays<
Runtime,
<Runtime as pallet_balances::Config>::ExistentialDeposit,
TreasuryAccount,
>,
>,
>;

#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = PassBenchmarkHelper;
}

#[cfg(feature = "runtime-benchmarks")]
pub struct PassBenchmarkHelper;

#[cfg(feature = "runtime-benchmarks")]
impl pallet_pass::BenchmarkHelper<Runtime> for PassBenchmarkHelper {
fn register_origin() -> frame_system::pallet_prelude::OriginFor<Runtime> {
RuntimeOrigin::root()
}

fn device_attestation(_: fc_traits_authn::DeviceId) -> pallet_pass::DeviceAttestationOf<Runtime, ()> {
PassDeviceAttestation::Dummy(fc_traits_authn::util::dummy::DummyAttestation::new(true))
}

fn credential(_: HashedUserId) -> pallet_pass::CredentialOf<Runtime, ()> {
PassCredential::Dummy(fc_traits_authn::util::dummy::DummyCredential::new(true))
}
}
259 changes: 19 additions & 240 deletions runtime/kreivo/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,13 +11,16 @@ include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
mod tests;

pub mod apis;
pub mod configuration;
pub mod constants;
pub mod contracts;
pub mod governance;
pub mod impls;
mod weights;
pub mod xcm_config;

pub use configuration::*;

use apis::*;
use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
@@ -86,6 +89,11 @@ pub mod payments;

pub mod communities;

use pallet_asset_tx_payment::ChargeAssetTxPayment;
use pallet_gas_transaction_payment::ChargeTransactionPayment as ChargeGasTxPayment;
use pallet_pass::ChargeTransactionToPassAccount as ChargeTxToPassAccount;
use pallet_skip_feeless_payment::SkipCheckIfFeeless;

// XCM Imports
use xcm::latest::prelude::BodyId;

@@ -99,7 +107,6 @@ pub use parachains_common::{
opaque, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, Hash, Header, Nonce, Signature,
AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, MAXIMUM_BLOCK_WEIGHT, MINUTES, NORMAL_DISPATCH_RATIO, SLOT_DURATION,
};
pub use runtime_common::impls::AssetsToBlockAuthor;

/// The address format for describing accounts.
pub type Address = MultiAddress<AccountId, CommunityId>;
@@ -113,6 +120,8 @@ pub type SignedBlock = generic::SignedBlock<Block>;
/// BlockId type as expected by this runtime.
pub type BlockId = generic::BlockId<Block>;

pub type ChargeTransaction = ChargeGasTxPayment<Runtime, ChargeAssetTxPayment<Runtime>>;

/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
@@ -122,7 +131,7 @@ pub type SignedExtra = (
frame_system::CheckEra<Runtime>,
frame_system::CheckNonce<Runtime>,
frame_system::CheckWeight<Runtime>,
pallet_asset_tx_payment::ChargeAssetTxPayment<Runtime>,
SkipCheckIfFeeless<Runtime, ChargeTxToPassAccount<ChargeTransaction, Runtime, ()>>,
);

/// Unchecked extrinsic type as expected by this runtime.
@@ -148,10 +157,10 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("kreivo-parachain"),
impl_name: create_runtime_str!("kreivo-parachain"),
authoring_version: 1,
spec_version: 111,
spec_version: 112,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 8,
transaction_version: 9,
state_version: 1,
};

@@ -192,11 +201,8 @@ mod runtime {
pub type ParachainInfo = parachain_info;
#[runtime::pallet_index(4)]
pub type Origins = pallet_custom_origins;
#[cfg(feature = "paseo")]
mod paseo {
#[runtime::pallet_index(5)]
pub type Sudo = pallet_sudo;
}
#[runtime::pallet_index(6)]
pub type Pass = pallet_pass;

// Monetary stuff.
#[runtime::pallet_index(10)]
@@ -211,6 +217,10 @@ mod runtime {
pub type AssetsTxPayment = pallet_asset_tx_payment;
#[runtime::pallet_index(15)]
pub type Vesting = pallet_vesting;
#[runtime::pallet_index(16)]
pub type SkipFeeless = pallet_skip_feeless_payment;
#[runtime::pallet_index(17)]
pub type GasTxPayment = pallet_gas_transaction_payment;

// Collator support. The order of these 4 are important and shall not change.
#[runtime::pallet_index(20)]
@@ -275,146 +285,11 @@ mod runtime {
pub type Contracts = pallet_contracts;
}

parameter_types! {
pub const Version: RuntimeVersion = VERSION;

// This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
// The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
// `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
// the lazy contract deletion.
pub RuntimeBlockLength: BlockLength =
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
.base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = ExtrinsicBaseWeight::get();
})
.for_class(DispatchClass::Normal, |weights| {
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
})
.for_class(DispatchClass::Operational, |weights| {
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
// Operational transactions have some extra reserved space, so that they
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
weights.reserved = Some(
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
);
})
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic();
pub const SS58Prefix: u16 = 2;
}

#[cfg(feature = "paseo")]
mod paseo {
use super::{Runtime, RuntimeCall, RuntimeEvent};

impl pallet_sudo::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = pallet_sudo::weights::SubstrateWeight<Self>;
}
}

impl pallet_custom_origins::Config for Runtime {}

pub struct CommunityLookup;
impl StaticLookup for CommunityLookup {
type Source = Address;
type Target = AccountId;
fn lookup(s: Self::Source) -> Result<Self::Target, LookupError> {
match s {
MultiAddress::Id(i) => Ok(i),
MultiAddress::Index(i) => Ok(Communities::community_account(&i)),
_ => Err(LookupError),
}
}
fn unlookup(t: Self::Target) -> Self::Source {
MultiAddress::Id(t)
}
}

// Configure FRAME pallets to include in runtime.
#[derive_impl(frame_system::config_preludes::ParaChainDefaultConfig as frame_system::DefaultConfig)]
impl frame_system::Config for Runtime {
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
type Lookup = CommunityLookup;
/// The type for hashing blocks and tries.
type Hash = Hash;
type Block = Block;
type Nonce = Nonce;
/// Maximum number of block number to block hash mappings to keep (oldest
/// pruned first).
type BlockHashCount = BlockHashCount;
/// Runtime version.
type Version = Version;
/// The data to be stored in an account.
type AccountData = pallet_balances::AccountData<Balance>;
/// The weight of database operations that the runtime can invoke.
type DbWeight = RocksDbWeight;
/// Block & extrinsics weights: base values and limits.
type BlockWeights = RuntimeBlockWeights;
/// The maximum length of a block (in bytes).
type BlockLength = RuntimeBlockLength;
/// This is used as an identifier of the chain. 42 is the generic substrate
/// prefix.
type SS58Prefix = SS58Prefix;
/// The action to take on a Runtime Upgrade
type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode<Self>;
type MaxConsumers = frame_support::traits::ConstU32<16>;
}

impl pallet_timestamp::Config for Runtime {
/// A timestamp: milliseconds since the unix epoch.
type Moment = u64;
type OnTimestampSet = Aura;
type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>;
type WeightInfo = ();
}

impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Aura>;
type EventHandler = (CollatorSelection,);
}

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

impl pallet_balances::Config for Runtime {
type MaxLocks = ConstU32<50>;
/// The type for recording an account's balance.
type Balance = Balance;
/// The ubiquitous event type.
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
type MaxReserves = ConstU32<50>;
type ReserveIdentifier = [u8; 8];
type RuntimeHoldReason = RuntimeHoldReason;
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<256>;
type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
/// Relay Chain `TransactionByteFee` / 10
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
}

impl pallet_transaction_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type OnChargeTransaction =
pallet_transaction_payment::FungibleAdapter<Balances, ResolveTo<TreasuryAccount, Balances>>;
type WeightToFee = WeightToFee;
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
type FeeMultiplierUpdate = SlowAdjustingFeeUpdate<Self>;
type OperationalFeeMultiplier = ConstU8<5>;
}

parameter_types! {
pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block;
}
@@ -442,8 +317,6 @@ impl pallet_message_queue::Config for Runtime {
type IdleMaxServiceWeight = ();
}

impl parachain_info::Config for Runtime {}

impl cumulus_pallet_aura_ext::Config for Runtime {}

/// How many parachain blocks are processed by the relay chain per parent.
@@ -455,26 +328,6 @@ const UNINCLUDED_SEGMENT_CAPACITY: u32 = 1;
/// Relay chain slot duration, in milliseconds.
const RELAY_CHAIN_SLOT_DURATION_MILLIS: u32 = 6_000;

parameter_types! {
pub const ReservedXcmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub const ReservedDmpWeight: Weight = MAXIMUM_BLOCK_WEIGHT.saturating_div(4);
pub const RelayOrigin: AggregateMessageOrigin = AggregateMessageOrigin::Parent;
}

impl cumulus_pallet_parachain_system::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type OnSystemEvent = ();
type SelfParaId = parachain_info::Pallet<Runtime>;
type OutboundXcmpMessageSource = XcmpQueue;
type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
type ReservedDmpWeight = ReservedDmpWeight;
type XcmpMessageHandler = XcmpQueue;
type ReservedXcmpWeight = ReservedXcmpWeight;
type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases;
type ConsensusHook = ConsensusHook;
}

/// Aura consensus hook
type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook<
Runtime,
@@ -631,54 +484,6 @@ impl pallet_utility::Config for Runtime {
type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
}

parameter_types! {
pub const AssetDeposit: Balance = UNITS / 10; // 1 / 10 UNITS deposit to create asset
pub const AssetAccountDeposit: Balance = deposit(1, 16);
pub const ApprovalDeposit: Balance = EXISTENTIAL_DEPOSIT;
pub const AssetsStringLimit: u32 = 50;
/// Key = 32 bytes, Value = 36 bytes (32+1+1+1+1)
// https://github.com/paritytech/substrate/blob/069917b/frame/assets/src/lib.rs#L257L271
pub const MetadataDepositBase: Balance = deposit(1, 68);
pub const MetadataDepositPerByte: Balance = deposit(0, 1);
}

/// We allow root to execute privileged asset operations.
pub type AssetsForceOrigin = EnsureRoot<AccountId>;
pub type KreivoAssetsInstance = pallet_assets::Instance1;
type KreivoAssetsCall = pallet_assets::Call<Runtime, KreivoAssetsInstance>;

impl pallet_assets::Config<KreivoAssetsInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type Balance = Balance;
type AssetId = FungibleAssetLocation;
type AssetIdParameter = FungibleAssetLocation;
type Currency = Balances;
/// Only root can create assets and force state changes.
type CreateOrigin = AsEnsureOriginWithArg<NeverEnsureOrigin<AccountId>>;
type ForceOrigin = AssetsForceOrigin;
type AssetDeposit = AssetDeposit;
type MetadataDepositBase = MetadataDepositBase;
type MetadataDepositPerByte = MetadataDepositPerByte;
type ApprovalDeposit = ApprovalDeposit;
type StringLimit = AssetsStringLimit;
type Freezer = AssetsFreezer;
type Extra = ();
type WeightInfo = weights::pallet_assets::WeightInfo<Runtime>;
type CallbackHandle = ();
type AssetAccountDeposit = AssetAccountDeposit;
type RemoveItemsLimit = frame_support::traits::ConstU32<1000>;
type MaxHolds = frame_support::traits::ConstU32<50>;
type RuntimeHoldReason = RuntimeHoldReason;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}

impl pallet_assets_freezer::Config<KreivoAssetsInstance> for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeFreezeReason = RuntimeFreezeReason;
}

parameter_types! {
// One storage item; key size 32, value size 8; .
pub const ProxyDepositBase: Balance = deposit(1, 40);
@@ -784,32 +589,6 @@ pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::Exponenti
ParachainSystem,
>;

impl pallet_asset_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Fungibles = Assets;
type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter<
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto, KreivoAssetsInstance>,
AssetsToBlockAuthor<Runtime, KreivoAssetsInstance>,
>;
}

parameter_types! {
pub const MinVestedTransfer: Balance = 100 * CENTS;
pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
}

impl pallet_vesting::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type BlockNumberToBalance = ConvertInto;
type MinVestedTransfer = MinVestedTransfer;
type WeightInfo = pallet_vesting::weights::SubstrateWeight<Runtime>;
type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons;
type BlockNumberProvider = System;
const MAX_VESTING_SCHEDULES: u32 = 28;
}

#[cfg(feature = "runtime-benchmarks")]
mod benches {
frame_benchmarking::define_benchmarks!(