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

Change solochain flag into subcommand #683

Merged
merged 19 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 16 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
4 changes: 4 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,11 @@ tap = "1.0.1"
# General (client)
async-io = "1.3"
async-trait = "0.1"
chrono = "0.4.31"
clap = { version = "4.5.3", default-features = false, features = [ "derive" ] }
core_extensions = "1.5.3"
exit-future = { version = "0.2.0" }
fdlimit = "0.3.0"
flume = "0.10.9"
fs2 = "0.4.3"
futures = { version = "0.3.1" }
Expand Down
49 changes: 40 additions & 9 deletions client/consensus/src/collators/lookahead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,32 @@ pub struct Params<
pub authoring_duration: Duration,
pub force_authoring: bool,
pub cancellation_token: CancellationToken,
pub orchestrator_tx_pool: Arc<TxPool>,
pub orchestrator_client: Arc<OClient>,
pub solochain: bool,
pub buy_core_params: BuyCoreParams<TxPool, OClient>,
}

pub enum BuyCoreParams<TxPool, OClient> {
Orchestrator {
orchestrator_tx_pool: Arc<TxPool>,
orchestrator_client: Arc<OClient>,
},
Solochain {
// TODO: relay_tx_pool
},
}

impl<TxPool, OClient> Clone for BuyCoreParams<TxPool, OClient> {
fn clone(&self) -> Self {
match self {
Self::Orchestrator {
orchestrator_tx_pool,
orchestrator_client,
} => Self::Orchestrator {
orchestrator_tx_pool: orchestrator_tx_pool.clone(),
orchestrator_client: orchestrator_client.clone(),
},
Self::Solochain {} => Self::Solochain {},
}
}
}

/// Run async-backing-friendly for Tanssi Aura.
Expand Down Expand Up @@ -637,12 +660,20 @@ where
let slot = inherent_providers.slot();
let container_chain_slot_duration = (params.get_current_slot_duration)(parent_header.hash());

let buy_core_result = if params.solochain {
// TODO: implement parathread support for solochain
log::warn!("Unimplemented: cannot buy core for parathread in solochain");
break;
} else {
try_to_buy_core::<_, _, <<OBlock as BlockT>::Header as HeaderT>::Number, _, CIDP, _, _>(params.para_id, aux_data, inherent_providers, &params.keystore, params.orchestrator_client.clone(), params.orchestrator_tx_pool.clone(), parent_header, params.orchestrator_slot_duration, container_chain_slot_duration).await
let buy_core_result = match &params.buy_core_params {
BuyCoreParams::Orchestrator {
orchestrator_client,
orchestrator_tx_pool,
} => {
try_to_buy_core::<_, _, <<OBlock as BlockT>::Header as HeaderT>::Number, _, CIDP, _, _>(params.para_id, aux_data, inherent_providers, &params.keystore, orchestrator_client.clone(), orchestrator_tx_pool.clone(), parent_header, params.orchestrator_slot_duration, container_chain_slot_duration).await
}
BuyCoreParams::Solochain {

} => {
// TODO: implement parathread support for solochain
log::warn!("Unimplemented: cannot buy core for parathread in solochain");
break;
}
};
match buy_core_result {
Ok(block_hash) => {
Expand Down
26 changes: 14 additions & 12 deletions client/consensus/src/mocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@

use {
crate::{
collators::lookahead::Params as LookAheadParams, OrchestratorAuraWorkerAuxData,
SlotFrequency,
collators::lookahead::{BuyCoreParams, Params as LookAheadParams},
OrchestratorAuraWorkerAuxData, SlotFrequency,
},
async_trait::async_trait,
cumulus_client_collator::service::CollatorService,
cumulus_client_consensus_common::{ParachainBlockImportMarker, ValidationCodeHashProvider},
cumulus_client_consensus_proposer::Proposer as ConsensusProposer,
cumulus_primitives_core::{relay_chain::BlockId, CollationInfo, CollectCollationInfo, ParaId},
cumulus_primitives_core::{
relay_chain::{BlockId, ValidationCodeHash},
CollationInfo, CollectCollationInfo, ParaId,
},
cumulus_relay_chain_interface::{
CommittedCandidateReceipt, OverseerHandle, RelayChainInterface, RelayChainResult,
StorageValue,
Expand All @@ -35,7 +38,10 @@ use {
pallet_xcm_core_buyer_runtime_api::BuyingError,
parity_scale_codec::Encode,
polkadot_core_primitives::{Header as PHeader, InboundDownwardMessage, InboundHrmpMessage},
polkadot_node_subsystem::messages::{RuntimeApiMessage, RuntimeApiRequest},
polkadot_node_subsystem::{
messages::{RuntimeApiMessage, RuntimeApiRequest},
overseer, OverseerSignal,
},
polkadot_overseer::dummy::dummy_overseer_builder,
polkadot_parachain_primitives::primitives::HeadData,
polkadot_primitives::{
Expand Down Expand Up @@ -512,11 +518,6 @@ impl<B: BlockT> sc_consensus::Verifier<B> for SealExtractorVerfier {
}
}

use {
cumulus_primitives_core::relay_chain::ValidationCodeHash,
polkadot_node_subsystem::{overseer, OverseerSignal},
};

pub struct DummyCodeHashProvider;
impl ValidationCodeHashProvider<PHash> for DummyCodeHashProvider {
fn code_hash_at(&self, _at: PHash) -> Option<ValidationCodeHash> {
Expand Down Expand Up @@ -984,10 +985,11 @@ impl CollatorLookaheadTestBuilder {
para_client: environ.clone().into(),
sync_oracle: DummyOracle,
para_backend: backend,
orchestrator_client: environ.into(),
buy_core_params: BuyCoreParams::Orchestrator {
orchestrator_client: environ.into(),
orchestrator_tx_pool: orchestrator_tx_pool.clone(),
},
orchestrator_slot_duration: SlotDuration::from_millis(SLOT_DURATION_MS),
orchestrator_tx_pool: orchestrator_tx_pool.clone(),
solochain: false,
};
let (fut, exit_notification_receiver) = crate::collators::lookahead::run::<
_,
Expand Down
2 changes: 2 additions & 0 deletions client/service-container-chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ log = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true }
tokio-util = { workspace = true }
url = { workspace = true }

# Local
ccp-authorities-noting-inherent = { workspace = true, features = [ "std" ] }
Expand Down Expand Up @@ -70,6 +71,7 @@ sp-timestamp = { workspace = true, features = [ "std" ] }
polkadot-primitives = { workspace = true }

# Cumulus
cumulus-client-cli = { workspace = true }
cumulus-client-collator = { workspace = true }
cumulus-client-consensus-aura = { workspace = true }
cumulus-client-consensus-common = { workspace = true }
Expand Down
125 changes: 111 additions & 14 deletions client/service-container-chain/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@

use {
crate::chain_spec::RawGenesisConfig,
cumulus_client_cli::{CollatorOptions, RelayChainMode},
dc_orchestrator_chain_interface::ContainerChainGenesisData,
dp_container_chain_genesis_data::json::properties_to_map,
sc_chain_spec::ChainSpec,
sc_cli::{CliConfiguration, SubstrateCli},
sc_network::config::MultiaddrWithPeerId,
sc_service::BasePath,
sp_runtime::Storage,
std::{collections::BTreeMap, net::SocketAddr, path::PathBuf},
std::{collections::BTreeMap, net::SocketAddr},
url::Url,
};

/// The `run` command used to run a container chain node.
Expand All @@ -45,16 +49,76 @@ pub struct ContainerChainRunCmd {
/// Keep container-chain db after changing collator assignments
#[arg(long)]
pub keep_db: bool,

/// Creates a less resource-hungry node that retrieves relay chain data from an RPC endpoint.
///
/// The provided URLs should point to RPC endpoints of the relay chain.
/// This node connects to the remote nodes following the order they were specified in. If the
/// connection fails, it attempts to connect to the next endpoint in the list.
///
/// Note: This option doesn't stop the node from connecting to the relay chain network but
/// reduces bandwidth use.
#[arg(
long,
value_parser = validate_relay_chain_url,
num_args = 0..,
alias = "relay-chain-rpc-url"
)]
pub relay_chain_rpc_urls: Vec<Url>,

/// EXPERIMENTAL: Embed a light client for the relay chain. Only supported for full-nodes.
girazoki marked this conversation as resolved.
Show resolved Hide resolved
/// Will use the specified relay chain chainspec.
#[arg(long, conflicts_with_all = ["relay_chain_rpc_urls", "collator"])]
pub relay_chain_light_client: bool,
}

impl ContainerChainRunCmd {
/// Create a [`NormalizedRunCmd`] which merges the `collator` cli argument into `validator` to
/// have only one.
pub fn normalize(&self) -> ContainerChainCli {
let mut new_base = self.clone();

new_base.base.validator = self.base.validator || self.collator;

// Append `containers/` to base_path for this object. This is to ensure that when spawning
// a new container chain, its database is always inside the `containers` folder.
// So if the user passes `--base-path /tmp/node`, we want the ephemeral container data in
// `/tmp/node/containers`, and the persistent storage in `/tmp/node/config`.
let base_path = base_path_or_default(
self.base.base_path().expect("failed to get base_path"),
&ContainerChainCli::executable_name(),
);

let base_path = base_path.path().join("containers");
new_base.base.shared_params.base_path = Some(base_path);

ContainerChainCli {
base: new_base,
preloaded_chain_spec: None,
}
}

/// Create [`CollatorOptions`] representing options only relevant to parachain collator nodes
// Copied from polkadot-sdk/cumulus/client/cli/src/lib.rs
pub fn collator_options(&self) -> CollatorOptions {
let relay_chain_mode = match (
self.relay_chain_light_client,
!self.relay_chain_rpc_urls.is_empty(),
) {
(true, _) => RelayChainMode::LightClient,
(_, true) => RelayChainMode::ExternalRpc(self.relay_chain_rpc_urls.clone()),
_ => RelayChainMode::Embedded,
};

CollatorOptions { relay_chain_mode }
}
}

#[derive(Debug)]
pub struct ContainerChainCli {
/// The actual container chain cli object.
pub base: ContainerChainRunCmd,

/// The base path that should be used by the container chain.
pub base_path: PathBuf,

/// The ChainSpecs that this struct can initialize. This starts empty and gets filled
/// by calling preload_chain_spec_file.
pub preloaded_chain_spec: Option<Box<dyn sc_chain_spec::ChainSpec>>,
Expand All @@ -64,7 +128,6 @@ impl Clone for ContainerChainCli {
fn clone(&self) -> Self {
Self {
base: self.base.clone(),
base_path: self.base_path.clone(),
preloaded_chain_spec: self.preloaded_chain_spec.as_ref().map(|x| x.cloned_box()),
}
}
Expand All @@ -76,13 +139,27 @@ impl ContainerChainCli {
para_config: &sc_service::Configuration,
container_chain_args: impl Iterator<Item = &'a String>,
) -> Self {
let base_path = para_config.base_path.path().join("containers");
let mut base: ContainerChainRunCmd = clap::Parser::parse_from(container_chain_args);

Self {
base_path,
base: clap::Parser::parse_from(container_chain_args),
preloaded_chain_spec: None,
// Copy some parachain args into container chain args

// If the container chain args have no --wasmtime-precompiled flag, use the same as the orchestrator
if base.base.import_params.wasmtime_precompiled.is_none() {
base.base
.import_params
.wasmtime_precompiled
.clone_from(&para_config.wasmtime_precompiled);
}

// Set container base path to the same value as orchestrator base_path.
// "containers" is appended in `base.normalize()`
if base.base.shared_params.base_path.is_some() {
log::warn!("Container chain --base-path is being ignored");
}
let base_path = para_config.base_path.path().to_owned();
base.base.shared_params.base_path = Some(base_path);

base.normalize()
}

pub fn chain_spec_from_genesis_data(
Expand Down Expand Up @@ -249,10 +326,7 @@ impl sc_cli::CliConfiguration<Self> for ContainerChainCli {
}

fn base_path(&self) -> sc_cli::Result<Option<sc_service::BasePath>> {
Ok(self
.shared_params()
.base_path()?
.or_else(|| Some(self.base_path.clone().into())))
self.shared_params().base_path()
}

fn rpc_addr(&self, default_listen_port: u16) -> sc_cli::Result<Option<SocketAddr>> {
Expand Down Expand Up @@ -366,3 +440,26 @@ fn parse_container_chain_id_str(id: &str) -> std::result::Result<u32, String> {
})
.ok_or_else(|| format!("load_spec called with invalid id: {:?}", id))
}

// Copied from polkadot-sdk/cumulus/client/cli/src/lib.rs
fn validate_relay_chain_url(arg: &str) -> Result<Url, String> {
let url = Url::parse(arg).map_err(|e| e.to_string())?;

let scheme = url.scheme();
if scheme == "ws" || scheme == "wss" {
Ok(url)
} else {
Err(format!(
"'{}' URL scheme not supported. Only websocket RPC is currently supported",
url.scheme()
))
}
}

/// Returns the value of `base_path` or the default_path if it is None
pub(crate) fn base_path_or_default(
base_path: Option<BasePath>,
executable_name: &String,
) -> BasePath {
base_path.unwrap_or_else(|| BasePath::from_project("", "", executable_name))
}
Loading
Loading