Skip to content

Commit

Permalink
Merge pull request #1157 from subspace/support-add-new-domain
Browse files Browse the repository at this point in the history
Support adding new domains
  • Loading branch information
liuchengxu authored Feb 20, 2023
2 parents 4beb4a0 + 5ebd7b9 commit a5ead62
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 66 deletions.
5 changes: 5 additions & 0 deletions crates/pallet-receipts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ impl<T: Config> Pallet<T> {
<HeadReceiptNumber<T>>::get(domain_id)
}

/// Initialize the head receipt on the domain creation.
pub fn initialize_head_receipt_number(domain_id: DomainId, created_at: T::BlockNumber) {
<HeadReceiptNumber<T>>::insert(domain_id, created_at)
}

/// Returns the block number of the oldest receipt still being tracked in the state.
pub fn oldest_receipt_number(domain_id: DomainId) -> T::BlockNumber {
Self::finalized_receipt_number(domain_id) + One::one()
Expand Down
78 changes: 41 additions & 37 deletions crates/subspace-node/src/bin/subspace-node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,49 +572,53 @@ fn main() -> Result<(), Error> {
))
})?;

let core_domain_node = match core_domain_cli.domain_id {
let core_domain_params = domain_service::CoreDomainParams {
domain_id: core_domain_cli.domain_id,
core_domain_config,
system_domain_client: system_domain_node.client.clone(),
system_domain_network: system_domain_node.network.clone(),
primary_chain_client: primary_chain_node.client.clone(),
primary_network: primary_chain_node.network.clone(),
select_chain: primary_chain_node.select_chain.clone(),
imported_block_notification_stream: imported_block_notification_stream(
),
new_slot_notification_stream: new_slot_notification_stream(),
block_import_throttling_buffer_size,
gossip_message_sink: gossip_msg_sink,
};

match core_domain_cli.domain_id {
DomainId::CORE_PAYMENTS => {
domain_service::new_full_core::<
_,
_,
_,
_,
_,
_,
_,
core_payments_domain_runtime::RuntimeApi,
CorePaymentsDomainExecutorDispatch,
>(
let core_domain_node =
domain_service::new_full_core::<
_,
_,
_,
_,
_,
_,
_,
core_payments_domain_runtime::RuntimeApi,
CorePaymentsDomainExecutorDispatch,
>(core_domain_params)
.await?;

domain_tx_pool_sinks.insert(
core_domain_cli.domain_id,
core_domain_config,
system_domain_node.client.clone(),
system_domain_node.network.clone(),
primary_chain_node.client.clone(),
primary_chain_node.network.clone(),
&primary_chain_node.select_chain,
imported_block_notification_stream(),
new_slot_notification_stream(),
block_import_throttling_buffer_size,
gossip_msg_sink,
)
.await?
core_domain_node.tx_pool_sink,
);
primary_chain_node
.task_manager
.add_child(core_domain_node.task_manager);

core_domain_node.network_starter.start_network();
}
_ => {
core_domain_id => {
return Err(Error::Other(format!(
"Invalid domain id, currently only core-payments domain is \
supported, please rerun with `--domain-id={:?}`",
u32::from(DomainId::CORE_PAYMENTS)
"{core_domain_id:?} unimplemented",
)));
}
};

domain_tx_pool_sinks
.insert(core_domain_cli.domain_id, core_domain_node.tx_pool_sink);
primary_chain_node
.task_manager
.add_child(core_domain_node.task_manager);

core_domain_node.network_starter.start_network();
}
}

let cross_domain_message_gossip_worker = GossipWorker::<Block>::new(
Expand Down
15 changes: 3 additions & 12 deletions crates/subspace-node/src/core_domain/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,19 +151,10 @@ impl SubstrateCli for CoreDomainCli {

fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn ChainSpec>, String> {
// TODO: add core domain chain spec an extension of system domain chain spec.
let chain_spec = match self.domain_id {
DomainId::CORE_PAYMENTS => match id {
"dev" => core_payments_chain_spec::development_config(),
"gemini-3c" => core_payments_chain_spec::gemini_3c_config(),
"devnet" => core_payments_chain_spec::devnet_config(),
"" | "local" => core_payments_chain_spec::local_testnet_config(),
path => core_payments_chain_spec::ChainSpec::from_json_file(
std::path::PathBuf::from(path),
)?,
},
match self.domain_id {
DomainId::CORE_PAYMENTS => core_payments_chain_spec::load_chain_spec(id),
domain_id => unreachable!("Unsupported core domain: {domain_id:?}"),
};
Ok(Box::new(chain_spec))
}
}

fn native_runtime_version(_chain_spec: &Box<dyn ChainSpec>) -> &'static RuntimeVersion {
Expand Down
11 changes: 11 additions & 0 deletions crates/subspace-node/src/core_domain/core_payments_chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@ pub fn devnet_config() -> ExecutionChainSpec<GenesisConfig> {
)
}

pub fn load_chain_spec(spec_id: &str) -> std::result::Result<Box<dyn sc_cli::ChainSpec>, String> {
let chain_spec = match spec_id {
"dev" => development_config(),
"gemini-3c" => gemini_3c_config(),
"devnet" => devnet_config(),
"" | "local" => local_testnet_config(),
path => ChainSpec::from_json_file(std::path::PathBuf::from(path))?,
};
Ok(Box::new(chain_spec))
}

fn testnet_genesis(
endowed_accounts: Vec<AccountId>,
maybe_sudo_account: Option<AccountId>,
Expand Down
8 changes: 4 additions & 4 deletions crates/subspace-node/src/system_domain/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub fn development_config() -> ExecutionChainSpec<GenesisConfig> {
min_operator_stake: 100 * SSC,
},
get_account_id_from_seed("Alice"),
Percent::one(),
Percent::from_percent(10),
)],
Some(get_account_id_from_seed("Alice")),
vec![(
Expand Down Expand Up @@ -133,7 +133,7 @@ pub fn local_testnet_config() -> ExecutionChainSpec<GenesisConfig> {
min_operator_stake: 100 * SSC,
},
get_account_id_from_seed("Alice"),
Percent::one(),
Percent::from_percent(10),
)],
Some(get_account_id_from_seed("Alice")),
vec![
Expand Down Expand Up @@ -208,7 +208,7 @@ pub fn gemini_3c_config() -> ExecutionChainSpec<GenesisConfig> {
},
AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ")
.expect("Wrong executor account address"),
Percent::one(),
Percent::from_percent(10),
)],
Some(sudo_account),
Default::default(),
Expand Down Expand Up @@ -274,7 +274,7 @@ pub fn devnet_config() -> ExecutionChainSpec<GenesisConfig> {
},
AccountId::from_ss58check("5Df6w8CgYY8kTRwCu8bjBsFu46fy4nFa61xk6dUbL6G4fFjQ")
.expect("Wrong executor account address"),
Percent::one(),
Percent::from_percent(10),
)],
Some(sudo_account.clone()),
vec![(
Expand Down
27 changes: 27 additions & 0 deletions domains/pallets/domain-registry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ mod pallet {
pub(super) type Domains<T: Config> =
StorageMap<_, Twox64Concat, DomainId, DomainConfig<T>, OptionQuery>;

/// At which block the domain was created.
#[pallet::storage]
pub(super) type CreatedAt<T: Config> =
StorageMap<_, Twox64Concat, DomainId, T::BlockNumber, OptionQuery>;

/// (executor, domain_id, allocated_stake_proportion)
#[pallet::storage]
pub(super) type DomainOperators<T: Config> = StorageDoubleMap<
Expand Down Expand Up @@ -453,6 +458,8 @@ mod pallet {
TooFarInFuture,
/// Core domain receipt points to an unknown primary block.
UnknownBlock,
/// Valid receipts start after the domain creation.
BeforeDomainCreation,
}

impl<T> From<PalletReceiptError> for Error<T> {
Expand Down Expand Up @@ -512,6 +519,9 @@ mod pallet {
/// Not a core domain bundle.
NotCoreDomainBundle,

/// Can not find the number of block the domain was created at.
DomainNotCreated,

/// Can not find the block hash of given primary block number.
UnavailablePrimaryBlockHash,

Expand Down Expand Up @@ -752,6 +762,7 @@ impl<T: Config> Pallet<T> {
return Err(Error::<T>::NotCoreDomainBundle);
}

let created_at = CreatedAt::<T>::get(domain_id).ok_or(Error::<T>::DomainNotCreated)?;
let head_receipt_number = Self::head_receipt_number(domain_id);
let max_allowed = head_receipt_number + T::MaximumReceiptDrift::get();

Expand All @@ -777,6 +788,15 @@ impl<T: Config> Pallet<T> {
}

let primary_number = receipt.primary_number;

if primary_number <= created_at {
log::error!(
target: "runtime::domain-registry",
"Domain was created at #{created_at:?}, but this receipt points to an earlier block #{:?}", receipt.primary_number,
);
return Err(Error::<T>::Receipt(ReceiptError::BeforeDomainCreation));
}

if !pallet_receipts::Pallet::<T>::point_to_valid_primary_block(domain_id, receipt) {
log::error!(
target: "runtime::domain-registry",
Expand Down Expand Up @@ -958,6 +978,13 @@ impl<T: Config> Pallet<T> {
DomainCreators::<T>::insert(domain_id, who, deposit);
NextDomainId::<T>::put(domain_id + 1);

let current_block_number = frame_system::Pallet::<T>::block_number();
CreatedAt::<T>::insert(domain_id, current_block_number);
pallet_receipts::Pallet::<T>::initialize_head_receipt_number(
domain_id,
current_block_number,
);

domain_id
}

Expand Down
46 changes: 34 additions & 12 deletions domains/service/src/core_domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,24 @@ where
Ok(params)
}

pub struct CoreDomainParams<SBlock, PBlock, SClient, PClient, SC, IBNS, NSNS>
where
SBlock: BlockT,
PBlock: BlockT,
{
pub domain_id: DomainId,
pub core_domain_config: DomainConfiguration,
pub system_domain_client: Arc<SClient>,
pub system_domain_network: Arc<NetworkService<SBlock, SBlock::Hash>>,
pub primary_chain_client: Arc<PClient>,
pub primary_network: Arc<NetworkService<PBlock, PBlock::Hash>>,
pub select_chain: SC,
pub imported_block_notification_stream: IBNS,
pub new_slot_notification_stream: NSNS,
pub block_import_throttling_buffer_size: u32,
pub gossip_message_sink: GossipMessageSink,
}

/// Start a node with the given parachain `Configuration` and relay chain `Configuration`.
///
/// This is the actual implementation that is abstract over the executor and the runtime api.
Expand All @@ -209,17 +227,7 @@ pub async fn new_full_core<
RuntimeApi,
ExecutorDispatch,
>(
domain_id: DomainId,
mut core_domain_config: DomainConfiguration,
system_domain_client: Arc<SClient>,
system_domain_network: Arc<NetworkService<SBlock, SBlock::Hash>>,
primary_chain_client: Arc<PClient>,
primary_network: Arc<NetworkService<PBlock, PBlock::Hash>>,
select_chain: &SC,
imported_block_notification_stream: IBNS,
new_slot_notification_stream: NSNS,
block_import_throttling_buffer_size: u32,
gossip_message_sink: GossipMessageSink,
core_domain_params: CoreDomainParams<SBlock, PBlock, SClient, PClient, SC, IBNS, NSNS>,
) -> sc_service::error::Result<
NewFullCore<
Arc<FullClient<RuntimeApi, ExecutorDispatch>>,
Expand Down Expand Up @@ -268,6 +276,20 @@ where
+ RelayerApi<Block, RelayerId, NumberFor<Block>>,
ExecutorDispatch: NativeExecutionDispatch + 'static,
{
let CoreDomainParams {
domain_id,
mut core_domain_config,
system_domain_client,
system_domain_network,
primary_chain_client,
primary_network,
select_chain,
imported_block_notification_stream,
new_slot_notification_stream,
block_import_throttling_buffer_size,
gossip_message_sink,
} = core_domain_params;

// TODO: Do we even need block announcement on core domain node?
// core_domain_config.announce_block = false;

Expand Down Expand Up @@ -340,7 +362,7 @@ where
domain_id,
system_domain_client.clone(),
&spawn_essential,
select_chain,
&select_chain,
EssentialExecutorParams {
primary_chain_client: primary_chain_client.clone(),
primary_network,
Expand Down
2 changes: 1 addition & 1 deletion domains/service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod core_domain;
mod rpc;
mod system_domain;

pub use self::core_domain::{new_full_core, NewFullCore};
pub use self::core_domain::{new_full_core, CoreDomainParams, NewFullCore};
pub use self::system_domain::{new_full_system, FullPool, NewFullSystem};
use domain_runtime_primitives::opaque::Block;
use domain_runtime_primitives::RelayerId;
Expand Down

0 comments on commit a5ead62

Please sign in to comment.