Skip to content

Commit

Permalink
domain instantiation accept endowed accounts for the domain at genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas committed Feb 9, 2024
1 parent 4f84bed commit f173d3a
Show file tree
Hide file tree
Showing 19 changed files with 235 additions and 109 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion crates/pallet-domains/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "h
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
log = { version = "0.4.20", default-features = false }
pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
scale-info = { version = "2.7.0", default-features = false, features = ["derive"] }
sp-consensus-slots = { version = "0.10.0-dev", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
sp-core = { version = "21.0.0", default-features = false, git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
Expand All @@ -32,7 +33,6 @@ subspace-runtime-primitives = { version = "0.1.0", default-features = false, pat

[dev-dependencies]
domain-pallet-executive = { version = "0.1.0", default-features = false, path = "../../domains/pallets/executive" }
pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
pallet-timestamp = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
pallet-block-fees = { version = "0.1.0", default-features = false, path = "../../domains/pallets/block-fees" }
sp-externalities = { version = "0.19.0", git = "https://github.com/subspace/polkadot-sdk", rev = "d6b500960579d73c43fc4ef550b703acfa61c4c8" }
Expand All @@ -48,6 +48,7 @@ std = [
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-balances/std",
"scale-info/std",
"sp-consensus-slots/std",
"sp-core/std",
Expand Down
2 changes: 2 additions & 0 deletions crates/pallet-domains/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ mod benchmarks {
bundle_slot_probability: (1, 1),
target_bundles_per_block: 10,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

#[extrinsic_call]
Expand Down Expand Up @@ -434,6 +435,7 @@ mod benchmarks {
bundle_slot_probability: (1, 1),
target_bundles_per_block: 10,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

assert_ok!(Domains::<T>::instantiate_domain(
Expand Down
29 changes: 21 additions & 8 deletions crates/pallet-domains/src/domain_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use crate::pallet::{DomainStakingSummary, NextEVMChainId};
use crate::runtime_registry::DomainRuntimeInfo;
use crate::staking::StakingSummary;
use crate::{
Config, DomainHashingFor, DomainRegistry, ExecutionReceiptOf, HoldIdentifier, NextDomainId,
RuntimeRegistry,
BalanceOf, Config, DomainHashingFor, DomainRegistry, ExecutionReceiptOf, HoldIdentifier,
NextDomainId, RuntimeRegistry,
};
use alloc::string::String;
use codec::{Decode, Encode};
use domain_runtime_primitives::MultiAccountId;
use frame_support::traits::fungible::{Inspect, MutateHold};
use frame_support::traits::tokens::{Fortitude, Preservation};
use frame_support::weights::Weight;
Expand All @@ -25,6 +26,7 @@ use sp_runtime::traits::{CheckedAdd, Zero};
use sp_runtime::DigestItem;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::collections::btree_set::BTreeSet;
use sp_std::vec::Vec;

/// Domain registry specific errors
#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)]
Expand All @@ -42,10 +44,11 @@ pub enum Error {
FailedToGenerateGenesisStateRoot,
DomainNotFound,
NotDomainOwner,
FailedToGenerateRawGenesis(crate::runtime_registry::Error),
}

#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
pub struct DomainConfig<AccountId: Ord> {
pub struct DomainConfig<AccountId: Ord, Balance> {
/// A user defined name for this domain, should be a human-readable UTF-8 encoded string.
pub domain_name: String,
/// A pointer to the `RuntimeRegistry` entry for this domain.
Expand All @@ -61,25 +64,27 @@ pub struct DomainConfig<AccountId: Ord> {
pub target_bundles_per_block: u32,
/// Allowed operators to operate for this domain.
pub operator_allow_list: OperatorAllowList<AccountId>,
/// Initial balances for Domain
pub initial_balances: Vec<(MultiAccountId, Balance)>,
}

#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
pub struct DomainObject<Number, ReceiptHash, AccountId: Ord> {
pub struct DomainObject<Number, ReceiptHash, AccountId: Ord, Balance> {
/// The address of the domain creator, used to validate updating the domain config.
pub owner_account_id: AccountId,
/// The consensus chain block number when the domain first instantiated.
pub created_at: Number,
/// The hash of the genesis execution receipt for this domain.
pub genesis_receipt_hash: ReceiptHash,
/// The domain config.
pub domain_config: DomainConfig<AccountId>,
pub domain_config: DomainConfig<AccountId, Balance>,
/// Domain runtime specific information.
pub domain_runtime_info: DomainRuntimeInfo,
}

pub(crate) fn can_instantiate_domain<T: Config>(
owner_account_id: &T::AccountId,
domain_config: &DomainConfig<T::AccountId>,
domain_config: &DomainConfig<T::AccountId, BalanceOf<T>>,
) -> Result<(), Error> {
ensure!(
domain_config.domain_name.len() as u32 <= T::MaxDomainNameLength::get(),
Expand Down Expand Up @@ -120,7 +125,7 @@ pub(crate) fn can_instantiate_domain<T: Config>(
}

pub(crate) fn do_instantiate_domain<T: Config>(
domain_config: DomainConfig<T::AccountId>,
domain_config: DomainConfig<T::AccountId, BalanceOf<T>>,
owner_account_id: T::AccountId,
created_at: BlockNumberFor<T>,
) -> Result<DomainId, Error> {
Expand All @@ -141,9 +146,16 @@ pub(crate) fn do_instantiate_domain<T: Config>(
}
};

// TODO: burn the total initial balance for domain from the domain owner account
let genesis_receipt = {
let state_version = runtime_obj.version.state_version();
let raw_genesis = runtime_obj.into_complete_raw_genesis(domain_id, domain_runtime_info);
let raw_genesis = runtime_obj
.into_complete_raw_genesis::<T>(
domain_id,
domain_runtime_info,
domain_config.initial_balances.clone(),
)
.map_err(Error::FailedToGenerateRawGenesis)?;
let state_root = raw_genesis.state_root::<DomainHashingFor<T>>(state_version);
let genesis_block_hash = derive_domain_block_hash::<T::DomainHeader>(
Zero::zero(),
Expand Down Expand Up @@ -244,6 +256,7 @@ mod tests {
bundle_slot_probability: (0, 0),
target_bundles_per_block: 0,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

let mut ext = new_test_ext();
Expand Down
18 changes: 14 additions & 4 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ mod pallet {
_,
Identity,
DomainId,
DomainObject<BlockNumberFor<T>, ReceiptHashFor<T>, T::AccountId>,
DomainObject<BlockNumberFor<T>, ReceiptHashFor<T>, T::AccountId, BalanceOf<T>>,
OptionQuery,
>;

Expand Down Expand Up @@ -1139,7 +1139,7 @@ mod pallet {
#[pallet::weight(T::WeightInfo::instantiate_domain())]
pub fn instantiate_domain(
origin: OriginFor<T>,
domain_config: DomainConfig<T::AccountId>,
domain_config: DomainConfig<T::AccountId, BalanceOf<T>>,
) -> DispatchResult {
ensure_root(origin)?;

Expand Down Expand Up @@ -1314,6 +1314,11 @@ mod pallet {
bundle_slot_probability: genesis_domain.bundle_slot_probability,
target_bundles_per_block: genesis_domain.target_bundles_per_block,
operator_allow_list: genesis_domain.operator_allow_list,
initial_balances: genesis_domain
.initial_balances
.into_iter()
.map(|(acc, balance)| (acc, balance.saturated_into()))
.collect(),
};
let domain_owner = genesis_domain.owner_account_id;
let domain_id =
Expand Down Expand Up @@ -1498,8 +1503,13 @@ impl<T: Config> Pallet<T> {
let domain_obj = DomainRegistry::<T>::get(domain_id)?;
let runtime_object = RuntimeRegistry::<T>::get(domain_obj.domain_config.runtime_id)?;
let runtime_type = runtime_object.runtime_type.clone();
let raw_genesis =
runtime_object.into_complete_raw_genesis(domain_id, domain_obj.domain_runtime_info);
let raw_genesis = runtime_object
.into_complete_raw_genesis::<T>(
domain_id,
domain_obj.domain_runtime_info,
domain_obj.domain_config.initial_balances,
)
.ok()?;
Some((
DomainInstanceData {
runtime_type,
Expand Down
78 changes: 70 additions & 8 deletions crates/pallet-domains/src/runtime_registry.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
//! Runtime registry for domains

use crate::pallet::{NextRuntimeId, RuntimeRegistry, ScheduledRuntimeUpgrades};
use crate::{Config, Event};
use crate::{BalanceOf, Config, Event};
use alloc::string::String;
use codec::{Decode, Encode};
use domain_runtime_primitives::EVMChainId;
use domain_runtime_primitives::{AccountId20, EVMChainId, MultiAccountId, TryConvertBack};
use frame_support::PalletError;
use frame_system::pallet_prelude::*;
use frame_system::AccountInfo;
use scale_info::TypeInfo;
use sp_core::Hasher;
use sp_domains::storage::RawGenesis;
use sp_domains::storage::{RawGenesis, StorageData, StorageKey};
use sp_domains::{DomainId, DomainsDigestItem, RuntimeId, RuntimeType};
use sp_runtime::traits::{CheckedAdd, Get};
use sp_runtime::traits::{CheckedAdd, Get, Zero};
use sp_runtime::DigestItem;
use sp_std::collections::btree_map::BTreeMap;
use sp_std::vec::Vec;
use sp_version::RuntimeVersion;

Expand All @@ -28,6 +30,8 @@ pub enum Error {
MaxScheduledBlockNumber,
FailedToDecodeRawGenesis,
RuntimeCodeNotFoundInRawGenesis,
InitialBalanceOverflow,
InvalidAccountIdType,
}

#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -56,21 +60,79 @@ impl Default for DomainRuntimeInfo {
}
}

fn derive_initial_balances_storages<T: Config, AccountId: Encode>(
balances: BTreeMap<AccountId, BalanceOf<T>>,
) -> Result<Vec<(StorageKey, StorageData)>, Error> {
let mut initial_storages = vec![];
let total_balance = balances
.iter()
.try_fold(BalanceOf::<T>::zero(), |total, (_, balance)| {
total.checked_add(balance)
})
.ok_or(Error::InitialBalanceOverflow)?;

let total_issuance_key = sp_domains::domain_total_issuance_storage_key();
initial_storages.push((total_issuance_key, StorageData(total_balance.encode())));

for (account_id, balance) in balances {
let account_storage_key = sp_domains::domain_account_storage_key(account_id);
let account_info = AccountInfo {
nonce: domain_runtime_primitives::Nonce::zero(),
consumers: 0,
// providers are set to 1 for new accounts
providers: 1,
sufficients: 0,
data: pallet_balances::AccountData {
free: balance,
..Default::default()
},
};
initial_storages.push((account_storage_key, StorageData(account_info.encode())))
}

Ok(initial_storages)
}

impl<Number, Hash> RuntimeObject<Number, Hash> {
// Return a complete raw genesis with runtime code and domain id set properly
pub fn into_complete_raw_genesis(
pub fn into_complete_raw_genesis<T: Config>(
self,
domain_id: DomainId,
domain_runtime_info: DomainRuntimeInfo,
) -> RawGenesis {
initial_balances: Vec<(MultiAccountId, BalanceOf<T>)>,
) -> Result<RawGenesis, Error> {
let RuntimeObject {
mut raw_genesis, ..
} = self;
raw_genesis.set_domain_id(domain_id);
match domain_runtime_info {
DomainRuntimeInfo::EVM { chain_id } => raw_genesis.set_evm_chain_id(chain_id),
DomainRuntimeInfo::EVM { chain_id } => {
raw_genesis.set_evm_chain_id(chain_id);
let initial_balances = initial_balances
.into_iter()
.try_fold(
BTreeMap::<AccountId20, BalanceOf<T>>::new(),
|mut acc, (account_id, balance)| {
let account_id =
domain_runtime_primitives::AccountId20Converter::try_convert_back(
account_id,
)?;
let balance = if let Some(previous_balance) = acc.get(&account_id) {
previous_balance.checked_add(&balance)?
} else {
balance
};
acc.insert(account_id, balance);
Some(acc)
},
)
.ok_or(Error::InvalidAccountIdType)?;
raw_genesis
.set_top_storages(derive_initial_balances_storages::<T, _>(initial_balances)?);
}
}
raw_genesis

Ok(raw_genesis)
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/pallet-domains/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,7 @@ pub(crate) mod tests {
bundle_slot_probability: (0, 0),
target_bundles_per_block: 0,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

let domain_obj = DomainObject {
Expand Down Expand Up @@ -1685,6 +1686,7 @@ pub(crate) mod tests {
bundle_slot_probability: (0, 0),
target_bundles_per_block: 0,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

let domain_obj = DomainObject {
Expand Down Expand Up @@ -1798,6 +1800,7 @@ pub(crate) mod tests {
bundle_slot_probability: (0, 0),
target_bundles_per_block: 0,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

let domain_obj = DomainObject {
Expand Down
1 change: 1 addition & 0 deletions crates/pallet-domains/src/staking_epoch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ mod tests {
bundle_slot_probability: (0, 0),
target_bundles_per_block: 0,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};

let domain_obj = DomainObject {
Expand Down
2 changes: 2 additions & 0 deletions crates/pallet-domains/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ pub(crate) fn register_genesis_domain(creator: u128, operator_ids: Vec<OperatorI
bundle_slot_probability: (1, 1),
target_bundles_per_block: 1,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
},
)
.unwrap();
Expand Down Expand Up @@ -827,6 +828,7 @@ fn test_bundle_fromat_verification() {
bundle_slot_probability: (1, 1),
target_bundles_per_block: 1,
operator_allow_list: OperatorAllowList::Anyone,
initial_balances: Default::default(),
};
let domain_obj = DomainObject {
owner_account_id: Default::default(),
Expand Down
Loading

0 comments on commit f173d3a

Please sign in to comment.