fix: migrate vendor rustfmt.toml to stable-only features
- Update vendor/pezkuwi-zombienet-sdk/rustfmt.toml to stable-only - Reformat 74 vendor files with stable rustfmt - Remove nightly-only features causing CI failures
This commit is contained in:
@@ -302,7 +302,9 @@ impl<T: Config> ExtrinsicEvents<T> {
|
|||||||
///
|
///
|
||||||
/// This works in the same way that [`events::Events::find()`] does, with the
|
/// This works in the same way that [`events::Events::find()`] does, with the
|
||||||
/// exception that it filters out events not related to the submitted extrinsic.
|
/// exception that it filters out events not related to the submitted extrinsic.
|
||||||
pub fn find<'a, Ev: events::StaticEvent + 'a>(&'a self) -> impl Iterator<Item = Result<Ev, EventsError>> + 'a {
|
pub fn find<'a, Ev: events::StaticEvent + 'a>(
|
||||||
|
&'a self,
|
||||||
|
) -> impl Iterator<Item = Result<Ev, EventsError>> + 'a {
|
||||||
self.iter().filter_map(|ev| ev.and_then(|ev| ev.as_event::<Ev>()).transpose())
|
self.iter().filter_map(|ev| ev.and_then(|ev| ev.as_event::<Ev>()).transpose())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -137,10 +137,7 @@ impl GlobalSettingsBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self::transition(
|
Self::transition(
|
||||||
GlobalSettings {
|
GlobalSettings { bootnodes_addresses: addrs, ..self.config },
|
||||||
bootnodes_addresses: addrs,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
merge_errors_vecs(self.errors, errors),
|
merge_errors_vecs(self.errors, errors),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -148,33 +145,21 @@ impl GlobalSettingsBuilder {
|
|||||||
/// Set global spawn timeout in seconds.
|
/// Set global spawn timeout in seconds.
|
||||||
pub fn with_network_spawn_timeout(self, timeout: Duration) -> Self {
|
pub fn with_network_spawn_timeout(self, timeout: Duration) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
GlobalSettings {
|
GlobalSettings { network_spawn_timeout: timeout, ..self.config },
|
||||||
network_spawn_timeout: timeout,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set individual node spawn timeout in seconds.
|
/// Set individual node spawn timeout in seconds.
|
||||||
pub fn with_node_spawn_timeout(self, timeout: Duration) -> Self {
|
pub fn with_node_spawn_timeout(self, timeout: Duration) -> Self {
|
||||||
Self::transition(
|
Self::transition(GlobalSettings { node_spawn_timeout: timeout, ..self.config }, self.errors)
|
||||||
GlobalSettings {
|
|
||||||
node_spawn_timeout: timeout,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set local IP used to expose local services (including RPC, metrics and monitoring).
|
/// Set local IP used to expose local services (including RPC, metrics and monitoring).
|
||||||
pub fn with_local_ip(self, local_ip: &str) -> Self {
|
pub fn with_local_ip(self, local_ip: &str) -> Self {
|
||||||
match IpAddr::from_str(local_ip) {
|
match IpAddr::from_str(local_ip) {
|
||||||
Ok(local_ip) => Self::transition(
|
Ok(local_ip) => Self::transition(
|
||||||
GlobalSettings {
|
GlobalSettings { local_ip: Some(local_ip), ..self.config },
|
||||||
local_ip: Some(local_ip),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
@@ -187,10 +172,7 @@ impl GlobalSettingsBuilder {
|
|||||||
/// Set the directory to use as base (instead of a random tmp one).
|
/// Set the directory to use as base (instead of a random tmp one).
|
||||||
pub fn with_base_dir(self, base_dir: impl Into<PathBuf>) -> Self {
|
pub fn with_base_dir(self, base_dir: impl Into<PathBuf>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
GlobalSettings {
|
GlobalSettings { base_dir: Some(base_dir.into()), ..self.config },
|
||||||
base_dir: Some(base_dir.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -198,23 +180,14 @@ impl GlobalSettingsBuilder {
|
|||||||
/// Set the spawn concurrency
|
/// Set the spawn concurrency
|
||||||
pub fn with_spawn_concurrency(self, spawn_concurrency: usize) -> Self {
|
pub fn with_spawn_concurrency(self, spawn_concurrency: usize) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
GlobalSettings {
|
GlobalSettings { spawn_concurrency: Some(spawn_concurrency), ..self.config },
|
||||||
spawn_concurrency: Some(spawn_concurrency),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the `tear_down_on_failure` flag
|
/// Set the `tear_down_on_failure` flag
|
||||||
pub fn with_tear_down_on_failure(self, tear_down_on_failure: bool) -> Self {
|
pub fn with_tear_down_on_failure(self, tear_down_on_failure: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(GlobalSettings { tear_down_on_failure, ..self.config }, self.errors)
|
||||||
GlobalSettings {
|
|
||||||
tear_down_on_failure,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Seals the builder and returns a [`GlobalSettings`] if there are no validation errors, else returns errors.
|
/// Seals the builder and returns a [`GlobalSettings`] if there are no validation errors, else returns errors.
|
||||||
@@ -261,14 +234,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(global_settings_config.network_spawn_timeout(), 600);
|
assert_eq!(global_settings_config.network_spawn_timeout(), 600);
|
||||||
assert_eq!(global_settings_config.node_spawn_timeout(), 120);
|
assert_eq!(global_settings_config.node_spawn_timeout(), 120);
|
||||||
assert_eq!(
|
assert_eq!(global_settings_config.local_ip().unwrap().to_string().as_str(), "10.0.0.1");
|
||||||
global_settings_config
|
|
||||||
.local_ip()
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.as_str(),
|
|
||||||
"10.0.0.1"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
global_settings_config.base_dir().unwrap(),
|
global_settings_config.base_dir().unwrap(),
|
||||||
Path::new("/home/nonroot/mynetwork")
|
Path::new("/home/nonroot/mynetwork")
|
||||||
@@ -299,14 +265,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(global_settings_config.network_spawn_timeout(), 600);
|
assert_eq!(global_settings_config.network_spawn_timeout(), 600);
|
||||||
assert_eq!(global_settings_config.node_spawn_timeout(), 600);
|
assert_eq!(global_settings_config.node_spawn_timeout(), 600);
|
||||||
assert_eq!(
|
assert_eq!(global_settings_config.local_ip().unwrap().to_string().as_str(), "10.0.0.1");
|
||||||
global_settings_config
|
|
||||||
.local_ip()
|
|
||||||
.unwrap()
|
|
||||||
.to_string()
|
|
||||||
.as_str(),
|
|
||||||
"10.0.0.1"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -345,10 +304,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn global_settings_builder_should_fails_and_returns_an_error_if_local_ip_is_invalid() {
|
fn global_settings_builder_should_fails_and_returns_an_error_if_local_ip_is_invalid() {
|
||||||
let errors = GlobalSettingsBuilder::new()
|
let errors = GlobalSettingsBuilder::new().with_local_ip("invalid").build().unwrap_err();
|
||||||
.with_local_ip("invalid")
|
|
||||||
.build()
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(errors.len(), 1);
|
assert_eq!(errors.len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -63,10 +63,7 @@ impl Default for HrmpChannelConfigBuilder<Initial> {
|
|||||||
|
|
||||||
impl<A> HrmpChannelConfigBuilder<A> {
|
impl<A> HrmpChannelConfigBuilder<A> {
|
||||||
fn transition<B>(&self, config: HrmpChannelConfig) -> HrmpChannelConfigBuilder<B> {
|
fn transition<B>(&self, config: HrmpChannelConfig) -> HrmpChannelConfigBuilder<B> {
|
||||||
HrmpChannelConfigBuilder {
|
HrmpChannelConfigBuilder { config, _state: PhantomData }
|
||||||
config,
|
|
||||||
_state: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,38 +74,26 @@ impl HrmpChannelConfigBuilder<Initial> {
|
|||||||
|
|
||||||
/// Set the sending parachain ID.
|
/// Set the sending parachain ID.
|
||||||
pub fn with_sender(self, sender: ParaId) -> HrmpChannelConfigBuilder<WithSender> {
|
pub fn with_sender(self, sender: ParaId) -> HrmpChannelConfigBuilder<WithSender> {
|
||||||
self.transition(HrmpChannelConfig {
|
self.transition(HrmpChannelConfig { sender, ..self.config })
|
||||||
sender,
|
|
||||||
..self.config
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HrmpChannelConfigBuilder<WithSender> {
|
impl HrmpChannelConfigBuilder<WithSender> {
|
||||||
/// Set the receiving parachain ID.
|
/// Set the receiving parachain ID.
|
||||||
pub fn with_recipient(self, recipient: ParaId) -> HrmpChannelConfigBuilder<WithRecipient> {
|
pub fn with_recipient(self, recipient: ParaId) -> HrmpChannelConfigBuilder<WithRecipient> {
|
||||||
self.transition(HrmpChannelConfig {
|
self.transition(HrmpChannelConfig { recipient, ..self.config })
|
||||||
recipient,
|
|
||||||
..self.config
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HrmpChannelConfigBuilder<WithRecipient> {
|
impl HrmpChannelConfigBuilder<WithRecipient> {
|
||||||
/// Set the max capacity of messages in the channel.
|
/// Set the max capacity of messages in the channel.
|
||||||
pub fn with_max_capacity(self, max_capacity: u32) -> Self {
|
pub fn with_max_capacity(self, max_capacity: u32) -> Self {
|
||||||
self.transition(HrmpChannelConfig {
|
self.transition(HrmpChannelConfig { max_capacity, ..self.config })
|
||||||
max_capacity,
|
|
||||||
..self.config
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum size of a message in the channel.
|
/// Set the maximum size of a message in the channel.
|
||||||
pub fn with_max_message_size(self, max_message_size: u32) -> Self {
|
pub fn with_max_message_size(self, max_message_size: u32) -> Self {
|
||||||
self.transition(HrmpChannelConfig {
|
self.transition(HrmpChannelConfig { max_message_size, ..self.config })
|
||||||
max_message_size,
|
|
||||||
..self.config
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> HrmpChannelConfig {
|
pub fn build(self) -> HrmpChannelConfig {
|
||||||
|
|||||||
+64
-182
@@ -47,9 +47,7 @@ impl NetworkConfig {
|
|||||||
|
|
||||||
/// The relay chain of the network.
|
/// The relay chain of the network.
|
||||||
pub fn relaychain(&self) -> &RelaychainConfig {
|
pub fn relaychain(&self) -> &RelaychainConfig {
|
||||||
self.relaychain
|
self.relaychain.as_ref().expect(&format!("{RELAY_NOT_NONE}, {THIS_IS_A_BUG}"))
|
||||||
.as_ref()
|
|
||||||
.expect(&format!("{RELAY_NOT_NONE}, {THIS_IS_A_BUG}"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The teyrchains of the network.
|
/// The teyrchains of the network.
|
||||||
@@ -123,26 +121,14 @@ impl NetworkConfig {
|
|||||||
let relaychain_default_db_snapshot: Option<AssetLocation> =
|
let relaychain_default_db_snapshot: Option<AssetLocation> =
|
||||||
network_config.relaychain().default_db_snapshot().cloned();
|
network_config.relaychain().default_db_snapshot().cloned();
|
||||||
|
|
||||||
let default_args: Vec<Arg> = network_config
|
let default_args: Vec<Arg> =
|
||||||
.relaychain()
|
network_config.relaychain().default_args().into_iter().cloned().collect();
|
||||||
.default_args()
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut nodes: Vec<NodeConfig> = network_config
|
let mut nodes: Vec<NodeConfig> =
|
||||||
.relaychain()
|
network_config.relaychain().nodes().into_iter().cloned().collect();
|
||||||
.nodes()
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let group_nodes: Vec<GroupNodeConfig> = network_config
|
let group_nodes: Vec<GroupNodeConfig> =
|
||||||
.relaychain()
|
network_config.relaychain().group_node_configs().into_iter().cloned().collect();
|
||||||
.group_node_configs()
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(group) = group_nodes.iter().find(|n| n.count == 0) {
|
if let Some(group) = group_nodes.iter().find(|n| n.count == 0) {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
@@ -203,11 +189,8 @@ impl NetworkConfig {
|
|||||||
|
|
||||||
let default_args: Vec<Arg> = para.default_args().into_iter().cloned().collect();
|
let default_args: Vec<Arg> = para.default_args().into_iter().cloned().collect();
|
||||||
|
|
||||||
let group_collators: Vec<GroupNodeConfig> = para
|
let group_collators: Vec<GroupNodeConfig> =
|
||||||
.group_collators_configs()
|
para.group_collators_configs().into_iter().cloned().collect();
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if let Some(group) = group_collators.iter().find(|n| n.count == 0) {
|
if let Some(group) = group_collators.iter().find(|n| n.count == 0) {
|
||||||
return Err(anyhow!(
|
return Err(anyhow!(
|
||||||
@@ -287,9 +270,7 @@ fn populate_collator_with_defaults(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if teyrchain_default_db_snapshot.is_some() && collator.db_snapshot.is_none() {
|
if teyrchain_default_db_snapshot.is_some() && collator.db_snapshot.is_none() {
|
||||||
collator
|
collator.db_snapshot.clone_from(teyrchain_default_db_snapshot);
|
||||||
.db_snapshot
|
|
||||||
.clone_from(teyrchain_default_db_snapshot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !default_args.is_empty() && collator.args().is_empty() {
|
if !default_args.is_empty() && collator.args().is_empty() {
|
||||||
@@ -405,12 +386,7 @@ impl<A> NetworkConfigBuilder<A> {
|
|||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
errors: Vec<anyhow::Error>,
|
errors: Vec<anyhow::Error>,
|
||||||
) -> NetworkConfigBuilder<B> {
|
) -> NetworkConfigBuilder<B> {
|
||||||
NetworkConfigBuilder {
|
NetworkConfigBuilder { config, errors, validation_context, _state: PhantomData }
|
||||||
config,
|
|
||||||
errors,
|
|
||||||
validation_context,
|
|
||||||
_state: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,16 +429,9 @@ impl NetworkConfigBuilder<Initial> {
|
|||||||
RelaychainConfigBuilder<relaychain::Initial>,
|
RelaychainConfigBuilder<relaychain::Initial>,
|
||||||
) -> RelaychainConfigBuilder<relaychain::WithAtLeastOneNode>,
|
) -> RelaychainConfigBuilder<relaychain::WithAtLeastOneNode>,
|
||||||
) -> NetworkConfigBuilder<WithRelaychain> {
|
) -> NetworkConfigBuilder<WithRelaychain> {
|
||||||
match f(RelaychainConfigBuilder::new(
|
match f(RelaychainConfigBuilder::new(self.validation_context.clone())).build() {
|
||||||
self.validation_context.clone(),
|
|
||||||
))
|
|
||||||
.build()
|
|
||||||
{
|
|
||||||
Ok(relaychain) => Self::transition(
|
Ok(relaychain) => Self::transition(
|
||||||
NetworkConfig {
|
NetworkConfig { relaychain: Some(relaychain), ..self.config },
|
||||||
relaychain: Some(relaychain),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -479,10 +448,7 @@ impl NetworkConfigBuilder<WithRelaychain> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match f(GlobalSettingsBuilder::new()).build() {
|
match f(GlobalSettingsBuilder::new()).build() {
|
||||||
Ok(global_settings) => Self::transition(
|
Ok(global_settings) => Self::transition(
|
||||||
NetworkConfig {
|
NetworkConfig { global_settings, ..self.config },
|
||||||
global_settings,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -646,10 +612,7 @@ mod tests {
|
|||||||
.with_chain("myparachain1")
|
.with_chain("myparachain1")
|
||||||
.with_initial_balance(100_000)
|
.with_initial_balance(100_000)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("command1").validator(true)
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("command1")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_parachain(|parachain| {
|
.with_parachain(|parachain| {
|
||||||
@@ -658,10 +621,7 @@ mod tests {
|
|||||||
.with_chain("myparachain2")
|
.with_chain("myparachain2")
|
||||||
.with_initial_balance(0)
|
.with_initial_balance(0)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator2").with_command("command2").validator(true)
|
||||||
.with_name("collator2")
|
|
||||||
.with_command("command2")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_hrmp_channel(|hrmp_channel1| {
|
.with_hrmp_channel(|hrmp_channel1| {
|
||||||
@@ -679,9 +639,7 @@ mod tests {
|
|||||||
.with_max_message_size(250)
|
.with_max_message_size(250)
|
||||||
})
|
})
|
||||||
.with_global_settings(|global_settings| {
|
.with_global_settings(|global_settings| {
|
||||||
global_settings
|
global_settings.with_network_spawn_timeout(1200).with_node_spawn_timeout(240)
|
||||||
.with_network_spawn_timeout(1200)
|
|
||||||
.with_node_spawn_timeout(240)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -693,13 +651,7 @@ mod tests {
|
|||||||
assert_eq!(node.name(), "node");
|
assert_eq!(node.name(), "node");
|
||||||
assert_eq!(node.command().unwrap().as_str(), "command");
|
assert_eq!(node.command().unwrap().as_str(), "command");
|
||||||
assert!(node.is_validator());
|
assert!(node.is_validator());
|
||||||
assert_eq!(
|
assert_eq!(network_config.relaychain().random_nominators_count().unwrap(), 10);
|
||||||
network_config
|
|
||||||
.relaychain()
|
|
||||||
.random_nominators_count()
|
|
||||||
.unwrap(),
|
|
||||||
10
|
|
||||||
);
|
|
||||||
|
|
||||||
// teyrchains
|
// teyrchains
|
||||||
assert_eq!(network_config.teyrchains().len(), 2);
|
assert_eq!(network_config.teyrchains().len(), 2);
|
||||||
@@ -743,10 +695,7 @@ mod tests {
|
|||||||
assert_eq!(hrmp_channel2.max_message_size(), 250);
|
assert_eq!(hrmp_channel2.max_message_size(), 250);
|
||||||
|
|
||||||
// global settings
|
// global settings
|
||||||
assert_eq!(
|
assert_eq!(network_config.global_settings().network_spawn_timeout(), 1200);
|
||||||
network_config.global_settings().network_spawn_timeout(),
|
|
||||||
1200
|
|
||||||
);
|
|
||||||
assert_eq!(network_config.global_settings().node_spawn_timeout(), 240);
|
assert_eq!(network_config.global_settings().node_spawn_timeout(), 240);
|
||||||
assert!(network_config.global_settings().tear_down_on_failure());
|
assert!(network_config.global_settings().tear_down_on_failure());
|
||||||
}
|
}
|
||||||
@@ -767,10 +716,7 @@ mod tests {
|
|||||||
.with_chain("myparachain")
|
.with_chain("myparachain")
|
||||||
.with_initial_balance(100_000)
|
.with_initial_balance(100_000)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("command1").validator(true)
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("command1")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@@ -839,9 +785,7 @@ mod tests {
|
|||||||
.with_chain("myparachain1")
|
.with_chain("myparachain1")
|
||||||
.with_initial_balance(100_000)
|
.with_initial_balance(100_000)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("invalid command")
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("invalid command")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_parachain(|parachain| {
|
.with_parachain(|parachain| {
|
||||||
@@ -850,15 +794,14 @@ mod tests {
|
|||||||
.with_chain("myparachain2")
|
.with_chain("myparachain2")
|
||||||
.with_initial_balance(100_000)
|
.with_initial_balance(100_000)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator2").validator(true).with_resources(
|
||||||
.with_name("collator2")
|
|resources| {
|
||||||
.validator(true)
|
|
||||||
.with_resources(|resources| {
|
|
||||||
resources
|
resources
|
||||||
.with_limit_cpu("1000m")
|
.with_limit_cpu("1000m")
|
||||||
.with_request_memory("1Gi")
|
.with_request_memory("1Gi")
|
||||||
.with_request_cpu("invalid")
|
.with_request_cpu("invalid")
|
||||||
})
|
},
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@@ -891,10 +834,7 @@ mod tests {
|
|||||||
.with_chain("myparachain")
|
.with_chain("myparachain")
|
||||||
.with_initial_balance(100_000)
|
.with_initial_balance(100_000)
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("command").validator(true)
|
||||||
.with_name("collator")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_global_settings(|global_settings| {
|
.with_global_settings(|global_settings| {
|
||||||
@@ -968,10 +908,11 @@ mod tests {
|
|||||||
.with_default_args(vec![("-lparachain", "debug").into()])
|
.with_default_args(vec![("-lparachain", "debug").into()])
|
||||||
.with_validator(|node| node.with_name("alice"))
|
.with_validator(|node| node.with_name("alice"))
|
||||||
.with_validator(|node| {
|
.with_validator(|node| {
|
||||||
node.with_name("bob")
|
node.with_name("bob").invulnerable(false).bootnode(true).with_args(vec![(
|
||||||
.invulnerable(false)
|
"--database",
|
||||||
.bootnode(true)
|
"paritydb-experimental",
|
||||||
.with_args(vec![("--database", "paritydb-experimental").into()])
|
)
|
||||||
|
.into()])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@@ -1160,10 +1101,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn the_toml_config_with_custom_settings() {
|
fn the_toml_config_with_custom_settings() {
|
||||||
let settings = GlobalSettingsBuilder::new()
|
let settings =
|
||||||
.with_base_dir("/tmp/test-demo")
|
GlobalSettingsBuilder::new().with_base_dir("/tmp/test-demo").build().unwrap();
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let load_from_toml = NetworkConfig::load_from_toml_with_settings(
|
let load_from_toml = NetworkConfig::load_from_toml_with_settings(
|
||||||
"./testing/snapshots/0000-small-network.toml",
|
"./testing/snapshots/0000-small-network.toml",
|
||||||
@@ -1210,10 +1149,7 @@ mod tests {
|
|||||||
// We need to assert parts of the network config separately because the expected one contains the chain default context which
|
// We need to assert parts of the network config separately because the expected one contains the chain default context which
|
||||||
// is used for dumbing to tomp while the
|
// is used for dumbing to tomp while the
|
||||||
// while loaded
|
// while loaded
|
||||||
assert_eq!(
|
assert_eq!(expected.relaychain().chain(), load_from_toml.relaychain().chain());
|
||||||
expected.relaychain().chain(),
|
|
||||||
load_from_toml.relaychain().chain()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected.relaychain().default_args(),
|
expected.relaychain().default_args(),
|
||||||
load_from_toml.relaychain().default_args()
|
load_from_toml.relaychain().default_args()
|
||||||
@@ -1237,16 +1173,10 @@ mod tests {
|
|||||||
assert_eq!(expected_node.name(), loaded_node.name());
|
assert_eq!(expected_node.name(), loaded_node.name());
|
||||||
assert_eq!(expected_node.command(), loaded_node.command());
|
assert_eq!(expected_node.command(), loaded_node.command());
|
||||||
assert_eq!(expected_node.args(), loaded_node.args());
|
assert_eq!(expected_node.args(), loaded_node.args());
|
||||||
assert_eq!(
|
assert_eq!(expected_node.is_invulnerable(), loaded_node.is_invulnerable());
|
||||||
expected_node.is_invulnerable(),
|
|
||||||
loaded_node.is_invulnerable()
|
|
||||||
);
|
|
||||||
assert_eq!(expected_node.is_validator(), loaded_node.is_validator());
|
assert_eq!(expected_node.is_validator(), loaded_node.is_validator());
|
||||||
assert_eq!(expected_node.is_bootnode(), loaded_node.is_bootnode());
|
assert_eq!(expected_node.is_bootnode(), loaded_node.is_bootnode());
|
||||||
assert_eq!(
|
assert_eq!(expected_node.initial_balance(), loaded_node.initial_balance());
|
||||||
expected_node.initial_balance(),
|
|
||||||
loaded_node.initial_balance()
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1392,21 +1322,12 @@ mod tests {
|
|||||||
assert_eq!(expected_node.args(), loaded_node.args());
|
assert_eq!(expected_node.args(), loaded_node.args());
|
||||||
assert_eq!(expected_node.is_validator(), loaded_node.is_validator());
|
assert_eq!(expected_node.is_validator(), loaded_node.is_validator());
|
||||||
assert_eq!(expected_node.is_bootnode(), loaded_node.is_bootnode());
|
assert_eq!(expected_node.is_bootnode(), loaded_node.is_bootnode());
|
||||||
assert_eq!(
|
assert_eq!(expected_node.initial_balance(), loaded_node.initial_balance());
|
||||||
expected_node.initial_balance(),
|
assert_eq!(expected_node.is_invulnerable(), loaded_node.is_invulnerable());
|
||||||
loaded_node.initial_balance()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
expected_node.is_invulnerable(),
|
|
||||||
loaded_node.is_invulnerable()
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expected
|
expected.teyrchains().iter().zip(load_from_toml.teyrchains().iter()).for_each(
|
||||||
.teyrchains()
|
|(expected_parachain, loaded_parachain)| {
|
||||||
.iter()
|
|
||||||
.zip(load_from_toml.teyrchains().iter())
|
|
||||||
.for_each(|(expected_parachain, loaded_parachain)| {
|
|
||||||
assert_eq!(expected_parachain.id(), loaded_parachain.id());
|
assert_eq!(expected_parachain.id(), loaded_parachain.id());
|
||||||
assert_eq!(expected_parachain.chain(), loaded_parachain.chain());
|
assert_eq!(expected_parachain.chain(), loaded_parachain.chain());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1429,10 +1350,7 @@ mod tests {
|
|||||||
expected_parachain.default_command(),
|
expected_parachain.default_command(),
|
||||||
loaded_parachain.default_command()
|
loaded_parachain.default_command()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(expected_parachain.default_image(), loaded_parachain.default_image());
|
||||||
expected_parachain.default_image(),
|
|
||||||
loaded_parachain.default_image()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected_parachain.collators().len(),
|
expected_parachain.collators().len(),
|
||||||
loaded_parachain.collators().len()
|
loaded_parachain.collators().len()
|
||||||
@@ -1449,10 +1367,7 @@ mod tests {
|
|||||||
expected_collator.is_validator(),
|
expected_collator.is_validator(),
|
||||||
loaded_collator.is_validator()
|
loaded_collator.is_validator()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(expected_collator.is_bootnode(), loaded_collator.is_bootnode());
|
||||||
expected_collator.is_bootnode(),
|
|
||||||
loaded_collator.is_bootnode()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected_collator.is_invulnerable(),
|
expected_collator.is_invulnerable(),
|
||||||
loaded_collator.is_invulnerable()
|
loaded_collator.is_invulnerable()
|
||||||
@@ -1462,18 +1377,13 @@ mod tests {
|
|||||||
loaded_collator.initial_balance()
|
loaded_collator.initial_balance()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
|
||||||
expected
|
|
||||||
.hrmp_channels()
|
|
||||||
.iter()
|
|
||||||
.zip(load_from_toml.hrmp_channels().iter())
|
|
||||||
.for_each(|(expected_hrmp_channel, loaded_hrmp_channel)| {
|
|
||||||
assert_eq!(expected_hrmp_channel.sender(), loaded_hrmp_channel.sender());
|
|
||||||
assert_eq!(
|
|
||||||
expected_hrmp_channel.recipient(),
|
|
||||||
loaded_hrmp_channel.recipient()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expected.hrmp_channels().iter().zip(load_from_toml.hrmp_channels().iter()).for_each(
|
||||||
|
|(expected_hrmp_channel, loaded_hrmp_channel)| {
|
||||||
|
assert_eq!(expected_hrmp_channel.sender(), loaded_hrmp_channel.sender());
|
||||||
|
assert_eq!(expected_hrmp_channel.recipient(), loaded_hrmp_channel.recipient());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected_hrmp_channel.max_capacity(),
|
expected_hrmp_channel.max_capacity(),
|
||||||
loaded_hrmp_channel.max_capacity()
|
loaded_hrmp_channel.max_capacity()
|
||||||
@@ -1482,7 +1392,8 @@ mod tests {
|
|||||||
expected_hrmp_channel.max_message_size(),
|
expected_hrmp_channel.max_message_size(),
|
||||||
loaded_hrmp_channel.max_message_size()
|
loaded_hrmp_channel.max_message_size()
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1558,11 +1469,8 @@ mod tests {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
expected
|
expected.teyrchains().iter().zip(load_from_toml.teyrchains().iter()).for_each(
|
||||||
.teyrchains()
|
|(expected_parachain, loaded_parachain)| {
|
||||||
.iter()
|
|
||||||
.zip(load_from_toml.teyrchains().iter())
|
|
||||||
.for_each(|(expected_parachain, loaded_parachain)| {
|
|
||||||
assert_eq!(expected_parachain.id(), loaded_parachain.id());
|
assert_eq!(expected_parachain.id(), loaded_parachain.id());
|
||||||
assert_eq!(expected_parachain.chain(), loaded_parachain.chain());
|
assert_eq!(expected_parachain.chain(), loaded_parachain.chain());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1585,10 +1493,7 @@ mod tests {
|
|||||||
expected_parachain.default_command(),
|
expected_parachain.default_command(),
|
||||||
loaded_parachain.default_command()
|
loaded_parachain.default_command()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(expected_parachain.default_image(), loaded_parachain.default_image());
|
||||||
expected_parachain.default_image(),
|
|
||||||
loaded_parachain.default_image()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected_parachain.collators().len(),
|
expected_parachain.collators().len(),
|
||||||
loaded_parachain.collators().len()
|
loaded_parachain.collators().len()
|
||||||
@@ -1605,10 +1510,7 @@ mod tests {
|
|||||||
expected_collator.is_validator(),
|
expected_collator.is_validator(),
|
||||||
loaded_collator.is_validator()
|
loaded_collator.is_validator()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(expected_collator.is_bootnode(), loaded_collator.is_bootnode());
|
||||||
expected_collator.is_bootnode(),
|
|
||||||
loaded_collator.is_bootnode()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
expected_collator.is_invulnerable(),
|
expected_collator.is_invulnerable(),
|
||||||
loaded_collator.is_invulnerable()
|
loaded_collator.is_invulnerable()
|
||||||
@@ -1618,7 +1520,8 @@ mod tests {
|
|||||||
loaded_collator.initial_balance()
|
loaded_collator.initial_balance()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1649,17 +1552,13 @@ mod tests {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(errors.first().unwrap().to_string(), "relaychain.chain: can't be empty");
|
||||||
errors.first().unwrap().to_string(),
|
|
||||||
"relaychain.chain: can't be empty"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn with_chain_and_nodes_should_fail_with_empty_node_list() {
|
fn with_chain_and_nodes_should_fail_with_empty_node_list() {
|
||||||
let errors = NetworkConfigBuilder::with_chain_and_nodes("rococo-local", vec![])
|
let errors =
|
||||||
.build()
|
NetworkConfigBuilder::with_chain_and_nodes("rococo-local", vec![]).build().unwrap_err();
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
errors.first().unwrap().to_string(),
|
errors.first().unwrap().to_string(),
|
||||||
@@ -1726,10 +1625,7 @@ mod tests {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(errors.first().unwrap().to_string(), "teyrchain[1].can't be empty");
|
||||||
errors.first().unwrap().to_string(),
|
|
||||||
"teyrchain[1].can't be empty"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1789,10 +1685,7 @@ mod tests {
|
|||||||
.with_fullnode(|node| node.with_name("node").with_command("command"))
|
.with_fullnode(|node| node.with_name("node").with_command("command"))
|
||||||
})
|
})
|
||||||
.with_parachain(|parachain| {
|
.with_parachain(|parachain| {
|
||||||
parachain
|
parachain.with_id(1).with_chain("myparachain1").with_collator(|collator| {
|
||||||
.with_id(1)
|
|
||||||
.with_chain("myparachain1")
|
|
||||||
.with_collator(|collator| {
|
|
||||||
collator.with_name("collator1").with_command("command1")
|
collator.with_name("collator1").with_command("command1")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1821,10 +1714,7 @@ mod tests {
|
|||||||
.with_fullnode(|node| node.with_name("node").with_command("command"))
|
.with_fullnode(|node| node.with_name("node").with_command("command"))
|
||||||
})
|
})
|
||||||
.with_parachain(|parachain| {
|
.with_parachain(|parachain| {
|
||||||
parachain
|
parachain.with_id(1).with_chain("myparachain1").with_collator(|collator| {
|
||||||
.with_id(1)
|
|
||||||
.with_chain("myparachain1")
|
|
||||||
.with_collator(|collator| {
|
|
||||||
collator.with_name("collator1").with_command("command1")
|
collator.with_name("collator1").with_command("command1")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -1854,10 +1744,7 @@ mod tests {
|
|||||||
NetworkConfig::load_from_toml("./testing/snapshots/0006-without-rc-chain-name.toml")
|
NetworkConfig::load_from_toml("./testing/snapshots/0006-without-rc-chain-name.toml")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!("rococo-local", loaded_from_toml.relaychain().chain().as_str());
|
||||||
"rococo-local",
|
|
||||||
loaded_from_toml.relaychain().chain().as_str()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1868,12 +1755,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
loaded_from_toml
|
loaded_from_toml.relaychain().nodes().iter().filter(|n| n.name() == "alice").count(),
|
||||||
.relaychain()
|
|
||||||
.nodes()
|
|
||||||
.iter()
|
|
||||||
.filter(|n| n.name() == "alice")
|
|
||||||
.count(),
|
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
+33
-137
@@ -178,9 +178,7 @@ impl Default for RelaychainConfigBuilder<Initial> {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
config: RelaychainConfig {
|
config: RelaychainConfig {
|
||||||
chain: "default"
|
chain: "default".try_into().expect(&format!("{DEFAULT_TYPESTATE} {THIS_IS_A_BUG}")),
|
||||||
.try_into()
|
|
||||||
.expect(&format!("{DEFAULT_TYPESTATE} {THIS_IS_A_BUG}")),
|
|
||||||
default_command: None,
|
default_command: None,
|
||||||
default_image: None,
|
default_image: None,
|
||||||
default_resources: None,
|
default_resources: None,
|
||||||
@@ -213,12 +211,7 @@ impl<A> RelaychainConfigBuilder<A> {
|
|||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
errors: Vec<anyhow::Error>,
|
errors: Vec<anyhow::Error>,
|
||||||
) -> RelaychainConfigBuilder<B> {
|
) -> RelaychainConfigBuilder<B> {
|
||||||
RelaychainConfigBuilder {
|
RelaychainConfigBuilder { config, validation_context, errors, _state: PhantomData }
|
||||||
config,
|
|
||||||
validation_context,
|
|
||||||
errors,
|
|
||||||
_state: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_chain_context(&self) -> ChainDefaultContext {
|
fn default_chain_context(&self) -> ChainDefaultContext {
|
||||||
@@ -235,10 +228,7 @@ impl<A> RelaychainConfigBuilder<A> {
|
|||||||
where
|
where
|
||||||
F: FnOnce(NodeConfigBuilder<node::Initial>) -> NodeConfigBuilder<node::Buildable>,
|
F: FnOnce(NodeConfigBuilder<node::Initial>) -> NodeConfigBuilder<node::Buildable>,
|
||||||
{
|
{
|
||||||
f(NodeConfigBuilder::new(
|
f(NodeConfigBuilder::new(self.default_chain_context(), self.validation_context.clone()))
|
||||||
self.default_chain_context(),
|
|
||||||
self.validation_context.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,10 +236,7 @@ impl RelaychainConfigBuilder<Initial> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> RelaychainConfigBuilder<Initial> {
|
) -> RelaychainConfigBuilder<Initial> {
|
||||||
Self {
|
Self { validation_context, ..Self::default() }
|
||||||
validation_context,
|
|
||||||
..Self::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the chain name (e.g. rococo-local).
|
/// Set the chain name (e.g. rococo-local).
|
||||||
@@ -260,10 +247,7 @@ impl RelaychainConfigBuilder<Initial> {
|
|||||||
{
|
{
|
||||||
match chain.try_into() {
|
match chain.try_into() {
|
||||||
Ok(chain) => Self::transition(
|
Ok(chain) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { chain, ..self.config },
|
||||||
chain,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -285,10 +269,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
{
|
{
|
||||||
match command.try_into() {
|
match command.try_into() {
|
||||||
Ok(command) => Self::transition(
|
Ok(command) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { default_command: Some(command), ..self.config },
|
||||||
default_command: Some(command),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -308,10 +289,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
{
|
{
|
||||||
match image.try_into() {
|
match image.try_into() {
|
||||||
Ok(image) => Self::transition(
|
Ok(image) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { default_image: Some(image), ..self.config },
|
||||||
default_image: Some(image),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -330,10 +308,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match f(ResourcesBuilder::new()).build() {
|
match f(ResourcesBuilder::new()).build() {
|
||||||
Ok(default_resources) => Self::transition(
|
Ok(default_resources) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { default_resources: Some(default_resources), ..self.config },
|
||||||
default_resources: Some(default_resources),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -354,10 +329,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the default database snapshot location that will be used for state. Can be overridden.
|
/// Set the default database snapshot location that will be used for state. Can be overridden.
|
||||||
pub fn with_default_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_default_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { default_db_snapshot: Some(location.into()), ..self.config },
|
||||||
default_db_snapshot: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -366,10 +338,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the default arguments that will be used to execute the node command. Can be overridden.
|
/// Set the default arguments that will be used to execute the node command. Can be overridden.
|
||||||
pub fn with_default_args(self, args: Vec<Arg>) -> Self {
|
pub fn with_default_args(self, args: Vec<Arg>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { default_args: args, ..self.config },
|
||||||
default_args: args,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -378,10 +347,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the location of a pre-existing chain specification for the relay chain.
|
/// Set the location of a pre-existing chain specification for the relay chain.
|
||||||
pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { chain_spec_path: Some(location.into()), ..self.config },
|
||||||
chain_spec_path: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -390,10 +356,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the location of a wasm to override the chain-spec.
|
/// Set the location of a wasm to override the chain-spec.
|
||||||
pub fn with_wasm_override(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_wasm_override(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { wasm_override: Some(location.into()), ..self.config },
|
||||||
wasm_override: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -402,10 +365,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the chain-spec command _template_ for the relay chain.
|
/// Set the chain-spec command _template_ for the relay chain.
|
||||||
pub fn with_chain_spec_command(self, cmd_template: impl Into<String>) -> Self {
|
pub fn with_chain_spec_command(self, cmd_template: impl Into<String>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { chain_spec_command: Some(cmd_template.into()), ..self.config },
|
||||||
chain_spec_command: Some(cmd_template.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -425,10 +385,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
ChainSpecRuntime::new(location.into())
|
ChainSpecRuntime::new(location.into())
|
||||||
};
|
};
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { chain_spec_runtime: Some(chain_spec_runtime), ..self.config },
|
||||||
chain_spec_runtime: Some(chain_spec_runtime),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -437,10 +394,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set if the chain-spec command needs to be run locally or not (false by default)
|
/// Set if the chain-spec command needs to be run locally or not (false by default)
|
||||||
pub fn chain_spec_command_is_local(self, choice: bool) -> Self {
|
pub fn chain_spec_command_is_local(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { chain_spec_command_is_local: choice, ..self.config },
|
||||||
chain_spec_command_is_local: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -473,10 +427,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the maximum number of nominations to create per nominator.
|
/// Set the maximum number of nominations to create per nominator.
|
||||||
pub fn with_max_nominations(self, max_nominations: u8) -> Self {
|
pub fn with_max_nominations(self, max_nominations: u8) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { max_nominations: Some(max_nominations), ..self.config },
|
||||||
max_nominations: Some(max_nominations),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -502,10 +453,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
||||||
match self.create_node_builder(f).validator(true).build() {
|
match self.create_node_builder(f).validator(true).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: [self.config.nodes, vec![node]].concat(), ..self.config },
|
||||||
nodes: [self.config.nodes, vec![node]].concat(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -531,10 +479,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
||||||
match self.create_node_builder(f).validator(false).build() {
|
match self.create_node_builder(f).validator(false).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: [self.config.nodes, vec![node]].concat(), ..self.config },
|
||||||
nodes: [self.config.nodes, vec![node]].concat(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -565,10 +510,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
||||||
match self.create_node_builder(f).build() {
|
match self.create_node_builder(f).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: vec![node], ..self.config },
|
||||||
nodes: vec![node],
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -598,10 +540,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
.build()
|
.build()
|
||||||
{
|
{
|
||||||
Ok(group_node) => Self::transition(
|
Ok(group_node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { node_groups: vec![group_node], ..self.config },
|
||||||
node_groups: vec![group_node],
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -622,10 +561,7 @@ impl RelaychainConfigBuilder<WithChain> {
|
|||||||
/// Set the location or inline value of a json to override the raw chain-spec.
|
/// Set the location or inline value of a json to override the raw chain-spec.
|
||||||
pub fn with_raw_spec_override(self, overrides: impl Into<JsonOverrides>) -> Self {
|
pub fn with_raw_spec_override(self, overrides: impl Into<JsonOverrides>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { raw_spec_override: Some(overrides.into()), ..self.config },
|
||||||
raw_spec_override: Some(overrides.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -641,10 +577,7 @@ impl RelaychainConfigBuilder<WithAtLeastOneNode> {
|
|||||||
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
) -> RelaychainConfigBuilder<WithAtLeastOneNode> {
|
||||||
match self.create_node_builder(f).validator(true).build() {
|
match self.create_node_builder(f).validator(true).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: [self.config.nodes, vec![node]].concat(), ..self.config },
|
||||||
nodes: [self.config.nodes, vec![node]].concat(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -670,10 +603,7 @@ impl RelaychainConfigBuilder<WithAtLeastOneNode> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match self.create_node_builder(f).validator(false).build() {
|
match self.create_node_builder(f).validator(false).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: [self.config.nodes, vec![node]].concat(), ..self.config },
|
||||||
nodes: [self.config.nodes, vec![node]].concat(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -704,10 +634,7 @@ impl RelaychainConfigBuilder<WithAtLeastOneNode> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match self.create_node_builder(f).build() {
|
match self.create_node_builder(f).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
RelaychainConfig {
|
RelaychainConfig { nodes: [self.config.nodes, vec![node]].concat(), ..self.config },
|
||||||
nodes: [self.config.nodes, vec![node]].concat(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -783,10 +710,7 @@ mod tests {
|
|||||||
.with_default_image("myrepo:myimage")
|
.with_default_image("myrepo:myimage")
|
||||||
.with_default_command("default_command")
|
.with_default_command("default_command")
|
||||||
.with_default_resources(|resources| {
|
.with_default_resources(|resources| {
|
||||||
resources
|
resources.with_limit_cpu("500M").with_limit_memory("1G").with_request_cpu("250M")
|
||||||
.with_limit_cpu("500M")
|
|
||||||
.with_limit_memory("1G")
|
|
||||||
.with_request_cpu("250M")
|
|
||||||
})
|
})
|
||||||
.with_default_db_snapshot("https://www.urltomysnapshot.com/file.tgz")
|
.with_default_db_snapshot("https://www.urltomysnapshot.com/file.tgz")
|
||||||
.with_chain_spec_path("./path/to/chain/spec.json")
|
.with_chain_spec_path("./path/to/chain/spec.json")
|
||||||
@@ -811,14 +735,8 @@ mod tests {
|
|||||||
assert_eq!(node2.name(), "node2");
|
assert_eq!(node2.name(), "node2");
|
||||||
assert_eq!(node2.command().unwrap().as_str(), "command2");
|
assert_eq!(node2.command().unwrap().as_str(), "command2");
|
||||||
assert!(node2.is_validator());
|
assert!(node2.is_validator());
|
||||||
assert_eq!(
|
assert_eq!(relaychain_config.default_command().unwrap().as_str(), "default_command");
|
||||||
relaychain_config.default_command().unwrap().as_str(),
|
assert_eq!(relaychain_config.default_image().unwrap().as_str(), "myrepo:myimage");
|
||||||
"default_command"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
relaychain_config.default_image().unwrap().as_str(),
|
|
||||||
"myrepo:myimage"
|
|
||||||
);
|
|
||||||
let default_resources = relaychain_config.default_resources().unwrap();
|
let default_resources = relaychain_config.default_resources().unwrap();
|
||||||
assert_eq!(default_resources.limit_cpu().unwrap().as_str(), "500M");
|
assert_eq!(default_resources.limit_cpu().unwrap().as_str(), "500M");
|
||||||
assert_eq!(default_resources.limit_memory().unwrap().as_str(), "1G");
|
assert_eq!(default_resources.limit_memory().unwrap().as_str(), "1G");
|
||||||
@@ -836,11 +754,7 @@ mod tests {
|
|||||||
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/runtime.wasm"
|
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/runtime.wasm"
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
relaychain_config
|
relaychain_config.chain_spec_runtime().unwrap().preset.as_deref(),
|
||||||
.chain_spec_runtime()
|
|
||||||
.unwrap()
|
|
||||||
.preset
|
|
||||||
.as_deref(),
|
|
||||||
Some("local_testnet")
|
Some("local_testnet")
|
||||||
);
|
);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@@ -848,10 +762,7 @@ mod tests {
|
|||||||
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/override/runtime.wasm"
|
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/override/runtime.wasm"
|
||||||
));
|
));
|
||||||
let args: Vec<Arg> = vec![("--arg1", "value1").into(), "--option2".into()];
|
let args: Vec<Arg> = vec![("--arg1", "value1").into(), "--option2".into()];
|
||||||
assert_eq!(
|
assert_eq!(relaychain_config.default_args(), args.iter().collect::<Vec<_>>());
|
||||||
relaychain_config.default_args(),
|
|
||||||
args.iter().collect::<Vec<_>>()
|
|
||||||
);
|
|
||||||
assert_eq!(relaychain_config.random_nominators_count().unwrap(), 42);
|
assert_eq!(relaychain_config.random_nominators_count().unwrap(), 42);
|
||||||
assert_eq!(relaychain_config.max_nominations().unwrap(), 5);
|
assert_eq!(relaychain_config.max_nominations().unwrap(), 5);
|
||||||
|
|
||||||
@@ -914,9 +825,7 @@ mod tests {
|
|||||||
let errors = RelaychainConfigBuilder::new(Default::default())
|
let errors = RelaychainConfigBuilder::new(Default::default())
|
||||||
.with_chain("chain")
|
.with_chain("chain")
|
||||||
.with_default_resources(|default_resources| {
|
.with_default_resources(|default_resources| {
|
||||||
default_resources
|
default_resources.with_limit_memory("100m").with_request_cpu("invalid")
|
||||||
.with_limit_memory("100m")
|
|
||||||
.with_request_cpu("invalid")
|
|
||||||
})
|
})
|
||||||
.with_validator(|node| node.with_name("node").with_command("command"))
|
.with_validator(|node| node.with_name("node").with_command("command"))
|
||||||
.build()
|
.build()
|
||||||
@@ -1040,14 +949,7 @@ mod tests {
|
|||||||
assert_eq!(relaychain_config.chain().as_str(), "chain");
|
assert_eq!(relaychain_config.chain().as_str(), "chain");
|
||||||
assert_eq!(relaychain_config.nodes().len(), 1);
|
assert_eq!(relaychain_config.nodes().len(), 1);
|
||||||
assert_eq!(relaychain_config.group_node_configs().len(), 1);
|
assert_eq!(relaychain_config.group_node_configs().len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(relaychain_config.group_node_configs().first().unwrap().count, 2);
|
||||||
relaychain_config
|
|
||||||
.group_node_configs()
|
|
||||||
.first()
|
|
||||||
.unwrap()
|
|
||||||
.count,
|
|
||||||
2
|
|
||||||
);
|
|
||||||
let &node = relaychain_config.nodes().first().unwrap();
|
let &node = relaychain_config.nodes().first().unwrap();
|
||||||
assert_eq!(node.name(), "node");
|
assert_eq!(node.name(), "node");
|
||||||
assert_eq!(node.command().unwrap().as_str(), "node_command");
|
assert_eq!(node.command().unwrap().as_str(), "node_command");
|
||||||
@@ -1055,14 +957,8 @@ mod tests {
|
|||||||
let group_nodes = relaychain_config.group_node_configs();
|
let group_nodes = relaychain_config.group_node_configs();
|
||||||
let group_base_node = group_nodes.first().unwrap();
|
let group_base_node = group_nodes.first().unwrap();
|
||||||
assert_eq!(group_base_node.base_config.name(), "group_node");
|
assert_eq!(group_base_node.base_config.name(), "group_node");
|
||||||
assert_eq!(
|
assert_eq!(group_base_node.base_config.command().unwrap().as_str(), "some_command");
|
||||||
group_base_node.base_config.command().unwrap().as_str(),
|
assert_eq!(group_base_node.base_config.image().unwrap().as_str(), "repo:image");
|
||||||
"some_command"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
group_base_node.base_config.image().unwrap().as_str(),
|
|
||||||
"repo:image"
|
|
||||||
);
|
|
||||||
assert!(group_base_node.base_config.is_validator());
|
assert!(group_base_node.base_config.is_validator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,9 +37,8 @@ pub fn generate_unique_node_name(
|
|||||||
node_name: impl Into<String>,
|
node_name: impl Into<String>,
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut context = validation_context
|
let mut context =
|
||||||
.try_borrow_mut()
|
validation_context.try_borrow_mut().expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
||||||
.expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
|
||||||
|
|
||||||
generate_unique_node_name_from_names(node_name, &mut context.used_nodes_names)
|
generate_unique_node_name_from_names(node_name, &mut context.used_nodes_names)
|
||||||
}
|
}
|
||||||
@@ -87,9 +86,8 @@ pub fn ensure_port_unique(
|
|||||||
port: Port,
|
port: Port,
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
let mut context = validation_context
|
let mut context =
|
||||||
.try_borrow_mut()
|
validation_context.try_borrow_mut().expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
||||||
.expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
|
||||||
|
|
||||||
if !context.used_ports.contains(&port) {
|
if !context.used_ports.contains(&port) {
|
||||||
context.used_ports.push(port);
|
context.used_ports.push(port);
|
||||||
@@ -103,9 +101,8 @@ pub fn generate_unique_para_id(
|
|||||||
para_id: ParaId,
|
para_id: ParaId,
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let mut context = validation_context
|
let mut context =
|
||||||
.try_borrow_mut()
|
validation_context.try_borrow_mut().expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
||||||
.expect(&format!("{BORROWABLE}, {THIS_IS_A_BUG}"));
|
|
||||||
|
|
||||||
if let Some(suffix) = context.used_para_ids.get_mut(¶_id) {
|
if let Some(suffix) = context.used_para_ids.get_mut(¶_id) {
|
||||||
*suffix += 1;
|
*suffix += 1;
|
||||||
|
|||||||
@@ -55,10 +55,7 @@ pub struct EnvVar {
|
|||||||
|
|
||||||
impl From<(&str, &str)> for EnvVar {
|
impl From<(&str, &str)> for EnvVar {
|
||||||
fn from((name, value): (&str, &str)) -> Self {
|
fn from((name, value): (&str, &str)) -> Self {
|
||||||
Self {
|
Self { name: name.to_owned(), value: value.to_owned() }
|
||||||
name: name.to_owned(),
|
|
||||||
value: value.to_owned(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,12 +412,7 @@ impl<A> NodeConfigBuilder<A> {
|
|||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
errors: Vec<anyhow::Error>,
|
errors: Vec<anyhow::Error>,
|
||||||
) -> NodeConfigBuilder<B> {
|
) -> NodeConfigBuilder<B> {
|
||||||
NodeConfigBuilder {
|
NodeConfigBuilder { config, validation_context, errors, _state: PhantomData }
|
||||||
config,
|
|
||||||
validation_context,
|
|
||||||
errors,
|
|
||||||
_state: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,10 +442,7 @@ impl NodeConfigBuilder<Initial> {
|
|||||||
|
|
||||||
match ensure_value_is_not_empty(&name) {
|
match ensure_value_is_not_empty(&name) {
|
||||||
Ok(_) => Self::transition(
|
Ok(_) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { name, ..self.config },
|
||||||
name,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -479,10 +468,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
{
|
{
|
||||||
match command.try_into() {
|
match command.try_into() {
|
||||||
Ok(command) => Self::transition(
|
Ok(command) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { command: Some(command), ..self.config },
|
||||||
command: Some(command),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -502,10 +488,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
{
|
{
|
||||||
match subcommand.try_into() {
|
match subcommand.try_into() {
|
||||||
Ok(subcommand) => Self::transition(
|
Ok(subcommand) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { subcommand: Some(subcommand), ..self.config },
|
||||||
subcommand: Some(subcommand),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -525,10 +508,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
{
|
{
|
||||||
match image.try_into() {
|
match image.try_into() {
|
||||||
Ok(image) => Self::transition(
|
Ok(image) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { image: Some(image), ..self.config },
|
||||||
image: Some(image),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -542,23 +522,13 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
|
|
||||||
/// Set the arguments that will be used when launching the node. Override the default.
|
/// Set the arguments that will be used when launching the node. Override the default.
|
||||||
pub fn with_args(self, args: Vec<Arg>) -> Self {
|
pub fn with_args(self, args: Vec<Arg>) -> Self {
|
||||||
Self::transition(
|
Self::transition(NodeConfig { args, ..self.config }, self.validation_context, self.errors)
|
||||||
NodeConfig {
|
|
||||||
args,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
|
||||||
self.errors,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether the node is a validator.
|
/// Set whether the node is a validator.
|
||||||
pub fn validator(self, choice: bool) -> Self {
|
pub fn validator(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { is_validator: choice, ..self.config },
|
||||||
is_validator: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -567,10 +537,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set whether the node is invulnerable.
|
/// Set whether the node is invulnerable.
|
||||||
pub fn invulnerable(self, choice: bool) -> Self {
|
pub fn invulnerable(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { is_invulnerable: choice, ..self.config },
|
||||||
is_invulnerable: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -579,10 +546,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set whether the node is a bootnode.
|
/// Set whether the node is a bootnode.
|
||||||
pub fn bootnode(self, choice: bool) -> Self {
|
pub fn bootnode(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { is_bootnode: choice, ..self.config },
|
||||||
is_bootnode: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -591,10 +555,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Override the EVM session key to use for the node
|
/// Override the EVM session key to use for the node
|
||||||
pub fn with_override_eth_key(self, session_key: impl Into<String>) -> Self {
|
pub fn with_override_eth_key(self, session_key: impl Into<String>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { override_eth_key: Some(session_key.into()), ..self.config },
|
||||||
override_eth_key: Some(session_key.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -603,10 +564,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set the node initial balance.
|
/// Set the node initial balance.
|
||||||
pub fn with_initial_balance(self, initial_balance: u128) -> Self {
|
pub fn with_initial_balance(self, initial_balance: u128) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { initial_balance: initial_balance.into(), ..self.config },
|
||||||
initial_balance: initial_balance.into(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -616,11 +574,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_env(self, env: Vec<impl Into<EnvVar>>) -> Self {
|
pub fn with_env(self, env: Vec<impl Into<EnvVar>>) -> Self {
|
||||||
let env = env.into_iter().map(|var| var.into()).collect::<Vec<_>>();
|
let env = env.into_iter().map(|var| var.into()).collect::<Vec<_>>();
|
||||||
|
|
||||||
Self::transition(
|
Self::transition(NodeConfig { env, ..self.config }, self.validation_context, self.errors)
|
||||||
NodeConfig { env, ..self.config },
|
|
||||||
self.validation_context,
|
|
||||||
self.errors,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the bootnodes addresses that the node will try to connect to. Override the default.
|
/// Set the bootnodes addresses that the node will try to connect to. Override the default.
|
||||||
@@ -645,10 +599,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { bootnodes_addresses: addrs, ..self.config },
|
||||||
bootnodes_addresses: addrs,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
merge_errors_vecs(self.errors, errors),
|
merge_errors_vecs(self.errors, errors),
|
||||||
)
|
)
|
||||||
@@ -658,10 +609,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_resources(self, f: impl FnOnce(ResourcesBuilder) -> ResourcesBuilder) -> Self {
|
pub fn with_resources(self, f: impl FnOnce(ResourcesBuilder) -> ResourcesBuilder) -> Self {
|
||||||
match f(ResourcesBuilder::new()).build() {
|
match f(ResourcesBuilder::new()).build() {
|
||||||
Ok(resources) => Self::transition(
|
Ok(resources) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { resources: Some(resources), ..self.config },
|
||||||
resources: Some(resources),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -683,10 +631,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_ws_port(self, ws_port: Port) -> Self {
|
pub fn with_ws_port(self, ws_port: Port) -> Self {
|
||||||
match ensure_port_unique(ws_port, self.validation_context.clone()) {
|
match ensure_port_unique(ws_port, self.validation_context.clone()) {
|
||||||
Ok(_) => Self::transition(
|
Ok(_) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { ws_port: Some(ws_port), ..self.config },
|
||||||
ws_port: Some(ws_port),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -702,10 +647,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_rpc_port(self, rpc_port: Port) -> Self {
|
pub fn with_rpc_port(self, rpc_port: Port) -> Self {
|
||||||
match ensure_port_unique(rpc_port, self.validation_context.clone()) {
|
match ensure_port_unique(rpc_port, self.validation_context.clone()) {
|
||||||
Ok(_) => Self::transition(
|
Ok(_) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { rpc_port: Some(rpc_port), ..self.config },
|
||||||
rpc_port: Some(rpc_port),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -721,10 +663,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_prometheus_port(self, prometheus_port: Port) -> Self {
|
pub fn with_prometheus_port(self, prometheus_port: Port) -> Self {
|
||||||
match ensure_port_unique(prometheus_port, self.validation_context.clone()) {
|
match ensure_port_unique(prometheus_port, self.validation_context.clone()) {
|
||||||
Ok(_) => Self::transition(
|
Ok(_) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { prometheus_port: Some(prometheus_port), ..self.config },
|
||||||
prometheus_port: Some(prometheus_port),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -740,10 +679,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
pub fn with_p2p_port(self, p2p_port: Port) -> Self {
|
pub fn with_p2p_port(self, p2p_port: Port) -> Self {
|
||||||
match ensure_port_unique(p2p_port, self.validation_context.clone()) {
|
match ensure_port_unique(p2p_port, self.validation_context.clone()) {
|
||||||
Ok(_) => Self::transition(
|
Ok(_) => Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { p2p_port: Some(p2p_port), ..self.config },
|
||||||
p2p_port: Some(p2p_port),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -759,10 +695,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// if and only if the multiaddress is set to use `webrtc`.
|
/// if and only if the multiaddress is set to use `webrtc`.
|
||||||
pub fn with_p2p_cert_hash(self, p2p_cert_hash: impl Into<String>) -> Self {
|
pub fn with_p2p_cert_hash(self, p2p_cert_hash: impl Into<String>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { p2p_cert_hash: Some(p2p_cert_hash.into()), ..self.config },
|
||||||
p2p_cert_hash: Some(p2p_cert_hash.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -771,10 +704,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set the database snapshot that will be used to launch the node. Override the default.
|
/// Set the database snapshot that will be used to launch the node. Override the default.
|
||||||
pub fn with_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { db_snapshot: Some(location.into()), ..self.config },
|
||||||
db_snapshot: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -783,10 +713,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set the node log path that will be used to launch the node.
|
/// Set the node log path that will be used to launch the node.
|
||||||
pub fn with_log_path(self, log_path: impl Into<PathBuf>) -> Self {
|
pub fn with_log_path(self, log_path: impl Into<PathBuf>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { node_log_path: Some(log_path.into()), ..self.config },
|
||||||
node_log_path: Some(log_path.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -795,10 +722,7 @@ impl NodeConfigBuilder<Buildable> {
|
|||||||
/// Set the keystore path override.
|
/// Set the keystore path override.
|
||||||
pub fn with_keystore_path(self, keystore_path: impl Into<PathBuf>) -> Self {
|
pub fn with_keystore_path(self, keystore_path: impl Into<PathBuf>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
NodeConfig {
|
NodeConfig { keystore_path: Some(keystore_path.into()), ..self.config },
|
||||||
keystore_path: Some(keystore_path.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -869,13 +793,7 @@ impl GroupNodeConfigBuilder<Initial> {
|
|||||||
Err((_name, errors)) => (errors, NodeConfig::default()),
|
Err((_name, errors)) => (errors, NodeConfig::default()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self { base_config, count: 1, validation_context, errors, _state: PhantomData }
|
||||||
base_config,
|
|
||||||
count: 1,
|
|
||||||
validation_context,
|
|
||||||
errors,
|
|
||||||
_state: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the base node config using a closure.
|
/// Set the base node config using a closure.
|
||||||
@@ -932,10 +850,7 @@ impl GroupNodeConfigBuilder<Buildable> {
|
|||||||
return Err((self.base_config.name().to_string(), self.errors));
|
return Err((self.base_config.name().to_string(), self.errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(GroupNodeConfig {
|
Ok(GroupNodeConfig { base_config: self.base_config, count: self.count })
|
||||||
base_config: self.base_config,
|
|
||||||
count: self.count,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,10 +946,8 @@ mod tests {
|
|||||||
fn node_config_builder_should_use_unique_name_if_node_name_already_used() {
|
fn node_config_builder_should_use_unique_name_if_node_name_already_used() {
|
||||||
let mut used_nodes_names = HashSet::new();
|
let mut used_nodes_names = HashSet::new();
|
||||||
used_nodes_names.insert("mynode".into());
|
used_nodes_names.insert("mynode".into());
|
||||||
let validation_context = Rc::new(RefCell::new(ValidationContext {
|
let validation_context =
|
||||||
used_nodes_names,
|
Rc::new(RefCell::new(ValidationContext { used_nodes_names, ..Default::default() }));
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
let node_config =
|
let node_config =
|
||||||
NodeConfigBuilder::new(ChainDefaultContext::default(), validation_context)
|
NodeConfigBuilder::new(ChainDefaultContext::default(), validation_context)
|
||||||
.with_name("mynode")
|
.with_name("mynode")
|
||||||
@@ -1143,9 +1056,7 @@ mod tests {
|
|||||||
NodeConfigBuilder::new(ChainDefaultContext::default(), Default::default())
|
NodeConfigBuilder::new(ChainDefaultContext::default(), Default::default())
|
||||||
.with_name("node")
|
.with_name("node")
|
||||||
.with_resources(|resources| {
|
.with_resources(|resources| {
|
||||||
resources
|
resources.with_limit_cpu("invalid").with_request_memory("invalid")
|
||||||
.with_limit_cpu("invalid")
|
|
||||||
.with_request_memory("invalid")
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1171,9 +1082,7 @@ mod tests {
|
|||||||
.with_command("invalid command")
|
.with_command("invalid command")
|
||||||
.with_image("myinvalid.image")
|
.with_image("myinvalid.image")
|
||||||
.with_resources(|resources| {
|
.with_resources(|resources| {
|
||||||
resources
|
resources.with_limit_cpu("invalid").with_request_memory("invalid")
|
||||||
.with_limit_cpu("invalid")
|
|
||||||
.with_request_memory("invalid")
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1288,9 +1197,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn node_config_builder_should_fails_if_node_name_is_empty() {
|
fn node_config_builder_should_fails_if_node_name_is_empty() {
|
||||||
let validation_context = Rc::new(RefCell::new(ValidationContext {
|
let validation_context = Rc::new(RefCell::new(ValidationContext { ..Default::default() }));
|
||||||
..Default::default()
|
|
||||||
}));
|
|
||||||
|
|
||||||
let (_, errors) =
|
let (_, errors) =
|
||||||
NodeConfigBuilder::new(ChainDefaultContext::default(), validation_context)
|
NodeConfigBuilder::new(ChainDefaultContext::default(), validation_context)
|
||||||
@@ -1340,14 +1247,8 @@ mod tests {
|
|||||||
assert_eq!(group_config.count, 5);
|
assert_eq!(group_config.count, 5);
|
||||||
|
|
||||||
assert_eq!(group_config.base_config.name(), "node");
|
assert_eq!(group_config.base_config.name(), "node");
|
||||||
assert_eq!(
|
assert_eq!(group_config.base_config.command().unwrap().as_str(), "some_command");
|
||||||
group_config.base_config.command().unwrap().as_str(),
|
assert_eq!(group_config.base_config.image().unwrap().as_str(), "repo:image");
|
||||||
"some_command"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
group_config.base_config.image().unwrap().as_str(),
|
|
||||||
"repo:image"
|
|
||||||
);
|
|
||||||
assert!(group_config.base_config.is_validator());
|
assert!(group_config.base_config.is_validator());
|
||||||
assert!(group_config.base_config.is_invulnerable());
|
assert!(group_config.base_config.is_invulnerable());
|
||||||
assert!(group_config.base_config.is_bootnode());
|
assert!(group_config.base_config.is_bootnode());
|
||||||
|
|||||||
@@ -105,10 +105,7 @@ impl Serialize for Resources {
|
|||||||
if self.limit_memory.is_some() || self.limit_memory.is_some() {
|
if self.limit_memory.is_some() || self.limit_memory.is_some() {
|
||||||
state.serialize_field(
|
state.serialize_field(
|
||||||
"limits",
|
"limits",
|
||||||
&ResourcesField {
|
&ResourcesField { memory: self.limit_memory.clone(), cpu: self.limit_cpu.clone() },
|
||||||
memory: self.limit_memory.clone(),
|
|
||||||
cpu: self.limit_cpu.clone(),
|
|
||||||
},
|
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
state.skip_field("limits")?;
|
state.skip_field("limits")?;
|
||||||
@@ -210,10 +207,7 @@ impl ResourcesBuilder {
|
|||||||
{
|
{
|
||||||
match quantity.try_into() {
|
match quantity.try_into() {
|
||||||
Ok(quantity) => Self::transition(
|
Ok(quantity) => Self::transition(
|
||||||
Resources {
|
Resources { request_memory: Some(quantity), ..self.config },
|
||||||
request_memory: Some(quantity),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
@@ -231,10 +225,7 @@ impl ResourcesBuilder {
|
|||||||
{
|
{
|
||||||
match quantity.try_into() {
|
match quantity.try_into() {
|
||||||
Ok(quantity) => Self::transition(
|
Ok(quantity) => Self::transition(
|
||||||
Resources {
|
Resources { request_cpu: Some(quantity), ..self.config },
|
||||||
request_cpu: Some(quantity),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
@@ -252,10 +243,7 @@ impl ResourcesBuilder {
|
|||||||
{
|
{
|
||||||
match quantity.try_into() {
|
match quantity.try_into() {
|
||||||
Ok(quantity) => Self::transition(
|
Ok(quantity) => Self::transition(
|
||||||
Resources {
|
Resources { limit_memory: Some(quantity), ..self.config },
|
||||||
limit_memory: Some(quantity),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
@@ -273,10 +261,7 @@ impl ResourcesBuilder {
|
|||||||
{
|
{
|
||||||
match quantity.try_into() {
|
match quantity.try_into() {
|
||||||
Ok(quantity) => Self::transition(
|
Ok(quantity) => Self::transition(
|
||||||
Resources {
|
Resources { limit_cpu: Some(quantity), ..self.config },
|
||||||
limit_cpu: Some(quantity),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
@@ -304,10 +289,7 @@ mod tests {
|
|||||||
|
|
||||||
macro_rules! impl_resources_quantity_unit_test {
|
macro_rules! impl_resources_quantity_unit_test {
|
||||||
($val:literal) => {{
|
($val:literal) => {{
|
||||||
let resources = ResourcesBuilder::new()
|
let resources = ResourcesBuilder::new().with_request_memory($val).build().unwrap();
|
||||||
.with_request_memory($val)
|
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(resources.request_memory().unwrap().as_str(), $val);
|
assert_eq!(resources.request_memory().unwrap().as_str(), $val);
|
||||||
assert_eq!(resources.request_cpu(), None);
|
assert_eq!(resources.request_cpu(), None);
|
||||||
@@ -470,9 +452,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn resources_config_builder_should_fails_and_returns_multiple_error_if_couldnt_parse_multiple_fields(
|
fn resources_config_builder_should_fails_and_returns_multiple_error_if_couldnt_parse_multiple_fields(
|
||||||
) {
|
) {
|
||||||
let resources_builder = ResourcesBuilder::new()
|
let resources_builder =
|
||||||
.with_limit_cpu("invalid")
|
ResourcesBuilder::new().with_limit_cpu("invalid").with_request_memory("invalid");
|
||||||
.with_request_memory("invalid");
|
|
||||||
|
|
||||||
let errors = resources_builder.build().err().unwrap();
|
let errors = resources_builder.build().err().unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -430,10 +430,7 @@ where
|
|||||||
T: AsRef<str> + Clone,
|
T: AsRef<str> + Clone,
|
||||||
{
|
{
|
||||||
fn from((option, values): (&str, &[T])) -> Self {
|
fn from((option, values): (&str, &[T])) -> Self {
|
||||||
Self::Array(
|
Self::Array(option.to_owned(), values.iter().map(|v| v.as_ref().to_string()).collect())
|
||||||
option.to_owned(),
|
|
||||||
values.iter().map(|v| v.as_ref().to_string()).collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,10 +439,7 @@ where
|
|||||||
T: AsRef<str>,
|
T: AsRef<str>,
|
||||||
{
|
{
|
||||||
fn from((option, values): (&str, Vec<T>)) -> Self {
|
fn from((option, values): (&str, Vec<T>)) -> Self {
|
||||||
Self::Array(
|
Self::Array(option.to_owned(), values.into_iter().map(|v| v.as_ref().to_string()).collect())
|
||||||
option.to_owned(),
|
|
||||||
values.into_iter().map(|v| v.as_ref().to_string()).collect(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,17 +553,11 @@ pub struct ChainSpecRuntime {
|
|||||||
|
|
||||||
impl ChainSpecRuntime {
|
impl ChainSpecRuntime {
|
||||||
pub fn new(location: AssetLocation) -> Self {
|
pub fn new(location: AssetLocation) -> Self {
|
||||||
ChainSpecRuntime {
|
ChainSpecRuntime { location, preset: None }
|
||||||
location,
|
|
||||||
preset: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_preset(location: AssetLocation, preset: impl Into<String>) -> Self {
|
pub fn with_preset(location: AssetLocation, preset: impl Into<String>) -> Self {
|
||||||
ChainSpecRuntime {
|
ChainSpecRuntime { location, preset: Some(preset.into()) }
|
||||||
location,
|
|
||||||
preset: Some(preset.into()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,24 +813,15 @@ mod tests {
|
|||||||
fn converting_a_str_with_whitespaces_into_a_chain_should_fails() {
|
fn converting_a_str_with_whitespaces_into_a_chain_should_fails() {
|
||||||
let got: Result<Chain, ConversionError> = "my chain".try_into();
|
let got: Result<Chain, ConversionError> = "my chain".try_into();
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(got.clone().unwrap_err(), ConversionError::ContainsWhitespaces(_)));
|
||||||
got.clone().unwrap_err(),
|
assert_eq!(got.unwrap_err().to_string(), "'my chain' shouldn't contains whitespace");
|
||||||
ConversionError::ContainsWhitespaces(_)
|
|
||||||
));
|
|
||||||
assert_eq!(
|
|
||||||
got.unwrap_err().to_string(),
|
|
||||||
"'my chain' shouldn't contains whitespace"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn converting_an_empty_str_into_a_chain_should_fails() {
|
fn converting_an_empty_str_into_a_chain_should_fails() {
|
||||||
let got: Result<Chain, ConversionError> = "".try_into();
|
let got: Result<Chain, ConversionError> = "".try_into();
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(got.clone().unwrap_err(), ConversionError::CantBeEmpty));
|
||||||
got.clone().unwrap_err(),
|
|
||||||
ConversionError::CantBeEmpty
|
|
||||||
));
|
|
||||||
assert_eq!(got.unwrap_err().to_string(), "can't be empty");
|
assert_eq!(got.unwrap_err().to_string(), "can't be empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,34 +876,19 @@ mod tests {
|
|||||||
fn converting_a_str_with_whitespaces_into_a_command_should_fails() {
|
fn converting_a_str_with_whitespaces_into_a_command_should_fails() {
|
||||||
let got: Result<Command, ConversionError> = "my command".try_into();
|
let got: Result<Command, ConversionError> = "my command".try_into();
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(got.clone().unwrap_err(), ConversionError::ContainsWhitespaces(_)));
|
||||||
got.clone().unwrap_err(),
|
assert_eq!(got.unwrap_err().to_string(), "'my command' shouldn't contains whitespace");
|
||||||
ConversionError::ContainsWhitespaces(_)
|
|
||||||
));
|
|
||||||
assert_eq!(
|
|
||||||
got.unwrap_err().to_string(),
|
|
||||||
"'my command' shouldn't contains whitespace"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_convert_to_json_overrides() {
|
fn test_convert_to_json_overrides() {
|
||||||
let url: AssetLocation = "https://example.com/overrides.json".into();
|
let url: AssetLocation = "https://example.com/overrides.json".into();
|
||||||
assert!(matches!(
|
assert!(matches!(url.into(), JsonOverrides::Location(AssetLocation::Url(_))));
|
||||||
url.into(),
|
|
||||||
JsonOverrides::Location(AssetLocation::Url(_))
|
|
||||||
));
|
|
||||||
|
|
||||||
let path: AssetLocation = "/path/to/overrides.json".into();
|
let path: AssetLocation = "/path/to/overrides.json".into();
|
||||||
assert!(matches!(
|
assert!(matches!(path.into(), JsonOverrides::Location(AssetLocation::FilePath(_))));
|
||||||
path.into(),
|
|
||||||
JsonOverrides::Location(AssetLocation::FilePath(_))
|
|
||||||
));
|
|
||||||
|
|
||||||
let inline = serde_json::json!({ "para_id": 2000});
|
let inline = serde_json::json!({ "para_id": 2000});
|
||||||
assert!(matches!(
|
assert!(matches!(inline.into(), JsonOverrides::Json(serde_json::Value::Object(_))));
|
||||||
inline.into(),
|
|
||||||
JsonOverrides::Json(serde_json::Value::Object(_))
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-260
@@ -114,10 +114,7 @@ pub struct TeyrchainConfig {
|
|||||||
chain: Option<Chain>,
|
chain: Option<Chain>,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
registration_strategy: Option<RegistrationStrategy>,
|
registration_strategy: Option<RegistrationStrategy>,
|
||||||
#[serde(
|
#[serde(skip_serializing_if = "super::utils::is_true", default = "default_as_true")]
|
||||||
skip_serializing_if = "super::utils::is_true",
|
|
||||||
default = "default_as_true"
|
|
||||||
)]
|
|
||||||
onboard_as_teyrchain: bool,
|
onboard_as_teyrchain: bool,
|
||||||
#[serde(rename = "balance", default = "default_initial_balance")]
|
#[serde(rename = "balance", default = "default_initial_balance")]
|
||||||
initial_balance: U128,
|
initial_balance: U128,
|
||||||
@@ -432,10 +429,7 @@ impl<A, C> TeyrchainConfigBuilder<A, C> {
|
|||||||
where
|
where
|
||||||
F: FnOnce(NodeConfigBuilder<node::Initial>) -> NodeConfigBuilder<node::Buildable>,
|
F: FnOnce(NodeConfigBuilder<node::Initial>) -> NodeConfigBuilder<node::Buildable>,
|
||||||
{
|
{
|
||||||
f(NodeConfigBuilder::new(
|
f(NodeConfigBuilder::new(self.default_chain_context(), self.validation_context.clone()))
|
||||||
self.default_chain_context(),
|
|
||||||
self.validation_context.clone(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,10 +438,7 @@ impl TeyrchainConfigBuilder<Initial, Bootstrap> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> TeyrchainConfigBuilder<Initial, Bootstrap> {
|
) -> TeyrchainConfigBuilder<Initial, Bootstrap> {
|
||||||
Self {
|
Self { validation_context, ..Self::default() }
|
||||||
validation_context,
|
|
||||||
..Self::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,10 +447,7 @@ impl TeyrchainConfigBuilder<WithId, Bootstrap> {
|
|||||||
/// using an extrinsic or in genesis.
|
/// using an extrinsic or in genesis.
|
||||||
pub fn with_registration_strategy(self, strategy: RegistrationStrategy) -> Self {
|
pub fn with_registration_strategy(self, strategy: RegistrationStrategy) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { registration_strategy: Some(strategy), ..self.config },
|
||||||
registration_strategy: Some(strategy),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -484,10 +472,7 @@ impl TeyrchainConfigBuilder<WithId, Running> {
|
|||||||
),
|
),
|
||||||
RegistrationStrategy::Manual | RegistrationStrategy::UsingExtrinsic => {
|
RegistrationStrategy::Manual | RegistrationStrategy::UsingExtrinsic => {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { registration_strategy: Some(strategy), ..self.config },
|
||||||
registration_strategy: Some(strategy),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -501,10 +486,7 @@ impl TeyrchainConfigBuilder<Initial, Running> {
|
|||||||
pub fn new_with_running(
|
pub fn new_with_running(
|
||||||
validation_context: Rc<RefCell<ValidationContext>>,
|
validation_context: Rc<RefCell<ValidationContext>>,
|
||||||
) -> TeyrchainConfigBuilder<Initial, Running> {
|
) -> TeyrchainConfigBuilder<Initial, Running> {
|
||||||
let mut builder = Self {
|
let mut builder = Self { validation_context, ..Self::default() };
|
||||||
validation_context,
|
|
||||||
..Self::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// override the registration strategy
|
// override the registration strategy
|
||||||
builder.config.registration_strategy = Some(RegistrationStrategy::UsingExtrinsic);
|
builder.config.registration_strategy = Some(RegistrationStrategy::UsingExtrinsic);
|
||||||
@@ -517,11 +499,7 @@ impl<C: Context> TeyrchainConfigBuilder<Initial, C> {
|
|||||||
pub fn with_id(self, id: u32) -> TeyrchainConfigBuilder<WithId, C> {
|
pub fn with_id(self, id: u32) -> TeyrchainConfigBuilder<WithId, C> {
|
||||||
let unique_id = generate_unique_para_id(id, self.validation_context.clone());
|
let unique_id = generate_unique_para_id(id, self.validation_context.clone());
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { id, unique_id, ..self.config },
|
||||||
id,
|
|
||||||
unique_id,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -538,10 +516,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
{
|
{
|
||||||
match chain.try_into() {
|
match chain.try_into() {
|
||||||
Ok(chain) => Self::transition(
|
Ok(chain) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { chain: Some(chain), ..self.config },
|
||||||
chain: Some(chain),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -556,10 +531,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set whether the teyrchain should be onboarded or stay a parathread. Default is ```true```.
|
/// Set whether the teyrchain should be onboarded or stay a parathread. Default is ```true```.
|
||||||
pub fn onboard_as_teyrchain(self, choice: bool) -> Self {
|
pub fn onboard_as_teyrchain(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { onboard_as_teyrchain: choice, ..self.config },
|
||||||
onboard_as_teyrchain: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -573,10 +545,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the initial balance of the teyrchain account.
|
/// Set the initial balance of the teyrchain account.
|
||||||
pub fn with_initial_balance(self, initial_balance: u128) -> Self {
|
pub fn with_initial_balance(self, initial_balance: u128) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { initial_balance: initial_balance.into(), ..self.config },
|
||||||
initial_balance: initial_balance.into(),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -590,10 +559,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
{
|
{
|
||||||
match command.try_into() {
|
match command.try_into() {
|
||||||
Ok(command) => Self::transition(
|
Ok(command) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { default_command: Some(command), ..self.config },
|
||||||
default_command: Some(command),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -613,10 +579,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
{
|
{
|
||||||
match image.try_into() {
|
match image.try_into() {
|
||||||
Ok(image) => Self::transition(
|
Ok(image) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { default_image: Some(image), ..self.config },
|
||||||
default_image: Some(image),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -635,10 +598,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
match f(ResourcesBuilder::new()).build() {
|
match f(ResourcesBuilder::new()).build() {
|
||||||
Ok(default_resources) => Self::transition(
|
Ok(default_resources) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { default_resources: Some(default_resources), ..self.config },
|
||||||
default_resources: Some(default_resources),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -659,10 +619,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the default database snapshot location that will be used for state. Can be overridden.
|
/// Set the default database snapshot location that will be used for state. Can be overridden.
|
||||||
pub fn with_default_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_default_db_snapshot(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { default_db_snapshot: Some(location.into()), ..self.config },
|
||||||
default_db_snapshot: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -671,10 +628,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the default arguments that will be used to execute the collator command. Can be overridden.
|
/// Set the default arguments that will be used to execute the collator command. Can be overridden.
|
||||||
pub fn with_default_args(self, args: Vec<Arg>) -> Self {
|
pub fn with_default_args(self, args: Vec<Arg>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { default_args: args, ..self.config },
|
||||||
default_args: args,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -683,10 +637,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the location of a pre-existing genesis WASM runtime blob of the teyrchain.
|
/// Set the location of a pre-existing genesis WASM runtime blob of the teyrchain.
|
||||||
pub fn with_genesis_wasm_path(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_genesis_wasm_path(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { genesis_wasm_path: Some(location.into()), ..self.config },
|
||||||
genesis_wasm_path: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -700,20 +651,14 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
{
|
{
|
||||||
match command.try_into() {
|
match command.try_into() {
|
||||||
Ok(command) => Self::transition(
|
Ok(command) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { genesis_wasm_generator: Some(command), ..self.config },
|
||||||
genesis_wasm_generator: Some(command),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
self.config,
|
self.config,
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
merge_errors(
|
merge_errors(self.errors, FieldError::GenesisWasmGenerator(error.into()).into()),
|
||||||
self.errors,
|
|
||||||
FieldError::GenesisWasmGenerator(error.into()).into(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -721,10 +666,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the location of a pre-existing genesis state of the teyrchain.
|
/// Set the location of a pre-existing genesis state of the teyrchain.
|
||||||
pub fn with_genesis_state_path(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_genesis_state_path(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { genesis_state_path: Some(location.into()), ..self.config },
|
||||||
genesis_state_path: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -738,20 +680,14 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
{
|
{
|
||||||
match command.try_into() {
|
match command.try_into() {
|
||||||
Ok(command) => Self::transition(
|
Ok(command) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { genesis_state_generator: Some(command), ..self.config },
|
||||||
genesis_state_generator: Some(command),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
Err(error) => Self::transition(
|
Err(error) => Self::transition(
|
||||||
self.config,
|
self.config,
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
merge_errors(
|
merge_errors(self.errors, FieldError::GenesisStateGenerator(error.into()).into()),
|
||||||
self.errors,
|
|
||||||
FieldError::GenesisStateGenerator(error.into()).into(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -759,10 +695,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the genesis overrides as a JSON object.
|
/// Set the genesis overrides as a JSON object.
|
||||||
pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self {
|
pub fn with_genesis_overrides(self, genesis_overrides: impl Into<serde_json::Value>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { genesis_overrides: Some(genesis_overrides.into()), ..self.config },
|
||||||
genesis_overrides: Some(genesis_overrides.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -771,10 +704,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the location of a pre-existing chain specification for the teyrchain.
|
/// Set the location of a pre-existing chain specification for the teyrchain.
|
||||||
pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_chain_spec_path(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { chain_spec_path: Some(location.into()), ..self.config },
|
||||||
chain_spec_path: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -783,10 +713,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the chain-spec command _template_ for the relay chain.
|
/// Set the chain-spec command _template_ for the relay chain.
|
||||||
pub fn with_chain_spec_command(self, cmd_template: impl Into<String>) -> Self {
|
pub fn with_chain_spec_command(self, cmd_template: impl Into<String>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { chain_spec_command: Some(cmd_template.into()), ..self.config },
|
||||||
chain_spec_command: Some(cmd_template.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -806,10 +733,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
ChainSpecRuntime::new(location.into())
|
ChainSpecRuntime::new(location.into())
|
||||||
};
|
};
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { chain_spec_runtime: Some(chain_spec_runtime), ..self.config },
|
||||||
chain_spec_runtime: Some(chain_spec_runtime),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -818,10 +742,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the location of a wasm to override the chain-spec.
|
/// Set the location of a wasm to override the chain-spec.
|
||||||
pub fn with_wasm_override(self, location: impl Into<AssetLocation>) -> Self {
|
pub fn with_wasm_override(self, location: impl Into<AssetLocation>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { wasm_override: Some(location.into()), ..self.config },
|
||||||
wasm_override: Some(location.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -830,10 +751,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set if the chain-spec command needs to be run locally or not (false by default)
|
/// Set if the chain-spec command needs to be run locally or not (false by default)
|
||||||
pub fn chain_spec_command_is_local(self, choice: bool) -> Self {
|
pub fn chain_spec_command_is_local(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { chain_spec_command_is_local: choice, ..self.config },
|
||||||
chain_spec_command_is_local: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -854,10 +772,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set whether the teyrchain is based on cumulus (true in a majority of case, except adder or undying collators).
|
/// Set whether the teyrchain is based on cumulus (true in a majority of case, except adder or undying collators).
|
||||||
pub fn cumulus_based(self, choice: bool) -> Self {
|
pub fn cumulus_based(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { is_cumulus_based: choice, ..self.config },
|
||||||
is_cumulus_based: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -871,10 +786,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set whether the teyrchain is evm based (e.g frontier /evm template)
|
/// Set whether the teyrchain is evm based (e.g frontier /evm template)
|
||||||
pub fn evm_based(self, choice: bool) -> Self {
|
pub fn evm_based(self, choice: bool) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { is_evm_based: choice, ..self.config },
|
||||||
is_evm_based: choice,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -902,10 +814,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { bootnodes_addresses: addrs, ..self.config },
|
||||||
bootnodes_addresses: addrs,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
merge_errors_vecs(self.errors, errors),
|
merge_errors_vecs(self.errors, errors),
|
||||||
)
|
)
|
||||||
@@ -914,10 +823,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Do not assign a bootnode role automatically if no nodes are marked as bootnodes.
|
/// Do not assign a bootnode role automatically if no nodes are marked as bootnodes.
|
||||||
pub fn without_default_bootnodes(self) -> Self {
|
pub fn without_default_bootnodes(self) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { no_default_bootnodes: true, ..self.config },
|
||||||
no_default_bootnodes: true,
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -930,10 +836,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
||||||
match self.create_node_builder(f).validator(true).build() {
|
match self.create_node_builder(f).validator(true).build() {
|
||||||
Ok(collator) => Self::transition(
|
Ok(collator) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { collators: vec![collator], ..self.config },
|
||||||
collators: vec![collator],
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -959,10 +862,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
||||||
match self.create_node_builder(f).validator(false).build() {
|
match self.create_node_builder(f).validator(false).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { collators: vec![node], ..self.config },
|
||||||
collators: vec![node],
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -993,10 +893,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
) -> TeyrchainConfigBuilder<WithAtLeastOneCollator, C> {
|
||||||
match self.create_node_builder(f).build() {
|
match self.create_node_builder(f).build() {
|
||||||
Ok(node) => Self::transition(
|
Ok(node) => Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { collators: vec![node], ..self.config },
|
||||||
collators: vec![node],
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
),
|
),
|
||||||
@@ -1050,10 +947,7 @@ impl<C: Context> TeyrchainConfigBuilder<WithId, C> {
|
|||||||
/// Set the location or inline value of json to override the raw chain-spec.
|
/// Set the location or inline value of json to override the raw chain-spec.
|
||||||
pub fn with_raw_spec_override(self, overrides: impl Into<JsonOverrides>) -> Self {
|
pub fn with_raw_spec_override(self, overrides: impl Into<JsonOverrides>) -> Self {
|
||||||
Self::transition(
|
Self::transition(
|
||||||
TeyrchainConfig {
|
TeyrchainConfig { raw_spec_override: Some(overrides.into()), ..self.config },
|
||||||
raw_spec_override: Some(overrides.into()),
|
|
||||||
..self.config
|
|
||||||
},
|
|
||||||
self.validation_context,
|
self.validation_context,
|
||||||
self.errors,
|
self.errors,
|
||||||
)
|
)
|
||||||
@@ -1215,10 +1109,7 @@ mod tests {
|
|||||||
.with_default_image("myrepo:myimage")
|
.with_default_image("myrepo:myimage")
|
||||||
.with_default_command("default_command")
|
.with_default_command("default_command")
|
||||||
.with_default_resources(|resources| {
|
.with_default_resources(|resources| {
|
||||||
resources
|
resources.with_limit_cpu("500M").with_limit_memory("1G").with_request_cpu("250M")
|
||||||
.with_limit_cpu("500M")
|
|
||||||
.with_limit_memory("1G")
|
|
||||||
.with_request_cpu("250M")
|
|
||||||
})
|
})
|
||||||
.with_default_db_snapshot("https://www.urltomysnapshot.com/file.tgz")
|
.with_default_db_snapshot("https://www.urltomysnapshot.com/file.tgz")
|
||||||
.with_default_args(vec![("--arg1", "value1").into(), "--option2".into()])
|
.with_default_args(vec![("--arg1", "value1").into(), "--option2".into()])
|
||||||
@@ -1240,16 +1131,10 @@ mod tests {
|
|||||||
])
|
])
|
||||||
.without_default_bootnodes()
|
.without_default_bootnodes()
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("command1").bootnode(true)
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("command1")
|
|
||||||
.bootnode(true)
|
|
||||||
})
|
})
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator2").with_command("command2").validator(true)
|
||||||
.with_name("collator2")
|
|
||||||
.with_command("command2")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -1272,14 +1157,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert!(!teyrchain_config.onboard_as_teyrchain());
|
assert!(!teyrchain_config.onboard_as_teyrchain());
|
||||||
assert_eq!(teyrchain_config.initial_balance(), 100_000_042);
|
assert_eq!(teyrchain_config.initial_balance(), 100_000_042);
|
||||||
assert_eq!(
|
assert_eq!(teyrchain_config.default_command().unwrap().as_str(), "default_command");
|
||||||
teyrchain_config.default_command().unwrap().as_str(),
|
assert_eq!(teyrchain_config.default_image().unwrap().as_str(), "myrepo:myimage");
|
||||||
"default_command"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
teyrchain_config.default_image().unwrap().as_str(),
|
|
||||||
"myrepo:myimage"
|
|
||||||
);
|
|
||||||
let default_resources = teyrchain_config.default_resources().unwrap();
|
let default_resources = teyrchain_config.default_resources().unwrap();
|
||||||
assert_eq!(default_resources.limit_cpu().unwrap().as_str(), "500M");
|
assert_eq!(default_resources.limit_cpu().unwrap().as_str(), "500M");
|
||||||
assert_eq!(default_resources.limit_memory().unwrap().as_str(), "1G");
|
assert_eq!(default_resources.limit_memory().unwrap().as_str(), "1G");
|
||||||
@@ -1300,38 +1179,21 @@ mod tests {
|
|||||||
&teyrchain_config.chain_spec_runtime().unwrap().location,
|
&teyrchain_config.chain_spec_runtime().unwrap().location,
|
||||||
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/runtime.wasm"
|
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/runtime.wasm"
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(teyrchain_config.chain_spec_runtime().unwrap().preset.as_deref(), Some("dev"));
|
||||||
teyrchain_config
|
|
||||||
.chain_spec_runtime()
|
|
||||||
.unwrap()
|
|
||||||
.preset
|
|
||||||
.as_deref(),
|
|
||||||
Some("dev")
|
|
||||||
);
|
|
||||||
|
|
||||||
let args: Vec<Arg> = vec![("--arg1", "value1").into(), "--option2".into()];
|
let args: Vec<Arg> = vec![("--arg1", "value1").into(), "--option2".into()];
|
||||||
assert_eq!(
|
assert_eq!(teyrchain_config.default_args(), args.iter().collect::<Vec<_>>());
|
||||||
teyrchain_config.default_args(),
|
|
||||||
args.iter().collect::<Vec<_>>()
|
|
||||||
);
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
teyrchain_config.genesis_wasm_path().unwrap(),
|
teyrchain_config.genesis_wasm_path().unwrap(),
|
||||||
AssetLocation::Url(value) if value.as_str() == "https://www.backupsite.com/my/wasm/file.tgz"
|
AssetLocation::Url(value) if value.as_str() == "https://www.backupsite.com/my/wasm/file.tgz"
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(teyrchain_config.genesis_wasm_generator().unwrap().as_str(), "generator_wasm");
|
||||||
teyrchain_config.genesis_wasm_generator().unwrap().as_str(),
|
|
||||||
"generator_wasm"
|
|
||||||
);
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
teyrchain_config.genesis_state_path().unwrap(),
|
teyrchain_config.genesis_state_path().unwrap(),
|
||||||
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/genesis/state"
|
AssetLocation::FilePath(value) if value.to_str().unwrap() == "./path/to/genesis/state"
|
||||||
));
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
teyrchain_config
|
teyrchain_config.genesis_state_generator().unwrap().cmd().as_str(),
|
||||||
.genesis_state_generator()
|
|
||||||
.unwrap()
|
|
||||||
.cmd()
|
|
||||||
.as_str(),
|
|
||||||
"undying-collator"
|
"undying-collator"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1372,40 +1234,23 @@ mod tests {
|
|||||||
.with_chain("myteyrchain")
|
.with_chain("myteyrchain")
|
||||||
.with_genesis_state_generator("generator_state --simple-flag --flag=value")
|
.with_genesis_state_generator("generator_state --simple-flag --flag=value")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("command").validator(true)
|
||||||
.with_name("collator")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
teyrchain_config
|
teyrchain_config.genesis_state_generator().unwrap().cmd().as_str(),
|
||||||
.genesis_state_generator()
|
|
||||||
.unwrap()
|
|
||||||
.cmd()
|
|
||||||
.as_str(),
|
|
||||||
"generator_state"
|
"generator_state"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(teyrchain_config.genesis_state_generator().unwrap().args().len(), 2);
|
||||||
teyrchain_config
|
|
||||||
.genesis_state_generator()
|
|
||||||
.unwrap()
|
|
||||||
.args()
|
|
||||||
.len(),
|
|
||||||
2
|
|
||||||
);
|
|
||||||
|
|
||||||
let args = teyrchain_config.genesis_state_generator().unwrap().args();
|
let args = teyrchain_config.genesis_state_generator().unwrap().args();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
args,
|
args,
|
||||||
&vec![
|
&vec![Arg::Flag("--simple-flag".into()), Arg::Option("--flag".into(), "value".into())]
|
||||||
Arg::Flag("--simple-flag".into()),
|
|
||||||
Arg::Option("--flag".into(), "value".into())
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1415,10 +1260,7 @@ mod tests {
|
|||||||
.with_id(1000)
|
.with_id(1000)
|
||||||
.with_chain("invalid chain")
|
.with_chain("invalid chain")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("command").validator(true)
|
||||||
.with_name("collator")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1437,10 +1279,7 @@ mod tests {
|
|||||||
.with_chain("chain")
|
.with_chain("chain")
|
||||||
.with_default_command("invalid command")
|
.with_default_command("invalid command")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("node").with_command("command").validator(true)
|
||||||
.with_name("node")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1459,10 +1298,7 @@ mod tests {
|
|||||||
.with_chain("chain")
|
.with_chain("chain")
|
||||||
.with_default_image("invalid image")
|
.with_default_image("invalid image")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("node").with_command("command").validator(true)
|
||||||
.with_name("node")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1481,15 +1317,10 @@ mod tests {
|
|||||||
.with_id(1000)
|
.with_id(1000)
|
||||||
.with_chain("chain")
|
.with_chain("chain")
|
||||||
.with_default_resources(|default_resources| {
|
.with_default_resources(|default_resources| {
|
||||||
default_resources
|
default_resources.with_limit_memory("100m").with_request_cpu("invalid")
|
||||||
.with_limit_memory("100m")
|
|
||||||
.with_request_cpu("invalid")
|
|
||||||
})
|
})
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("node").with_command("command").validator(true)
|
||||||
.with_name("node")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1509,10 +1340,7 @@ mod tests {
|
|||||||
.with_chain("myteyrchain")
|
.with_chain("myteyrchain")
|
||||||
.with_genesis_wasm_generator("invalid command")
|
.with_genesis_wasm_generator("invalid command")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("command").validator(true)
|
||||||
.with_name("collator")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1532,10 +1360,7 @@ mod tests {
|
|||||||
.with_chain("myteyrchain")
|
.with_chain("myteyrchain")
|
||||||
.with_raw_bootnodes_addresses(vec!["/ip4//tcp/45421", "//10.42.153.10/tcp/43111"])
|
.with_raw_bootnodes_addresses(vec!["/ip4//tcp/45421", "//10.42.153.10/tcp/43111"])
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("command").validator(true)
|
||||||
.with_name("collator")
|
|
||||||
.with_command("command")
|
|
||||||
.validator(true)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1557,9 +1382,7 @@ mod tests {
|
|||||||
.with_id(1000)
|
.with_id(1000)
|
||||||
.with_chain("myteyrchain")
|
.with_chain("myteyrchain")
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator").with_command("invalid command")
|
||||||
.with_name("collator")
|
|
||||||
.with_command("invalid command")
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@@ -1614,9 +1437,7 @@ mod tests {
|
|||||||
.invulnerable(true)
|
.invulnerable(true)
|
||||||
.bootnode(true)
|
.bootnode(true)
|
||||||
.with_resources(|resources| {
|
.with_resources(|resources| {
|
||||||
resources
|
resources.with_limit_cpu("invalid").with_request_memory("1G")
|
||||||
.with_limit_cpu("invalid")
|
|
||||||
.with_request_memory("1G")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
@@ -1732,10 +1553,7 @@ mod tests {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(config.registration_strategy(), Some(&RegistrationStrategy::UsingExtrinsic));
|
||||||
config.registration_strategy(),
|
|
||||||
Some(&RegistrationStrategy::UsingExtrinsic)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1785,23 +1603,16 @@ mod tests {
|
|||||||
.with_default_command("default_command")
|
.with_default_command("default_command")
|
||||||
.without_default_bootnodes()
|
.without_default_bootnodes()
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("command1").bootnode(true)
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("command1")
|
|
||||||
.bootnode(true)
|
|
||||||
})
|
})
|
||||||
.with_collator_group(|group| {
|
.with_collator_group(|group| {
|
||||||
group.with_count(2).with_base_node(|base| {
|
group.with_count(2).with_base_node(|base| {
|
||||||
base.with_name("collator_group1")
|
base.with_name("collator_group1").with_command("group_command1").bootnode(true)
|
||||||
.with_command("group_command1")
|
|
||||||
.bootnode(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_collator_group(|group| {
|
.with_collator_group(|group| {
|
||||||
group.with_count(3).with_base_node(|base| {
|
group.with_count(3).with_base_node(|base| {
|
||||||
base.with_name("collator_group2")
|
base.with_name("collator_group2").with_command("group_command2").bootnode(false)
|
||||||
.with_command("group_command2")
|
|
||||||
.bootnode(false)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
@@ -1838,23 +1649,16 @@ mod tests {
|
|||||||
.with_default_command("default_command")
|
.with_default_command("default_command")
|
||||||
.without_default_bootnodes()
|
.without_default_bootnodes()
|
||||||
.with_collator(|collator| {
|
.with_collator(|collator| {
|
||||||
collator
|
collator.with_name("collator1").with_command("command1").bootnode(true)
|
||||||
.with_name("collator1")
|
|
||||||
.with_command("command1")
|
|
||||||
.bootnode(true)
|
|
||||||
})
|
})
|
||||||
.with_collator_group(|group| {
|
.with_collator_group(|group| {
|
||||||
group.with_count(2).with_base_node(|base| {
|
group.with_count(2).with_base_node(|base| {
|
||||||
base.with_name("collator_group1")
|
base.with_name("collator_group1").with_command("group_command1").bootnode(true)
|
||||||
.with_command("group_command1")
|
|
||||||
.bootnode(true)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_collator_group(|group| {
|
.with_collator_group(|group| {
|
||||||
group.with_count(0).with_base_node(|base| {
|
group.with_count(0).with_base_node(|base| {
|
||||||
base.with_name("collator_group2")
|
base.with_name("collator_group2").with_command("group_command2").bootnode(false)
|
||||||
.with_command("group_command2")
|
|
||||||
.bootnode(false)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|||||||
+7
-22
@@ -57,12 +57,8 @@ mod tests {
|
|||||||
fn generate_for_alice_with_listen_addr() {
|
fn generate_for_alice_with_listen_addr() {
|
||||||
// Should override the ip/port
|
// Should override the ip/port
|
||||||
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
||||||
let args: Vec<String> = [
|
let args: Vec<String> =
|
||||||
"--some",
|
["--some", "other", "--listen-addr", "/ip4/192.168.100.1/tcp/30333/ws"]
|
||||||
"other",
|
|
||||||
"--listen-addr",
|
|
||||||
"/ip4/192.168.100.1/tcp/30333/ws",
|
|
||||||
]
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.to_string())
|
.map(|x| x.to_string())
|
||||||
.collect();
|
.collect();
|
||||||
@@ -78,31 +74,20 @@ mod tests {
|
|||||||
fn generate_for_alice_with_listen_addr_without_value_must_fail() {
|
fn generate_for_alice_with_listen_addr_without_value_must_fail() {
|
||||||
// Should override the ip/port
|
// Should override the ip/port
|
||||||
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
||||||
let args: Vec<String> = ["--some", "other", "--listen-addr"]
|
let args: Vec<String> =
|
||||||
.iter()
|
["--some", "other", "--listen-addr"].iter().map(|x| x.to_string()).collect();
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect();
|
|
||||||
let bootnode_addr = generate(peer_id, &LOCALHOST, 5678, args.iter().as_ref(), &None);
|
let bootnode_addr = generate(peer_id, &LOCALHOST, 5678, args.iter().as_ref(), &None);
|
||||||
|
|
||||||
assert!(bootnode_addr.is_err());
|
assert!(bootnode_addr.is_err());
|
||||||
assert!(matches!(
|
assert!(matches!(bootnode_addr, Err(GeneratorError::BootnodeAddrGeneration(_))));
|
||||||
bootnode_addr,
|
|
||||||
Err(GeneratorError::BootnodeAddrGeneration(_))
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_for_alice_withcert() {
|
fn generate_for_alice_withcert() {
|
||||||
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
let peer_id = "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"; // from alice as seed
|
||||||
let args: Vec<&str> = vec![];
|
let args: Vec<&str> = vec![];
|
||||||
let bootnode_addr = generate(
|
let bootnode_addr =
|
||||||
peer_id,
|
generate(peer_id, &LOCALHOST, 5678, &args, &Some(String::from("data"))).unwrap();
|
||||||
&LOCALHOST,
|
|
||||||
5678,
|
|
||||||
&args,
|
|
||||||
&Some(String::from("data")),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&bootnode_addr,
|
&bootnode_addr,
|
||||||
"/ip4/127.0.0.1/tcp/5678/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm/certhash/data"
|
"/ip4/127.0.0.1/tcp/5678/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm/certhash/data"
|
||||||
|
|||||||
+86
-252
@@ -8,12 +8,12 @@ use configuration::{
|
|||||||
types::{AssetLocation, Chain, ChainSpecRuntime, JsonOverrides, ParaId},
|
types::{AssetLocation, Chain, ChainSpecRuntime, JsonOverrides, ParaId},
|
||||||
HrmpChannelConfig,
|
HrmpChannelConfig,
|
||||||
};
|
};
|
||||||
|
use pezsc_chain_spec::{GenericChainSpec, GenesisConfigBuilderRuntimeCaller};
|
||||||
use provider::{
|
use provider::{
|
||||||
constants::NODE_CONFIG_DIR,
|
constants::NODE_CONFIG_DIR,
|
||||||
types::{GenerateFileCommand, GenerateFilesOptions, TransferedFile},
|
types::{GenerateFileCommand, GenerateFilesOptions, TransferedFile},
|
||||||
DynNamespace, ProviderError,
|
DynNamespace, ProviderError,
|
||||||
};
|
};
|
||||||
use pezsc_chain_spec::{GenericChainSpec, GenesisConfigBuilderRuntimeCaller};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use support::{constants::THIS_IS_A_BUG, fs::FileSystem, replacer::apply_replacements};
|
use support::{constants::THIS_IS_A_BUG, fs::FileSystem, replacer::apply_replacements};
|
||||||
@@ -199,27 +199,17 @@ impl ChainSpec {
|
|||||||
// if asset_location is some, then copy the asset to the `base_dir` of the ns with the name `<name>-plain.json`
|
// if asset_location is some, then copy the asset to the `base_dir` of the ns with the name `<name>-plain.json`
|
||||||
if let Some(location) = self.asset_location.as_ref() {
|
if let Some(location) = self.asset_location.as_ref() {
|
||||||
let maybe_plain_spec_full_path = scoped_fs.full_path(maybe_plain_spec_path.as_path());
|
let maybe_plain_spec_full_path = scoped_fs.full_path(maybe_plain_spec_path.as_path());
|
||||||
location
|
location.dump_asset(maybe_plain_spec_full_path).await.map_err(|e| {
|
||||||
.dump_asset(maybe_plain_spec_full_path)
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
GeneratorError::ChainSpecGeneration(format!(
|
GeneratorError::ChainSpecGeneration(format!(
|
||||||
"Error {e} dumping location {location:?}"
|
"Error {e} dumping location {location:?}"
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
} else if let Some(runtime) = self.runtime.as_ref() {
|
} else if let Some(runtime) = self.runtime.as_ref() {
|
||||||
trace!(
|
trace!("Creating chain-spec with runtime from localtion: {}", runtime.location);
|
||||||
"Creating chain-spec with runtime from localtion: {}",
|
|
||||||
runtime.location
|
|
||||||
);
|
|
||||||
// First dump the runtime into the ns scoped fs, since we want to easily reproduce
|
// First dump the runtime into the ns scoped fs, since we want to easily reproduce
|
||||||
let runtime_file_name = PathBuf::from(format!("{}-runtime.wasm", self.chain_spec_name));
|
let runtime_file_name = PathBuf::from(format!("{}-runtime.wasm", self.chain_spec_name));
|
||||||
let runtime_path_ns = scoped_fs.full_path(runtime_file_name.as_path());
|
let runtime_path_ns = scoped_fs.full_path(runtime_file_name.as_path());
|
||||||
runtime
|
runtime.location.dump_asset(runtime_path_ns).await.map_err(|e| {
|
||||||
.location
|
|
||||||
.dump_asset(runtime_path_ns)
|
|
||||||
.await
|
|
||||||
.map_err(|e| {
|
|
||||||
GeneratorError::ChainSpecGeneration(format!(
|
GeneratorError::ChainSpecGeneration(format!(
|
||||||
"Error {e} dumping location {:?}",
|
"Error {e} dumping location {:?}",
|
||||||
runtime.location
|
runtime.location
|
||||||
@@ -248,9 +238,8 @@ impl ChainSpec {
|
|||||||
} else {
|
} else {
|
||||||
DEFAULT_PRESETS_TO_CHECK.to_vec()
|
DEFAULT_PRESETS_TO_CHECK.to_vec()
|
||||||
};
|
};
|
||||||
let preset = preset_to_check
|
let preset =
|
||||||
.iter()
|
preset_to_check.iter().find(|preset| presets.iter().any(|item| item == *preset));
|
||||||
.find(|preset| presets.iter().any(|item| item == *preset));
|
|
||||||
|
|
||||||
trace!("presets: {:?} - preset to use: {:?}", presets, preset);
|
trace!("presets: {:?} - preset to use: {:?}", presets, preset);
|
||||||
let builder = if let Some(preset) = preset {
|
let builder = if let Some(preset) = preset {
|
||||||
@@ -268,11 +257,7 @@ impl ChainSpec {
|
|||||||
.with_genesis_config(default_config)
|
.with_genesis_config(default_config)
|
||||||
};
|
};
|
||||||
|
|
||||||
let builder = if let Context::Para {
|
let builder = if let Context::Para { relay_chain: _, para_id: _ } = &self.context {
|
||||||
relay_chain: _,
|
|
||||||
para_id: _,
|
|
||||||
} = &self.context
|
|
||||||
{
|
|
||||||
builder.with_id(self.chain_spec_name())
|
builder.with_id(self.chain_spec_name())
|
||||||
} else {
|
} else {
|
||||||
builder
|
builder
|
||||||
@@ -400,8 +385,7 @@ impl ChainSpec {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
self.build_raw_with_command(ns, scoped_fs, raw_spec_path, relay_chain_id)
|
self.build_raw_with_command(ns, scoped_fs, raw_spec_path, relay_chain_id).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -430,9 +414,7 @@ impl ChainSpec {
|
|||||||
"getting chain-spec as json should work, err: {e}"
|
"getting chain-spec as json should work, err: {e}"
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let contents = self
|
let contents = self.ensure_para_fields_in_raw(&contents, relay_chain_id).await?;
|
||||||
.ensure_para_fields_in_raw(&contents, relay_chain_id)
|
|
||||||
.await?;
|
|
||||||
self.write_spec(scoped_fs, contents).await?;
|
self.write_spec(scoped_fs, contents).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -449,31 +431,20 @@ impl ChainSpec {
|
|||||||
T: FileSystem,
|
T: FileSystem,
|
||||||
{
|
{
|
||||||
// fallback to use _cmd_ for raw creation
|
// fallback to use _cmd_ for raw creation
|
||||||
let temp_name = format!(
|
let temp_name = format!("temp-build-raw-{}-{}", self.chain_spec_name, rand::random::<u8>());
|
||||||
"temp-build-raw-{}-{}",
|
|
||||||
self.chain_spec_name,
|
|
||||||
rand::random::<u8>()
|
|
||||||
);
|
|
||||||
|
|
||||||
let cmd = self
|
let cmd = self
|
||||||
.command
|
.command
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(GeneratorError::ChainSpecGeneration(
|
.ok_or(GeneratorError::ChainSpecGeneration("Invalid command".into()))?;
|
||||||
"Invalid command".into(),
|
let maybe_plain_path = self
|
||||||
))?;
|
.maybe_plain_path
|
||||||
let maybe_plain_path =
|
|
||||||
self.maybe_plain_path
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(GeneratorError::ChainSpecGeneration(
|
.ok_or(GeneratorError::ChainSpecGeneration("Invalid plain path".into()))?;
|
||||||
"Invalid plain path".into(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
// TODO: we should get the full path from the scoped filesystem
|
// TODO: we should get the full path from the scoped filesystem
|
||||||
let chain_spec_path_local = format!(
|
let chain_spec_path_local =
|
||||||
"{}/{}",
|
format!("{}/{}", ns.base_dir().to_string_lossy(), maybe_plain_path.display());
|
||||||
ns.base_dir().to_string_lossy(),
|
|
||||||
maybe_plain_path.display()
|
|
||||||
);
|
|
||||||
// Remote path to be injected
|
// Remote path to be injected
|
||||||
let chain_spec_path_in_pod = format!("{}/{}", NODE_CONFIG_DIR, maybe_plain_path.display());
|
let chain_spec_path_in_pod = format!("{}/{}", NODE_CONFIG_DIR, maybe_plain_path.display());
|
||||||
// Path in the context of the node, this can be different in the context of the providers (e.g native)
|
// Path in the context of the node, this can be different in the context of the providers (e.g native)
|
||||||
@@ -482,12 +453,7 @@ impl ChainSpec {
|
|||||||
chain_spec_path_local.clone()
|
chain_spec_path_local.clone()
|
||||||
} else if ns.capabilities().prefix_with_full_path {
|
} else if ns.capabilities().prefix_with_full_path {
|
||||||
// In native
|
// In native
|
||||||
format!(
|
format!("{}/{}{}", ns.base_dir().to_string_lossy(), &temp_name, &chain_spec_path_in_pod)
|
||||||
"{}/{}{}",
|
|
||||||
ns.base_dir().to_string_lossy(),
|
|
||||||
&temp_name,
|
|
||||||
&chain_spec_path_in_pod
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
chain_spec_path_in_pod.clone()
|
chain_spec_path_in_pod.clone()
|
||||||
};
|
};
|
||||||
@@ -521,10 +487,7 @@ impl ChainSpec {
|
|||||||
let options = GenerateFilesOptions::with_files(
|
let options = GenerateFilesOptions::with_files(
|
||||||
vec![generate_command],
|
vec![generate_command],
|
||||||
self.image.clone(),
|
self.image.clone(),
|
||||||
&[TransferedFile::new(
|
&[TransferedFile::new(chain_spec_path_local, chain_spec_path_in_pod)],
|
||||||
chain_spec_path_local,
|
|
||||||
chain_spec_path_in_pod,
|
|
||||||
)],
|
|
||||||
expected_path.clone(),
|
expected_path.clone(),
|
||||||
)
|
)
|
||||||
.temp_name(temp_name);
|
.temp_name(temp_name);
|
||||||
@@ -536,9 +499,7 @@ impl ChainSpec {
|
|||||||
|
|
||||||
self.raw_path = Some(raw_spec_path.clone());
|
self.raw_path = Some(raw_spec_path.clone());
|
||||||
let (content, _) = self.read_spec(scoped_fs).await?;
|
let (content, _) = self.read_spec(scoped_fs).await?;
|
||||||
let content = self
|
let content = self.ensure_para_fields_in_raw(&content, relay_chain_id).await?;
|
||||||
.ensure_para_fields_in_raw(&content, relay_chain_id)
|
|
||||||
.await?;
|
|
||||||
self.write_spec(scoped_fs, content).await?;
|
self.write_spec(scoped_fs, content).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -549,11 +510,7 @@ impl ChainSpec {
|
|||||||
content: &str,
|
content: &str,
|
||||||
relay_chain_id: Option<Chain>,
|
relay_chain_id: Option<Chain>,
|
||||||
) -> Result<String, GeneratorError> {
|
) -> Result<String, GeneratorError> {
|
||||||
if let Context::Para {
|
if let Context::Para { relay_chain: _, para_id } = &self.context {
|
||||||
relay_chain: _,
|
|
||||||
para_id,
|
|
||||||
} = &self.context
|
|
||||||
{
|
|
||||||
let mut chain_spec_json: serde_json::Value =
|
let mut chain_spec_json: serde_json::Value =
|
||||||
serde_json::from_str(content).map_err(|e| {
|
serde_json::from_str(content).map_err(|e| {
|
||||||
GeneratorError::ChainSpecGeneration(format!(
|
GeneratorError::ChainSpecGeneration(format!(
|
||||||
@@ -805,47 +762,27 @@ impl ChainSpec {
|
|||||||
|
|
||||||
clear_authorities(&pointer, &mut chain_spec_json, &self.context);
|
clear_authorities(&pointer, &mut chain_spec_json, &self.context);
|
||||||
|
|
||||||
let key_type_to_use = if para.is_evm_based {
|
let key_type_to_use =
|
||||||
SessionKeyType::Evm
|
if para.is_evm_based { SessionKeyType::Evm } else { SessionKeyType::Default };
|
||||||
} else {
|
|
||||||
SessionKeyType::Default
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get validators to add as authorities
|
// Get validators to add as authorities
|
||||||
let validators: Vec<&NodeSpec> = para
|
let validators: Vec<&NodeSpec> =
|
||||||
.collators
|
para.collators.iter().filter(|node| node.is_validator).collect();
|
||||||
.iter()
|
|
||||||
.filter(|node| node.is_validator)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// check chain key types
|
// check chain key types
|
||||||
if chain_spec_json
|
if chain_spec_json.pointer(&format!("{pointer}/session")).is_some() {
|
||||||
.pointer(&format!("{pointer}/session"))
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
add_authorities(&pointer, &mut chain_spec_json, &validators, key_type_to_use);
|
add_authorities(&pointer, &mut chain_spec_json, &validators, key_type_to_use);
|
||||||
} else if chain_spec_json
|
} else if chain_spec_json.pointer(&format!("{pointer}/aura")).is_some() {
|
||||||
.pointer(&format!("{pointer}/aura"))
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
add_aura_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
add_aura_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
||||||
} else {
|
} else {
|
||||||
warn!("Can't customize keys, not `session` or `aura` find in the chain-spec file");
|
warn!("Can't customize keys, not `session` or `aura` find in the chain-spec file");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add nodes to collator
|
// Add nodes to collator
|
||||||
let invulnerables: Vec<&NodeSpec> = para
|
let invulnerables: Vec<&NodeSpec> =
|
||||||
.collators
|
para.collators.iter().filter(|node| node.is_invulnerable).collect();
|
||||||
.iter()
|
|
||||||
.filter(|node| node.is_invulnerable)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
add_collator_selection(
|
add_collator_selection(&pointer, &mut chain_spec_json, &invulnerables, key_type_to_use);
|
||||||
&pointer,
|
|
||||||
&mut chain_spec_json,
|
|
||||||
&invulnerables,
|
|
||||||
key_type_to_use,
|
|
||||||
);
|
|
||||||
|
|
||||||
// override `parachainInfo/parachainId`
|
// override `parachainInfo/parachainId`
|
||||||
override_parachain_info(&pointer, &mut chain_spec_json, para.id);
|
override_parachain_info(&pointer, &mut chain_spec_json, para.id);
|
||||||
@@ -920,31 +857,15 @@ impl ChainSpec {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// add staking
|
// add staking
|
||||||
add_staking(
|
add_staking(&pointer, &mut chain_spec_json, &relaychain.nodes, staking_min);
|
||||||
&pointer,
|
|
||||||
&mut chain_spec_json,
|
|
||||||
&relaychain.nodes,
|
|
||||||
staking_min,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get validators to add as authorities
|
// Get validators to add as authorities
|
||||||
let validators: Vec<&NodeSpec> = relaychain
|
let validators: Vec<&NodeSpec> =
|
||||||
.nodes
|
relaychain.nodes.iter().filter(|node| node.is_validator).collect();
|
||||||
.iter()
|
|
||||||
.filter(|node| node.is_validator)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// check chain key types
|
// check chain key types
|
||||||
if chain_spec_json
|
if chain_spec_json.pointer(&format!("{pointer}/session")).is_some() {
|
||||||
.pointer(&format!("{pointer}/session"))
|
add_authorities(&pointer, &mut chain_spec_json, &validators, SessionKeyType::Stash);
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
add_authorities(
|
|
||||||
&pointer,
|
|
||||||
&mut chain_spec_json,
|
|
||||||
&validators,
|
|
||||||
SessionKeyType::Stash,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
add_aura_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
add_aura_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
||||||
add_grandpa_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
add_grandpa_authorities(&pointer, &mut chain_spec_json, &validators, KeyType::Aura);
|
||||||
@@ -1141,16 +1062,10 @@ where
|
|||||||
let paras = val
|
let paras = val
|
||||||
.pointer_mut(paras_pointer)
|
.pointer_mut(paras_pointer)
|
||||||
.ok_or(anyhow!("paras pointer should be valid {paras_pointer:?} "))?;
|
.ok_or(anyhow!("paras pointer should be valid {paras_pointer:?} "))?;
|
||||||
let paras_vec = paras
|
let paras_vec = paras.as_array_mut().ok_or(anyhow!("paras should be an array"))?;
|
||||||
.as_array_mut()
|
|
||||||
.ok_or(anyhow!("paras should be an array"))?;
|
|
||||||
|
|
||||||
let head = scoped_fs
|
let head = scoped_fs.read_to_string(para_genesis_config.state_path.as_ref()).await?;
|
||||||
.read_to_string(para_genesis_config.state_path.as_ref())
|
let wasm = scoped_fs.read_to_string(para_genesis_config.wasm_path.as_ref()).await?;
|
||||||
.await?;
|
|
||||||
let wasm = scoped_fs
|
|
||||||
.read_to_string(para_genesis_config.wasm_path.as_ref())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
paras_vec.push(json!([
|
paras_vec.push(json!([
|
||||||
para_genesis_config.id,
|
para_genesis_config.id,
|
||||||
@@ -1190,13 +1105,9 @@ fn percolate_overrides<'a>(
|
|||||||
let pointer_parts = pointer.split('/').collect::<Vec<&str>>();
|
let pointer_parts = pointer.split('/').collect::<Vec<&str>>();
|
||||||
trace!("pointer_parts: {pointer_parts:?}");
|
trace!("pointer_parts: {pointer_parts:?}");
|
||||||
|
|
||||||
let top_level = overrides
|
let top_level = overrides.as_object().ok_or_else(|| anyhow!("Overrides must be an object"))?;
|
||||||
.as_object()
|
let top_level_key =
|
||||||
.ok_or_else(|| anyhow!("Overrides must be an object"))?;
|
top_level.keys().next().ok_or_else(|| anyhow!("Invalid override value: {overrides:?}"))?;
|
||||||
let top_level_key = top_level
|
|
||||||
.keys()
|
|
||||||
.next()
|
|
||||||
.ok_or_else(|| anyhow!("Invalid override value: {overrides:?}"))?;
|
|
||||||
trace!("top_level_key: {top_level_key}");
|
trace!("top_level_key: {top_level_key}");
|
||||||
let index = pointer_parts.iter().position(|x| *x == top_level_key);
|
let index = pointer_parts.iter().position(|x| *x == top_level_key);
|
||||||
let Some(i) = index else {
|
let Some(i) = index else {
|
||||||
@@ -1215,9 +1126,8 @@ fn percolate_overrides<'a>(
|
|||||||
trace!("overrides pointer {p}");
|
trace!("overrides pointer {p}");
|
||||||
p
|
p
|
||||||
};
|
};
|
||||||
let overrides_to_use = overrides
|
let overrides_to_use =
|
||||||
.pointer(&p)
|
overrides.pointer(&p).ok_or_else(|| anyhow!("Invalid override value: {overrides:?}"))?;
|
||||||
.ok_or_else(|| anyhow!("Invalid override value: {overrides:?}"))?;
|
|
||||||
Ok(overrides_to_use)
|
Ok(overrides_to_use)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1467,14 +1377,7 @@ fn add_hrmp_channels(
|
|||||||
if let Some(preopen_hrmp_channels) = val.pointer_mut("/hrmp/preopenHrmpChannels") {
|
if let Some(preopen_hrmp_channels) = val.pointer_mut("/hrmp/preopenHrmpChannels") {
|
||||||
let hrmp_channels = hrmp_channels
|
let hrmp_channels = hrmp_channels
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| {
|
.map(|c| (c.sender(), c.recipient(), c.max_capacity(), c.max_message_size()))
|
||||||
(
|
|
||||||
c.sender(),
|
|
||||||
c.recipient(),
|
|
||||||
c.max_capacity(),
|
|
||||||
c.max_message_size(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
*preopen_hrmp_channels = json!(hrmp_channels);
|
*preopen_hrmp_channels = json!(hrmp_channels);
|
||||||
} else {
|
} else {
|
||||||
@@ -1570,12 +1473,7 @@ fn add_staking(
|
|||||||
.get("sr_stash")
|
.get("sr_stash")
|
||||||
.expect("'sr_stash account should be defined for the node. qed")
|
.expect("'sr_stash account should be defined for the node. qed")
|
||||||
.address;
|
.address;
|
||||||
stakers.push(json!([
|
stakers.push(json!([sr_stash_addr, sr_stash_addr, staking_min, "Validator"]));
|
||||||
sr_stash_addr,
|
|
||||||
sr_stash_addr,
|
|
||||||
staking_min,
|
|
||||||
"Validator"
|
|
||||||
]));
|
|
||||||
|
|
||||||
if node.is_invulnerable {
|
if node.is_invulnerable {
|
||||||
invulnerables.push(sr_stash_addr);
|
invulnerables.push(sr_stash_addr);
|
||||||
@@ -1618,11 +1516,7 @@ fn add_collator_selection(
|
|||||||
session_key: SessionKeyType,
|
session_key: SessionKeyType,
|
||||||
) {
|
) {
|
||||||
if let Some(val) = chain_spec_json.pointer_mut(runtime_config_ptr) {
|
if let Some(val) = chain_spec_json.pointer_mut(runtime_config_ptr) {
|
||||||
let key_type = if let SessionKeyType::Evm = session_key {
|
let key_type = if let SessionKeyType::Evm = session_key { "eth" } else { "sr" };
|
||||||
"eth"
|
|
||||||
} else {
|
|
||||||
"sr"
|
|
||||||
};
|
|
||||||
let keys: Vec<String> = nodes
|
let keys: Vec<String> = nodes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|node| {
|
.map(|node| {
|
||||||
@@ -1653,13 +1547,13 @@ fn add_collator_selection(
|
|||||||
fn generate_balance_map(balances: &serde_json::Value) -> HashMap<String, u128> {
|
fn generate_balance_map(balances: &serde_json::Value) -> HashMap<String, u128> {
|
||||||
// SAFETY: balances is always an array in chain-spec with items [k,v]
|
// SAFETY: balances is always an array in chain-spec with items [k,v]
|
||||||
let balances_map: HashMap<String, u128> =
|
let balances_map: HashMap<String, u128> =
|
||||||
serde_json::from_value::<Vec<(String, u128)>>(balances.to_owned())
|
serde_json::from_value::<Vec<(String, u128)>>(balances.to_owned()).unwrap().iter().fold(
|
||||||
.unwrap()
|
HashMap::new(),
|
||||||
.iter()
|
|mut memo, balance| {
|
||||||
.fold(HashMap::new(), |mut memo, balance| {
|
|
||||||
memo.insert(balance.0.clone(), balance.1);
|
memo.insert(balance.0.clone(), balance.1);
|
||||||
memo
|
memo
|
||||||
});
|
},
|
||||||
|
);
|
||||||
balances_map
|
balances_map
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1759,9 +1653,8 @@ mod tests {
|
|||||||
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
||||||
clear_authorities(&pointer, &mut chain_spec_json, &Context::Relay);
|
clear_authorities(&pointer, &mut chain_spec_json, &Context::Relay);
|
||||||
|
|
||||||
let validator_count = chain_spec_json
|
let validator_count =
|
||||||
.pointer(&format!("{pointer}/staking/validatorCount"))
|
chain_spec_json.pointer(&format!("{pointer}/staking/validatorCount")).unwrap();
|
||||||
.unwrap();
|
|
||||||
assert_eq!(validator_count, &json!(500));
|
assert_eq!(validator_count, &json!(500));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1772,9 +1665,8 @@ mod tests {
|
|||||||
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
||||||
clear_authorities(&pointer, &mut chain_spec_json, &Context::Relay);
|
clear_authorities(&pointer, &mut chain_spec_json, &Context::Relay);
|
||||||
|
|
||||||
let validator_count = chain_spec_json
|
let validator_count =
|
||||||
.pointer(&format!("{pointer}/staking/validatorCount"))
|
chain_spec_json.pointer(&format!("{pointer}/staking/validatorCount")).unwrap();
|
||||||
.unwrap();
|
|
||||||
assert_eq!(validator_count, &json!(0));
|
assert_eq!(validator_count, &json!(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1809,9 +1701,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
trace!("chain spec: {chain_spec_json:#?}");
|
trace!("chain spec: {chain_spec_json:#?}");
|
||||||
assert!(chain_spec_json
|
assert!(chain_spec_json.pointer("/genesis/runtime/balances/devAccounts").is_some());
|
||||||
.pointer("/genesis/runtime/balances/devAccounts")
|
|
||||||
.is_some());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1820,23 +1710,14 @@ mod tests {
|
|||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let initial_balance = 1_000_000_000_000_u128;
|
let initial_balance = 1_000_000_000_000_u128;
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
let node = NodeSpec { name, accounts, initial_balance, ..Default::default() };
|
||||||
};
|
|
||||||
let node = NodeSpec {
|
|
||||||
name,
|
|
||||||
accounts,
|
|
||||||
initial_balance,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let nodes = vec![node];
|
let nodes = vec![node];
|
||||||
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
||||||
|
|
||||||
let new_balances = spec_plain
|
let new_balances = spec_plain.pointer("/genesis/runtime/balances/balances").unwrap();
|
||||||
.pointer("/genesis/runtime/balances/balances")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let balances_map = generate_balance_map(new_balances);
|
let balances_map = generate_balance_map(new_balances);
|
||||||
|
|
||||||
@@ -1844,27 +1725,20 @@ mod tests {
|
|||||||
let sr = nodes[0].accounts.accounts.get("sr").unwrap();
|
let sr = nodes[0].accounts.accounts.get("sr").unwrap();
|
||||||
let sr_stash = nodes[0].accounts.accounts.get("sr_stash").unwrap();
|
let sr_stash = nodes[0].accounts.accounts.get("sr_stash").unwrap();
|
||||||
assert_eq!(balances_map.get(&sr.address).unwrap(), &initial_balance);
|
assert_eq!(balances_map.get(&sr.address).unwrap(), &initial_balance);
|
||||||
assert_eq!(
|
assert_eq!(balances_map.get(&sr_stash.address).unwrap(), &initial_balance);
|
||||||
balances_map.get(&sr_stash.address).unwrap(),
|
|
||||||
&initial_balance
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_balances_ensure_zombie_account() {
|
fn add_balances_ensure_zombie_account() {
|
||||||
let mut spec_plain = chain_spec_test(ROCOCO_LOCAL_PLAIN_TESTING);
|
let mut spec_plain = chain_spec_test(ROCOCO_LOCAL_PLAIN_TESTING);
|
||||||
|
|
||||||
let balances = spec_plain
|
let balances = spec_plain.pointer("/genesis/runtime/balances/balances").unwrap();
|
||||||
.pointer("/genesis/runtime/balances/balances")
|
|
||||||
.unwrap();
|
|
||||||
let balances_map = generate_balance_map(balances);
|
let balances_map = generate_balance_map(balances);
|
||||||
|
|
||||||
let nodes: Vec<NodeSpec> = vec![];
|
let nodes: Vec<NodeSpec> = vec![];
|
||||||
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
||||||
|
|
||||||
let new_balances = spec_plain
|
let new_balances = spec_plain.pointer("/genesis/runtime/balances/balances").unwrap();
|
||||||
.pointer("/genesis/runtime/balances/balances")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let new_balances_map = generate_balance_map(new_balances);
|
let new_balances_map = generate_balance_map(new_balances);
|
||||||
|
|
||||||
@@ -1885,16 +1759,9 @@ mod tests {
|
|||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let initial_balance = 1_000_000_000_000_u128;
|
let initial_balance = 1_000_000_000_000_u128;
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
let node = NodeSpec { name, accounts, initial_balance, ..Default::default() };
|
||||||
};
|
|
||||||
let node = NodeSpec {
|
|
||||||
name,
|
|
||||||
accounts,
|
|
||||||
initial_balance,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let nodes = vec![node];
|
let nodes = vec![node];
|
||||||
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
add_balances("/genesis/runtime", &mut spec_plain, &nodes, 12, 0);
|
||||||
@@ -1911,16 +1778,9 @@ mod tests {
|
|||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let initial_balance = 1_000_000_000_000_u128;
|
let initial_balance = 1_000_000_000_000_u128;
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
let node = NodeSpec { name, accounts, initial_balance, ..Default::default() };
|
||||||
};
|
|
||||||
let node = NodeSpec {
|
|
||||||
name,
|
|
||||||
accounts,
|
|
||||||
initial_balance,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
let pointer = get_runtime_config_pointer(&chain_spec_json).unwrap();
|
||||||
let min = get_staking_min(&pointer, &mut chain_spec_json);
|
let min = get_staking_min(&pointer, &mut chain_spec_json);
|
||||||
@@ -1928,9 +1788,7 @@ mod tests {
|
|||||||
let nodes = vec![node];
|
let nodes = vec![node];
|
||||||
add_staking(&pointer, &mut chain_spec_json, &nodes, min);
|
add_staking(&pointer, &mut chain_spec_json, &nodes, min);
|
||||||
|
|
||||||
let new_staking = chain_spec_json
|
let new_staking = chain_spec_json.pointer("/genesis/runtimeGenesis/patch/staking").unwrap();
|
||||||
.pointer("/genesis/runtimeGenesis/patch/staking")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// stakers should be one (with the luca sr_stash accounts)
|
// stakers should be one (with the luca sr_stash accounts)
|
||||||
let sr_stash = nodes[0].accounts.accounts.get("sr_stash").unwrap();
|
let sr_stash = nodes[0].accounts.accounts.get("sr_stash").unwrap();
|
||||||
@@ -1946,21 +1804,16 @@ mod tests {
|
|||||||
let mut spec_plain = chain_spec_test(ROCOCO_LOCAL_PLAIN_TESTING);
|
let mut spec_plain = chain_spec_test(ROCOCO_LOCAL_PLAIN_TESTING);
|
||||||
|
|
||||||
{
|
{
|
||||||
let current_hrmp_channels = spec_plain
|
let current_hrmp_channels =
|
||||||
.pointer("/genesis/runtime/hrmp/preopenHrmpChannels")
|
spec_plain.pointer("/genesis/runtime/hrmp/preopenHrmpChannels").unwrap();
|
||||||
.unwrap();
|
|
||||||
// assert should be empty
|
// assert should be empty
|
||||||
assert_eq!(current_hrmp_channels, &json!([]));
|
assert_eq!(current_hrmp_channels, &json!([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
let para_100_101 = HrmpChannelConfigBuilder::new()
|
let para_100_101 =
|
||||||
.with_sender(100)
|
HrmpChannelConfigBuilder::new().with_sender(100).with_recipient(101).build();
|
||||||
.with_recipient(101)
|
let para_101_100 =
|
||||||
.build();
|
HrmpChannelConfigBuilder::new().with_sender(101).with_recipient(100).build();
|
||||||
let para_101_100 = HrmpChannelConfigBuilder::new()
|
|
||||||
.with_sender(101)
|
|
||||||
.with_recipient(100)
|
|
||||||
.build();
|
|
||||||
let channels = vec![para_100_101, para_101_100];
|
let channels = vec![para_100_101, para_101_100];
|
||||||
|
|
||||||
add_hrmp_channels("/genesis/runtime", &mut spec_plain, &channels);
|
add_hrmp_channels("/genesis/runtime", &mut spec_plain, &channels);
|
||||||
@@ -1986,14 +1839,10 @@ mod tests {
|
|||||||
*hrmp = json!(serde_json::Value::Null);
|
*hrmp = json!(serde_json::Value::Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
let para_100_101 = HrmpChannelConfigBuilder::new()
|
let para_100_101 =
|
||||||
.with_sender(100)
|
HrmpChannelConfigBuilder::new().with_sender(100).with_recipient(101).build();
|
||||||
.with_recipient(101)
|
let para_101_100 =
|
||||||
.build();
|
HrmpChannelConfigBuilder::new().with_sender(101).with_recipient(100).build();
|
||||||
let para_101_100 = HrmpChannelConfigBuilder::new()
|
|
||||||
.with_sender(101)
|
|
||||||
.with_recipient(100)
|
|
||||||
.build();
|
|
||||||
let channels = vec![para_100_101, para_101_100];
|
let channels = vec![para_100_101, para_101_100];
|
||||||
|
|
||||||
add_hrmp_channels("/genesis/runtime", &mut spec_plain, &channels);
|
add_hrmp_channels("/genesis/runtime", &mut spec_plain, &channels);
|
||||||
@@ -2007,15 +1856,9 @@ mod tests {
|
|||||||
fn get_node_keys_works() {
|
fn get_node_keys_works() {
|
||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
let node = NodeSpec { name, accounts, ..Default::default() };
|
||||||
};
|
|
||||||
let node = NodeSpec {
|
|
||||||
name,
|
|
||||||
accounts,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let sr = &node.accounts.accounts["sr"];
|
let sr = &node.accounts.accounts["sr"];
|
||||||
let keys = [
|
let keys = [
|
||||||
@@ -2028,10 +1871,7 @@ mod tests {
|
|||||||
("aura".into(), sr.address.clone()),
|
("aura".into(), sr.address.clone()),
|
||||||
("nimbus".into(), sr.address.clone()),
|
("nimbus".into(), sr.address.clone()),
|
||||||
("vrf".into(), sr.address.clone()),
|
("vrf".into(), sr.address.clone()),
|
||||||
(
|
("grandpa".into(), node.accounts.accounts["ed"].address.clone()),
|
||||||
"grandpa".into(),
|
|
||||||
node.accounts.accounts["ed"].address.clone(),
|
|
||||||
),
|
|
||||||
("beefy".into(), node.accounts.accounts["ec"].address.clone()),
|
("beefy".into(), node.accounts.accounts["ec"].address.clone()),
|
||||||
("eth".into(), node.accounts.accounts["eth"].address.clone()),
|
("eth".into(), node.accounts.accounts["eth"].address.clone()),
|
||||||
]
|
]
|
||||||
@@ -2054,15 +1894,9 @@ mod tests {
|
|||||||
fn get_node_keys_supports_asset_hub_polkadot() {
|
fn get_node_keys_supports_asset_hub_polkadot() {
|
||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
let node = NodeSpec { name, accounts, ..Default::default() };
|
||||||
};
|
|
||||||
let node = NodeSpec {
|
|
||||||
name,
|
|
||||||
accounts,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let node_key = get_node_keys(&node, SessionKeyType::default(), false);
|
let node_key = get_node_keys(&node, SessionKeyType::default(), false);
|
||||||
assert_eq!(node_key.2["aura"], node.accounts.accounts["sr"].address);
|
assert_eq!(node_key.2["aura"], node.accounts.accounts["sr"].address);
|
||||||
|
|||||||
+37
-125
@@ -31,14 +31,8 @@ impl Default for GenCmdOptions<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FLAGS_ADDED_BY_US: [&str; 3] = ["--no-telemetry", "--collator", "--"];
|
const FLAGS_ADDED_BY_US: [&str; 3] = ["--no-telemetry", "--collator", "--"];
|
||||||
const OPS_ADDED_BY_US: [&str; 6] = [
|
const OPS_ADDED_BY_US: [&str; 6] =
|
||||||
"--chain",
|
["--chain", "--name", "--rpc-cors", "--rpc-methods", "--parachain-id", "--node-key"];
|
||||||
"--name",
|
|
||||||
"--rpc-cors",
|
|
||||||
"--rpc-methods",
|
|
||||||
"--parachain-id",
|
|
||||||
"--node-key",
|
|
||||||
];
|
|
||||||
|
|
||||||
// TODO: can we abstract this and use only one fn (or at least split and reuse in small fns)
|
// TODO: can we abstract this and use only one fn (or at least split and reuse in small fns)
|
||||||
pub fn generate_for_cumulus_node(
|
pub fn generate_for_cumulus_node(
|
||||||
@@ -46,13 +40,7 @@ pub fn generate_for_cumulus_node(
|
|||||||
options: GenCmdOptions,
|
options: GenCmdOptions,
|
||||||
para_id: u32,
|
para_id: u32,
|
||||||
) -> (String, Vec<String>) {
|
) -> (String, Vec<String>) {
|
||||||
let NodeSpec {
|
let NodeSpec { key, args, is_validator, bootnodes_addresses, .. } = node;
|
||||||
key,
|
|
||||||
args,
|
|
||||||
is_validator,
|
|
||||||
bootnodes_addresses,
|
|
||||||
..
|
|
||||||
} = node;
|
|
||||||
|
|
||||||
let mut tmp_args: Vec<String> = vec!["--node-key".into(), key.clone()];
|
let mut tmp_args: Vec<String> = vec!["--node-key".into(), key.clone()];
|
||||||
|
|
||||||
@@ -66,11 +54,8 @@ pub fn generate_for_cumulus_node(
|
|||||||
|
|
||||||
if !bootnodes_addresses.is_empty() {
|
if !bootnodes_addresses.is_empty() {
|
||||||
tmp_args.push("--bootnodes".into());
|
tmp_args.push("--bootnodes".into());
|
||||||
let bootnodes = bootnodes_addresses
|
let bootnodes =
|
||||||
.iter()
|
bootnodes_addresses.iter().map(|m| m.to_string()).collect::<Vec<String>>().join(" ");
|
||||||
.map(|m| m.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" ");
|
|
||||||
tmp_args.push(bootnodes)
|
tmp_args.push(bootnodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,11 +91,8 @@ pub fn generate_for_cumulus_node(
|
|||||||
tmp_args.push("--base-path".into());
|
tmp_args.push("--base-path".into());
|
||||||
tmp_args.push(options.data_path.into());
|
tmp_args.push(options.data_path.into());
|
||||||
|
|
||||||
let node_specific_bootnodes: Vec<String> = node
|
let node_specific_bootnodes: Vec<String> =
|
||||||
.bootnodes_addresses
|
node.bootnodes_addresses.iter().map(|b| b.to_string()).collect();
|
||||||
.iter()
|
|
||||||
.map(|b| b.to_string())
|
|
||||||
.collect();
|
|
||||||
let full_bootnodes = [node_specific_bootnodes, options.bootnode_addr].concat();
|
let full_bootnodes = [node_specific_bootnodes, options.bootnode_addr].concat();
|
||||||
if !full_bootnodes.is_empty() {
|
if !full_bootnodes.is_empty() {
|
||||||
tmp_args.push("--bootnodes".into());
|
tmp_args.push("--bootnodes".into());
|
||||||
@@ -166,16 +148,12 @@ pub fn generate_for_cumulus_node(
|
|||||||
let full_p2p_port = node
|
let full_p2p_port = node
|
||||||
.full_node_p2p_port
|
.full_node_p2p_port
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect(&format!(
|
.expect(&format!("full node p2p_port should be specifed: {THIS_IS_A_BUG}"))
|
||||||
"full node p2p_port should be specifed: {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.0;
|
.0;
|
||||||
let full_prometheus_port = node
|
let full_prometheus_port = node
|
||||||
.full_node_prometheus_port
|
.full_node_prometheus_port
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect(&format!(
|
.expect(&format!("full node prometheus_port should be specifed: {THIS_IS_A_BUG}"))
|
||||||
"full node prometheus_port should be specifed: {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
// full_node: change p2p port if is the default
|
// full_node: change p2p port if is the default
|
||||||
@@ -270,13 +248,7 @@ pub fn generate_for_node(
|
|||||||
options: GenCmdOptions,
|
options: GenCmdOptions,
|
||||||
para_id: Option<u32>,
|
para_id: Option<u32>,
|
||||||
) -> (String, Vec<String>) {
|
) -> (String, Vec<String>) {
|
||||||
let NodeSpec {
|
let NodeSpec { key, args, is_validator, bootnodes_addresses, .. } = node;
|
||||||
key,
|
|
||||||
args,
|
|
||||||
is_validator,
|
|
||||||
bootnodes_addresses,
|
|
||||||
..
|
|
||||||
} = node;
|
|
||||||
let mut tmp_args: Vec<String> = vec![
|
let mut tmp_args: Vec<String> = vec![
|
||||||
"--node-key".into(),
|
"--node-key".into(),
|
||||||
key.clone(),
|
key.clone(),
|
||||||
@@ -302,11 +274,8 @@ pub fn generate_for_node(
|
|||||||
|
|
||||||
if !bootnodes_addresses.is_empty() {
|
if !bootnodes_addresses.is_empty() {
|
||||||
tmp_args.push("--bootnodes".into());
|
tmp_args.push("--bootnodes".into());
|
||||||
let bootnodes = bootnodes_addresses
|
let bootnodes =
|
||||||
.iter()
|
bootnodes_addresses.iter().map(|m| m.to_string()).collect::<Vec<String>>().join(" ");
|
||||||
.map(|m| m.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" ");
|
|
||||||
tmp_args.push(bootnodes)
|
tmp_args.push(bootnodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,9 +305,8 @@ pub fn generate_for_node(
|
|||||||
}) {
|
}) {
|
||||||
let mut parts = listen_val.split('/').collect::<Vec<&str>>();
|
let mut parts = listen_val.split('/').collect::<Vec<&str>>();
|
||||||
// TODO: move this to error
|
// TODO: move this to error
|
||||||
let port_part = parts
|
let port_part =
|
||||||
.get_mut(4)
|
parts.get_mut(4).expect(&format!("should have at least 5 parts {THIS_IS_A_BUG}"));
|
||||||
.expect(&format!("should have at least 5 parts {THIS_IS_A_BUG}"));
|
|
||||||
let port_to_use = p2p_port.to_string();
|
let port_to_use = p2p_port.to_string();
|
||||||
*port_part = port_to_use.as_str();
|
*port_part = port_to_use.as_str();
|
||||||
parts.join("/")
|
parts.join("/")
|
||||||
@@ -353,11 +321,8 @@ pub fn generate_for_node(
|
|||||||
tmp_args.push("--base-path".into());
|
tmp_args.push("--base-path".into());
|
||||||
tmp_args.push(options.data_path.into());
|
tmp_args.push(options.data_path.into());
|
||||||
|
|
||||||
let node_specific_bootnodes: Vec<String> = node
|
let node_specific_bootnodes: Vec<String> =
|
||||||
.bootnodes_addresses
|
node.bootnodes_addresses.iter().map(|b| b.to_string()).collect();
|
||||||
.iter()
|
|
||||||
.map(|b| b.to_string())
|
|
||||||
.collect();
|
|
||||||
let full_bootnodes = [node_specific_bootnodes, options.bootnode_addr].concat();
|
let full_bootnodes = [node_specific_bootnodes, options.bootnode_addr].concat();
|
||||||
if !full_bootnodes.is_empty() {
|
if !full_bootnodes.is_empty() {
|
||||||
tmp_args.push("--bootnodes".into());
|
tmp_args.push("--bootnodes".into());
|
||||||
@@ -448,10 +413,8 @@ mod tests {
|
|||||||
let mut name = String::from("luca");
|
let mut name = String::from("luca");
|
||||||
let initial_balance = 1_000_000_000_000_u128;
|
let initial_balance = 1_000_000_000_000_u128;
|
||||||
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
let seed = format!("//{}{name}", name.remove(0).to_uppercase());
|
||||||
let accounts = NodeAccounts {
|
let accounts =
|
||||||
accounts: generators::generate_node_keys(&seed).unwrap(),
|
NodeAccounts { accounts: generators::generate_node_keys(&seed).unwrap(), seed };
|
||||||
seed,
|
|
||||||
};
|
|
||||||
let (full_node_p2p_port, full_node_prometheus_port) = if full_node_present {
|
let (full_node_p2p_port, full_node_prometheus_port) = if full_node_present {
|
||||||
(
|
(
|
||||||
Some(generators::generate_node_port(None).unwrap()),
|
Some(generators::generate_node_port(None).unwrap()),
|
||||||
@@ -473,11 +436,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generate_for_native_cumulus_node_works() {
|
fn generate_for_native_cumulus_node_works() {
|
||||||
let node = get_node_spec(true);
|
let node = get_node_spec(true);
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: true, ..GenCmdOptions::default() };
|
||||||
is_native: true,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (program, args) = generate_for_cumulus_node(&node, opts, 1000);
|
let (program, args) = generate_for_cumulus_node(&node, opts, 1000);
|
||||||
assert_eq!(program.as_str(), "polkadot");
|
assert_eq!(program.as_str(), "polkadot");
|
||||||
@@ -487,28 +447,14 @@ mod tests {
|
|||||||
// ensure full node ports
|
// ensure full node ports
|
||||||
let i = args[divider_flag..]
|
let i = args[divider_flag..]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| {
|
.position(|x| x == node.full_node_p2p_port.as_ref().unwrap().0.to_string().as_str())
|
||||||
x == node
|
|
||||||
.full_node_p2p_port
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.0
|
|
||||||
.to_string()
|
|
||||||
.as_str()
|
|
||||||
})
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(&args[divider_flag + i - 1], "--port");
|
assert_eq!(&args[divider_flag + i - 1], "--port");
|
||||||
|
|
||||||
let i = args[divider_flag..]
|
let i = args[divider_flag..]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| {
|
.position(|x| {
|
||||||
x == node
|
x == node.full_node_prometheus_port.as_ref().unwrap().0.to_string().as_str()
|
||||||
.full_node_prometheus_port
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.0
|
|
||||||
.to_string()
|
|
||||||
.as_str()
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(&args[divider_flag + i - 1], "--prometheus-port");
|
assert_eq!(&args[divider_flag + i - 1], "--prometheus-port");
|
||||||
@@ -520,11 +466,8 @@ mod tests {
|
|||||||
fn generate_for_native_cumulus_node_rpc_external_is_not_removed_if_is_set_by_user() {
|
fn generate_for_native_cumulus_node_rpc_external_is_not_removed_if_is_set_by_user() {
|
||||||
let mut node = get_node_spec(true);
|
let mut node = get_node_spec(true);
|
||||||
node.args.push("--unsafe-rpc-external".into());
|
node.args.push("--unsafe-rpc-external".into());
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: true, ..GenCmdOptions::default() };
|
||||||
is_native: true,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (_, args) = generate_for_cumulus_node(&node, opts, 1000);
|
let (_, args) = generate_for_cumulus_node(&node, opts, 1000);
|
||||||
|
|
||||||
@@ -534,11 +477,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generate_for_non_native_cumulus_node_works() {
|
fn generate_for_non_native_cumulus_node_works() {
|
||||||
let node = get_node_spec(true);
|
let node = get_node_spec(true);
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: false, ..GenCmdOptions::default() };
|
||||||
is_native: false,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (program, args) = generate_for_cumulus_node(&node, opts, 1000);
|
let (program, args) = generate_for_cumulus_node(&node, opts, 1000);
|
||||||
assert_eq!(program.as_str(), "polkadot");
|
assert_eq!(program.as_str(), "polkadot");
|
||||||
@@ -548,46 +488,27 @@ mod tests {
|
|||||||
// ensure full node ports
|
// ensure full node ports
|
||||||
let i = args[divider_flag..]
|
let i = args[divider_flag..]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| {
|
.position(|x| x == node.full_node_p2p_port.as_ref().unwrap().0.to_string().as_str())
|
||||||
x == node
|
|
||||||
.full_node_p2p_port
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.0
|
|
||||||
.to_string()
|
|
||||||
.as_str()
|
|
||||||
})
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(&args[divider_flag + i - 1], "--port");
|
assert_eq!(&args[divider_flag + i - 1], "--port");
|
||||||
|
|
||||||
let i = args[divider_flag..]
|
let i = args[divider_flag..]
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| {
|
.position(|x| {
|
||||||
x == node
|
x == node.full_node_prometheus_port.as_ref().unwrap().0.to_string().as_str()
|
||||||
.full_node_prometheus_port
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.0
|
|
||||||
.to_string()
|
|
||||||
.as_str()
|
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(&args[divider_flag + i - 1], "--prometheus-port");
|
assert_eq!(&args[divider_flag + i - 1], "--prometheus-port");
|
||||||
|
|
||||||
// we expect to find this arg in collator node part
|
// we expect to find this arg in collator node part
|
||||||
assert!(&args[0..divider_flag]
|
assert!(&args[0..divider_flag].iter().any(|arg| arg == "--unsafe-rpc-external"));
|
||||||
.iter()
|
|
||||||
.any(|arg| arg == "--unsafe-rpc-external"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_for_native_node_rpc_external_works() {
|
fn generate_for_native_node_rpc_external_works() {
|
||||||
let node = get_node_spec(false);
|
let node = get_node_spec(false);
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: true, ..GenCmdOptions::default() };
|
||||||
is_native: true,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
||||||
assert_eq!(program.as_str(), "polkadot");
|
assert_eq!(program.as_str(), "polkadot");
|
||||||
@@ -598,11 +519,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn generate_for_non_native_node_rpc_external_works() {
|
fn generate_for_non_native_node_rpc_external_works() {
|
||||||
let node = get_node_spec(false);
|
let node = get_node_spec(false);
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: false, ..GenCmdOptions::default() };
|
||||||
is_native: false,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
||||||
assert_eq!(program.as_str(), "polkadot");
|
assert_eq!(program.as_str(), "polkadot");
|
||||||
@@ -613,22 +531,16 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_arg_removal_removes_insecure_validator_flag() {
|
fn test_arg_removal_removes_insecure_validator_flag() {
|
||||||
let mut node = get_node_spec(false);
|
let mut node = get_node_spec(false);
|
||||||
node.args
|
node.args.push(Arg::Flag("-:--insecure-validator-i-know-what-i-do".into()));
|
||||||
.push(Arg::Flag("-:--insecure-validator-i-know-what-i-do".into()));
|
|
||||||
node.is_validator = true;
|
node.is_validator = true;
|
||||||
node.available_args_output = Some("--insecure-validator-i-know-what-i-do".to_string());
|
node.available_args_output = Some("--insecure-validator-i-know-what-i-do".to_string());
|
||||||
|
|
||||||
let opts = GenCmdOptions {
|
let opts =
|
||||||
use_wrapper: false,
|
GenCmdOptions { use_wrapper: false, is_native: true, ..GenCmdOptions::default() };
|
||||||
is_native: true,
|
|
||||||
..GenCmdOptions::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
let (program, args) = generate_for_node(&node, opts, Some(1000));
|
||||||
assert_eq!(program.as_str(), "polkadot");
|
assert_eq!(program.as_str(), "polkadot");
|
||||||
assert!(args.iter().any(|arg| arg == "--validator"));
|
assert!(args.iter().any(|arg| arg == "--validator"));
|
||||||
assert!(!args
|
assert!(!args.iter().any(|arg| arg == "--insecure-validator-i-know-what-i-do"));
|
||||||
.iter()
|
|
||||||
.any(|arg| arg == "--insecure-validator-i-know-what-i-do"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -29,13 +29,7 @@ mod tests {
|
|||||||
fn generate_for_alice() {
|
fn generate_for_alice() {
|
||||||
let s = "alice";
|
let s = "alice";
|
||||||
let (key, peer_id) = generate(s).unwrap();
|
let (key, peer_id) = generate(s).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(&key, "2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90");
|
||||||
&key,
|
assert_eq!(&peer_id, "12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm");
|
||||||
"2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
&peer_id,
|
|
||||||
"12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
use pezsp_core::{crypto::SecretStringError, ecdsa, ed25519, keccak_256, sr25519, Pair, H160, H256};
|
use pezsp_core::{
|
||||||
|
crypto::SecretStringError, ecdsa, ed25519, keccak_256, sr25519, Pair, H160, H256,
|
||||||
|
};
|
||||||
|
|
||||||
use super::errors::GeneratorError;
|
use super::errors::GeneratorError;
|
||||||
use crate::shared::types::{Accounts, NodeAccount};
|
use crate::shared::types::{Accounts, NodeAccount};
|
||||||
@@ -126,26 +128,14 @@ mod tests {
|
|||||||
let ec = pair.get("ec").unwrap();
|
let ec = pair.get("ec").unwrap();
|
||||||
let eth = pair.get("eth").unwrap();
|
let eth = pair.get("eth").unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(sr.address, "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY");
|
||||||
sr.address,
|
assert_eq!(sr_stash.address, "5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY");
|
||||||
"5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"
|
assert_eq!(ed.address, "5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu");
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
sr_stash.address,
|
|
||||||
"5GNJqTPyNqANBkUVMN1LPPrxXnFouWXoe2wNSmmEoLctxiZY"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ed.address,
|
|
||||||
"5FA9nQDVg267DEd8m1ZypXLBnvN7SFxYwV7ndqSYGiN9TTpu"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("0x{}", ec.public_key),
|
format!("0x{}", ec.public_key),
|
||||||
"0x020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a1"
|
"0x020a1091341fe5664bfa1782d5e04779689068c916b04cb365ec3153755684d9a1"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(format!("0x{}", eth.public_key), "0xe04cc55ebee1cbce552f250e85c57b70b2e2625b")
|
||||||
format!("0x{}", eth.public_key),
|
|
||||||
"0xe04cc55ebee1cbce552f250e85c57b70b2e2625b"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-50
@@ -71,10 +71,7 @@ fn generate_keystore_filename(key_type: &KeystoreKeyType, acc: &NodeAccounts) ->
|
|||||||
let pk = acc
|
let pk = acc
|
||||||
.accounts
|
.accounts
|
||||||
.get(account_key)
|
.get(account_key)
|
||||||
.expect(&format!(
|
.expect(&format!("Key '{}' should be set for node {THIS_IS_A_BUG}", account_key))
|
||||||
"Key '{}' should be set for node {THIS_IS_A_BUG}",
|
|
||||||
account_key
|
|
||||||
))
|
|
||||||
.public_key
|
.public_key
|
||||||
.as_str();
|
.as_str();
|
||||||
|
|
||||||
@@ -92,22 +89,10 @@ mod tests {
|
|||||||
|
|
||||||
fn create_test_accounts() -> NodeAccounts {
|
fn create_test_accounts() -> NodeAccounts {
|
||||||
let mut accounts = HashMap::new();
|
let mut accounts = HashMap::new();
|
||||||
accounts.insert(
|
accounts.insert("sr".to_string(), NodeAccount::new("sr_address", "sr_public_key"));
|
||||||
"sr".to_string(),
|
accounts.insert("ed".to_string(), NodeAccount::new("ed_address", "ed_public_key"));
|
||||||
NodeAccount::new("sr_address", "sr_public_key"),
|
accounts.insert("ec".to_string(), NodeAccount::new("ec_address", "ec_public_key"));
|
||||||
);
|
NodeAccounts { seed: "//Alice".to_string(), accounts }
|
||||||
accounts.insert(
|
|
||||||
"ed".to_string(),
|
|
||||||
NodeAccount::new("ed_address", "ed_public_key"),
|
|
||||||
);
|
|
||||||
accounts.insert(
|
|
||||||
"ec".to_string(),
|
|
||||||
NodeAccount::new("ec_address", "ec_public_key"),
|
|
||||||
);
|
|
||||||
NodeAccounts {
|
|
||||||
seed: "//Alice".to_string(),
|
|
||||||
accounts,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_test_fs() -> InMemoryFileSystem {
|
fn create_test_fs() -> InMemoryFileSystem {
|
||||||
@@ -133,10 +118,8 @@ mod tests {
|
|||||||
|
|
||||||
assert!(filenames.len() > 10);
|
assert!(filenames.len() > 10);
|
||||||
|
|
||||||
let filename_strs: Vec<String> = filenames
|
let filename_strs: Vec<String> =
|
||||||
.iter()
|
filenames.iter().map(|p| p.to_string_lossy().to_string()).collect();
|
||||||
.map(|p| p.to_string_lossy().to_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Check that aura key is generated (hex of "aura" is 61757261)
|
// Check that aura key is generated (hex of "aura" is 61757261)
|
||||||
assert!(filename_strs.iter().any(|f| f.starts_with("61757261")));
|
assert!(filename_strs.iter().any(|f| f.starts_with("61757261")));
|
||||||
@@ -162,10 +145,8 @@ mod tests {
|
|||||||
let filenames = res.unwrap();
|
let filenames = res.unwrap();
|
||||||
assert_eq!(filenames.len(), 2);
|
assert_eq!(filenames.len(), 2);
|
||||||
|
|
||||||
let filename_strs: Vec<String> = filenames
|
let filename_strs: Vec<String> =
|
||||||
.iter()
|
filenames.iter().map(|p| p.to_string_lossy().to_string()).collect();
|
||||||
.map(|p| p.to_string_lossy().to_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// audi uses sr scheme by default
|
// audi uses sr scheme by default
|
||||||
assert!(filename_strs
|
assert!(filename_strs
|
||||||
@@ -221,27 +202,13 @@ mod tests {
|
|||||||
for tc in test_cases {
|
for tc in test_cases {
|
||||||
let accounts = create_test_accounts();
|
let accounts = create_test_accounts();
|
||||||
let fs = create_test_fs();
|
let fs = create_test_fs();
|
||||||
let scoped_fs = ScopedFilesystem {
|
let scoped_fs = ScopedFilesystem { fs: &fs, base_dir: "/tmp/test" };
|
||||||
fs: &fs,
|
|
||||||
base_dir: "/tmp/test",
|
|
||||||
};
|
|
||||||
|
|
||||||
let key_types: Vec<&str> = tc.key_types.clone();
|
let key_types: Vec<&str> = tc.key_types.clone();
|
||||||
let res = generate(
|
let res =
|
||||||
&accounts,
|
generate(&accounts, "node1", &scoped_fs, tc.asset_hub_polkadot, key_types).await;
|
||||||
"node1",
|
|
||||||
&scoped_fs,
|
|
||||||
tc.asset_hub_polkadot,
|
|
||||||
key_types,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
assert!(
|
assert!(res.is_ok(), "[{}] Expected Ok but got: {:?}", tc.name, res.err());
|
||||||
res.is_ok(),
|
|
||||||
"[{}] Expected Ok but got: {:?}",
|
|
||||||
tc.name,
|
|
||||||
res.err()
|
|
||||||
);
|
|
||||||
let filenames = res.unwrap();
|
let filenames = res.unwrap();
|
||||||
|
|
||||||
assert_eq!(filenames.len(), 1, "[{}] Expected 1 file", tc.name);
|
assert_eq!(filenames.len(), 1, "[{}] Expected 1 file", tc.name);
|
||||||
@@ -268,10 +235,7 @@ mod tests {
|
|||||||
async fn generate_ignores_invalid_key_specs_and_uses_defaults() {
|
async fn generate_ignores_invalid_key_specs_and_uses_defaults() {
|
||||||
let accounts = create_test_accounts();
|
let accounts = create_test_accounts();
|
||||||
let fs = create_test_fs();
|
let fs = create_test_fs();
|
||||||
let scoped_fs = ScopedFilesystem {
|
let scoped_fs = ScopedFilesystem { fs: &fs, base_dir: "/tmp/test" };
|
||||||
fs: &fs,
|
|
||||||
base_dir: "/tmp/test",
|
|
||||||
};
|
|
||||||
|
|
||||||
let key_types = vec![
|
let key_types = vec![
|
||||||
"invalid", // Too long
|
"invalid", // Too long
|
||||||
|
|||||||
+2
-7
@@ -58,10 +58,7 @@ pub struct KeystoreKeyType {
|
|||||||
|
|
||||||
impl KeystoreKeyType {
|
impl KeystoreKeyType {
|
||||||
pub fn new(key_type: impl Into<String>, scheme: KeyScheme) -> Self {
|
pub fn new(key_type: impl Into<String>, scheme: KeyScheme) -> Self {
|
||||||
Self {
|
Self { key_type: key_type.into(), scheme }
|
||||||
key_type: key_type.into(),
|
|
||||||
scheme,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,9 +157,7 @@ pub fn get_default_keystore_key_types(is_asset_hub_polkadot: bool) -> Vec<Keysto
|
|||||||
default_keys
|
default_keys
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|key_type| {
|
.filter_map(|key_type| {
|
||||||
predefined_schemes
|
predefined_schemes.get(*key_type).map(|scheme| KeystoreKeyType::new(*key_type, *scheme))
|
||||||
.get(*key_type)
|
|
||||||
.map(|scheme| KeystoreKeyType::new(*key_type, *scheme))
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-19
@@ -41,12 +41,7 @@ impl ParaArtifact {
|
|||||||
artifact_type: ParaArtifactType,
|
artifact_type: ParaArtifactType,
|
||||||
build_option: ParaArtifactBuildOption,
|
build_option: ParaArtifactBuildOption,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self { artifact_type, build_option, artifact_path: None, image: None }
|
||||||
artifact_type,
|
|
||||||
build_option,
|
|
||||||
artifact_path: None,
|
|
||||||
image: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn image(mut self, image: Option<String>) -> Self {
|
pub(crate) fn image(mut self, image: Option<String>) -> Self {
|
||||||
@@ -78,10 +73,7 @@ impl ParaArtifact {
|
|||||||
},
|
},
|
||||||
ParaArtifactBuildOption::Command(cmd) => (cmd, &vec![]),
|
ParaArtifactBuildOption::Command(cmd) => (cmd, &vec![]),
|
||||||
ParaArtifactBuildOption::CommandWithCustomArgs(cmd_with_custom_args) => {
|
ParaArtifactBuildOption::CommandWithCustomArgs(cmd_with_custom_args) => {
|
||||||
(
|
(&cmd_with_custom_args.cmd().as_str().to_string(), cmd_with_custom_args.args())
|
||||||
&cmd_with_custom_args.cmd().as_str().to_string(),
|
|
||||||
cmd_with_custom_args.args(),
|
|
||||||
)
|
|
||||||
// (cmd.cmd_as_str().to_string(), cmd.1)
|
// (cmd.cmd_as_str().to_string(), cmd.1)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -103,11 +95,8 @@ impl ParaArtifact {
|
|||||||
chain_spec_path.as_ref().to_string_lossy()
|
chain_spec_path.as_ref().to_string_lossy()
|
||||||
);
|
);
|
||||||
// Remote path to be injected
|
// Remote path to be injected
|
||||||
let chain_spec_path_in_pod = format!(
|
let chain_spec_path_in_pod =
|
||||||
"{}/{}",
|
format!("{}/{}", NODE_CONFIG_DIR, chain_spec_path.as_ref().to_string_lossy());
|
||||||
NODE_CONFIG_DIR,
|
|
||||||
chain_spec_path.as_ref().to_string_lossy()
|
|
||||||
);
|
|
||||||
// Path in the context of the node, this can be different in the context of the providers (e.g native)
|
// Path in the context of the node, this can be different in the context of the providers (e.g native)
|
||||||
let chain_spec_path_in_args = if ns.capabilities().prefix_with_full_path {
|
let chain_spec_path_in_args = if ns.capabilities().prefix_with_full_path {
|
||||||
// In native
|
// In native
|
||||||
@@ -140,10 +129,7 @@ impl ParaArtifact {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec![TransferedFile::new(
|
vec![TransferedFile::new(chain_spec_path_local, chain_spec_path_in_pod)]
|
||||||
chain_spec_path_local,
|
|
||||||
chain_spec_path_in_pod,
|
|
||||||
)]
|
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ pub fn generate(port: Option<Port>) -> Result<ParkedPort, GeneratorError> {
|
|||||||
.map_err(|_e| GeneratorError::PortGeneration(port, "Can't bind".into()))?;
|
.map_err(|_e| GeneratorError::PortGeneration(port, "Can't bind".into()))?;
|
||||||
let port = listener
|
let port = listener
|
||||||
.local_addr()
|
.local_addr()
|
||||||
.expect(&format!(
|
.expect(&format!("We should always get the local_addr from the listener {THIS_IS_A_BUG}"))
|
||||||
"We should always get the local_addr from the listener {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.port();
|
.port();
|
||||||
Ok(ParkedPort::new(port, listener))
|
Ok(ParkedPort::new(port, listener))
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-122
@@ -61,10 +61,7 @@ where
|
|||||||
T: FileSystem + Sync + Send + Clone,
|
T: FileSystem + Sync + Send + Clone,
|
||||||
{
|
{
|
||||||
pub fn new(filesystem: T, provider: DynProvider) -> Self {
|
pub fn new(filesystem: T, provider: DynProvider) -> Self {
|
||||||
Self {
|
Self { filesystem, provider }
|
||||||
filesystem,
|
|
||||||
provider,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn spawn(
|
pub async fn spawn(
|
||||||
@@ -74,10 +71,8 @@ where
|
|||||||
let global_timeout = network_config.global_settings().network_spawn_timeout();
|
let global_timeout = network_config.global_settings().network_spawn_timeout();
|
||||||
let network_spec = NetworkSpec::from_config(&network_config).await?;
|
let network_spec = NetworkSpec::from_config(&network_config).await?;
|
||||||
|
|
||||||
let res = timeout(
|
let res =
|
||||||
Duration::from_secs(global_timeout.into()),
|
timeout(Duration::from_secs(global_timeout.into()), self.spawn_inner(network_spec))
|
||||||
self.spawn_inner(network_spec),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|_| OrchestratorError::GlobalTimeOut(global_timeout));
|
.map_err(|_| OrchestratorError::GlobalTimeOut(global_timeout));
|
||||||
res?
|
res?
|
||||||
@@ -88,10 +83,8 @@ where
|
|||||||
network_spec: NetworkSpec,
|
network_spec: NetworkSpec,
|
||||||
) -> Result<Network<T>, OrchestratorError> {
|
) -> Result<Network<T>, OrchestratorError> {
|
||||||
let global_timeout = network_spec.global_settings.network_spawn_timeout();
|
let global_timeout = network_spec.global_settings.network_spawn_timeout();
|
||||||
let res = timeout(
|
let res =
|
||||||
Duration::from_secs(global_timeout as u64),
|
timeout(Duration::from_secs(global_timeout as u64), self.spawn_inner(network_spec))
|
||||||
self.spawn_inner(network_spec),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|_| OrchestratorError::GlobalTimeOut(global_timeout));
|
.map_err(|_| OrchestratorError::GlobalTimeOut(global_timeout));
|
||||||
res?
|
res?
|
||||||
@@ -108,10 +101,7 @@ where
|
|||||||
let zombie_json: serde_json::Value = serde_json::from_str(&zombie_json_content)?;
|
let zombie_json: serde_json::Value = serde_json::from_str(&zombie_json_content)?;
|
||||||
|
|
||||||
info!("recreating namespace...");
|
info!("recreating namespace...");
|
||||||
let ns: DynNamespace = self
|
let ns: DynNamespace = self.provider.create_namespace_from_json(&zombie_json).await?;
|
||||||
.provider
|
|
||||||
.create_namespace_from_json(&zombie_json)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
info!("recreating relaychain...");
|
info!("recreating relaychain...");
|
||||||
let (relay, initial_spec) =
|
let (relay, initial_spec) =
|
||||||
@@ -159,9 +149,7 @@ where
|
|||||||
|
|
||||||
// create namespace
|
// create namespace
|
||||||
let ns = if let Some(base_dir) = network_spec.global_settings.base_dir() {
|
let ns = if let Some(base_dir) = network_spec.global_settings.base_dir() {
|
||||||
self.provider
|
self.provider.create_namespace_with_base_dir(base_dir).await?
|
||||||
.create_namespace_with_base_dir(base_dir)
|
|
||||||
.await?
|
|
||||||
} else {
|
} else {
|
||||||
self.provider.create_namespace().await?
|
self.provider.create_namespace().await?
|
||||||
};
|
};
|
||||||
@@ -175,26 +163,16 @@ where
|
|||||||
info!("🕰 start time: {:?}", start_time);
|
info!("🕰 start time: {:?}", start_time);
|
||||||
info!("⚙️ spawn concurrency: {spawn_concurrency} (limited by tokens: {limited_by_tokens})");
|
info!("⚙️ spawn concurrency: {spawn_concurrency} (limited by tokens: {limited_by_tokens})");
|
||||||
|
|
||||||
network_spec
|
network_spec.populate_nodes_available_args(ns.clone()).await?;
|
||||||
.populate_nodes_available_args(ns.clone())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let base_dir = ns.base_dir().to_string_lossy();
|
let base_dir = ns.base_dir().to_string_lossy();
|
||||||
let scoped_fs = ScopedFilesystem::new(&self.filesystem, &base_dir);
|
let scoped_fs = ScopedFilesystem::new(&self.filesystem, &base_dir);
|
||||||
// Create chain-spec for relaychain
|
// Create chain-spec for relaychain
|
||||||
network_spec
|
network_spec.relaychain.chain_spec.build(&ns, &scoped_fs).await?;
|
||||||
.relaychain
|
|
||||||
.chain_spec
|
|
||||||
.build(&ns, &scoped_fs)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
debug!("relaychain spec built!");
|
debug!("relaychain spec built!");
|
||||||
// Create parachain artifacts (chain-spec, wasm, state)
|
// Create parachain artifacts (chain-spec, wasm, state)
|
||||||
let relay_chain_id = network_spec
|
let relay_chain_id = network_spec.relaychain.chain_spec.read_chain_id(&scoped_fs).await?;
|
||||||
.relaychain
|
|
||||||
.chain_spec
|
|
||||||
.read_chain_id(&scoped_fs)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let relay_chain_name = network_spec.relaychain.chain.as_str().to_owned();
|
let relay_chain_name = network_spec.relaychain.chain.as_str().to_owned();
|
||||||
let base_dir_exists = network_spec.global_settings.base_dir().is_some();
|
let base_dir_exists = network_spec.global_settings.base_dir().is_some();
|
||||||
@@ -233,19 +211,11 @@ where
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// Build raw version
|
// Build raw version
|
||||||
network_spec
|
network_spec.relaychain.chain_spec.build_raw(&ns, &scoped_fs, None).await?;
|
||||||
.relaychain
|
|
||||||
.chain_spec
|
|
||||||
.build_raw(&ns, &scoped_fs, None)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// override wasm if needed
|
// override wasm if needed
|
||||||
if let Some(ref wasm_override) = network_spec.relaychain.wasm_override {
|
if let Some(ref wasm_override) = network_spec.relaychain.wasm_override {
|
||||||
network_spec
|
network_spec.relaychain.chain_spec.override_code(&scoped_fs, wasm_override).await?;
|
||||||
.relaychain
|
|
||||||
.chain_spec
|
|
||||||
.override_code(&scoped_fs, wasm_override)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// override raw spec if needed
|
// override raw spec if needed
|
||||||
@@ -276,10 +246,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let global_files_to_inject = vec![TransferedFile::new(
|
let global_files_to_inject = vec![TransferedFile::new(
|
||||||
PathBuf::from(format!(
|
PathBuf::from(format!("{}/{relay_chain_name}.json", ns.base_dir().to_string_lossy())),
|
||||||
"{}/{relay_chain_name}.json",
|
|
||||||
ns.base_dir().to_string_lossy()
|
|
||||||
)),
|
|
||||||
PathBuf::from(format!("/cfg/{relay_chain_name}.json")),
|
PathBuf::from(format!("/cfg/{relay_chain_name}.json")),
|
||||||
)];
|
)];
|
||||||
|
|
||||||
@@ -339,11 +306,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the bootnodes to the relaychain spec file and ctx
|
// Add the bootnodes to the relaychain spec file and ctx
|
||||||
network_spec
|
network_spec.relaychain.chain_spec.add_bootnodes(&scoped_fs, &bootnodes_addr).await?;
|
||||||
.relaychain
|
|
||||||
.chain_spec
|
|
||||||
.add_bootnodes(&scoped_fs, &bootnodes_addr)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
ctx.bootnodes_addr = &bootnodes_addr;
|
ctx.bootnodes_addr = &bootnodes_addr;
|
||||||
|
|
||||||
@@ -436,9 +399,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(para_chain_spec) = para.chain_spec.as_ref() {
|
if let Some(para_chain_spec) = para.chain_spec.as_ref() {
|
||||||
para_chain_spec
|
para_chain_spec.add_bootnodes(&scoped_fs, &bootnodes_addr).await?;
|
||||||
.add_bootnodes(&scoped_fs, &bootnodes_addr)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx_para.bootnodes_addr = &bootnodes_addr;
|
ctx_para.bootnodes_addr = &bootnodes_addr;
|
||||||
@@ -527,9 +488,7 @@ where
|
|||||||
warn!("⚠️ Error getting start_time timestamp");
|
warn!("⚠️ Error getting start_time timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
scoped_fs
|
scoped_fs.write("zombie.json", serde_json::to_string_pretty(&zombie_json)?).await?;
|
||||||
.write("zombie.json", serde_json::to_string_pretty(&zombie_json)?)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if network_spec.global_settings.tear_down_on_failure() {
|
if network_spec.global_settings.tear_down_on_failure() {
|
||||||
network.spawn_watching_task();
|
network.spawn_watching_task();
|
||||||
@@ -551,11 +510,8 @@ async fn recreate_network_nodes_from_json(
|
|||||||
let mut nodes = Vec::with_capacity(raw_nodes.len());
|
let mut nodes = Vec::with_capacity(raw_nodes.len());
|
||||||
for raw in raw_nodes {
|
for raw in raw_nodes {
|
||||||
// validate provider tag
|
// validate provider tag
|
||||||
let provider_tag = raw
|
let provider_tag =
|
||||||
.inner
|
raw.inner.get("provider_tag").and_then(|v| v.as_str()).ok_or_else(|| {
|
||||||
.get("provider_tag")
|
|
||||||
.and_then(|v| v.as_str())
|
|
||||||
.ok_or_else(|| {
|
|
||||||
OrchestratorError::InvalidConfig("Missing `provider_tag` in inner node JSON".into())
|
OrchestratorError::InvalidConfig("Missing `provider_tag` in inner node JSON".into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -587,9 +543,7 @@ async fn recreate_relaychain_from_json(
|
|||||||
) -> Result<(Relaychain, NetworkSpec), OrchestratorError> {
|
) -> Result<(Relaychain, NetworkSpec), OrchestratorError> {
|
||||||
let relay_json = zombie_json
|
let relay_json = zombie_json
|
||||||
.get("relay")
|
.get("relay")
|
||||||
.ok_or(OrchestratorError::InvalidConfig(
|
.ok_or(OrchestratorError::InvalidConfig("Missing `relay` field in zombie.json".into()))?
|
||||||
"Missing `relay` field in zombie.json".into(),
|
|
||||||
))?
|
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
let mut relay_raw: RawRelaychain = serde_json::from_value(relay_json)?;
|
let mut relay_raw: RawRelaychain = serde_json::from_value(relay_json)?;
|
||||||
@@ -805,10 +759,8 @@ fn spawn_concurrency_from_env() -> Option<usize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_concurrency(spec: &NetworkSpec) -> Result<(usize, bool), anyhow::Error> {
|
fn calculate_concurrency(spec: &NetworkSpec) -> Result<(usize, bool), anyhow::Error> {
|
||||||
let desired_spawn_concurrency = match (
|
let desired_spawn_concurrency =
|
||||||
spawn_concurrency_from_env(),
|
match (spawn_concurrency_from_env(), spec.global_settings.spawn_concurrency()) {
|
||||||
spec.global_settings.spawn_concurrency(),
|
|
||||||
) {
|
|
||||||
(Some(n), _) => Some(n),
|
(Some(n), _) => Some(n),
|
||||||
(None, Some(n)) => Some(n),
|
(None, Some(n)) => Some(n),
|
||||||
_ => None,
|
_ => None,
|
||||||
@@ -843,10 +795,7 @@ fn calculate_concurrency(spec: &NetworkSpec) -> Result<(usize, bool), anyhow::Er
|
|||||||
fn dependency_levels_among<'a>(
|
fn dependency_levels_among<'a>(
|
||||||
nodes: &'a [&'a NodeSpec],
|
nodes: &'a [&'a NodeSpec],
|
||||||
) -> Result<Vec<Vec<&'a NodeSpec>>, OrchestratorError> {
|
) -> Result<Vec<Vec<&'a NodeSpec>>, OrchestratorError> {
|
||||||
let by_name = nodes
|
let by_name = nodes.iter().map(|n| (n.name.as_str(), *n)).collect::<HashMap<_, _>>();
|
||||||
.iter()
|
|
||||||
.map(|n| (n.name.as_str(), *n))
|
|
||||||
.collect::<HashMap<_, _>>();
|
|
||||||
|
|
||||||
let mut graph = HashMap::with_capacity(nodes.len());
|
let mut graph = HashMap::with_capacity(nodes.len());
|
||||||
let mut indegree = HashMap::with_capacity(nodes.len());
|
let mut indegree = HashMap::with_capacity(nodes.len());
|
||||||
@@ -900,15 +849,12 @@ fn dependency_levels_among<'a>(
|
|||||||
let mut current_level = Vec::with_capacity(level_size);
|
let mut current_level = Vec::with_capacity(level_size);
|
||||||
|
|
||||||
for _ in 0..level_size {
|
for _ in 0..level_size {
|
||||||
let n = queue
|
let n = queue.pop_front().expect(&format!("{QUEUE_NOT_EMPTY} {THIS_IS_A_BUG}"));
|
||||||
.pop_front()
|
|
||||||
.expect(&format!("{QUEUE_NOT_EMPTY} {THIS_IS_A_BUG}"));
|
|
||||||
current_level.push(n);
|
current_level.push(n);
|
||||||
processed_count += 1;
|
processed_count += 1;
|
||||||
|
|
||||||
for &neighbour in graph
|
for &neighbour in
|
||||||
.get(n.name.as_str())
|
graph.get(n.name.as_str()).expect(&format!("{GRAPH_CONTAINS_NAME} {THIS_IS_A_BUG}"))
|
||||||
.expect(&format!("{GRAPH_CONTAINS_NAME} {THIS_IS_A_BUG}"))
|
|
||||||
{
|
{
|
||||||
let neighbour_indegree = indegree
|
let neighbour_indegree = indegree
|
||||||
.get_mut(neighbour.name.as_str())
|
.get_mut(neighbour.name.as_str())
|
||||||
@@ -955,15 +901,10 @@ impl<'a, FS: FileSystem> ScopedFilesystem<'a, FS> {
|
|||||||
|
|
||||||
async fn copy_files(&self, files: Vec<&TransferedFile>) -> Result<(), FileSystemError> {
|
async fn copy_files(&self, files: Vec<&TransferedFile>) -> Result<(), FileSystemError> {
|
||||||
for file in files {
|
for file in files {
|
||||||
let full_remote_path = PathBuf::from(format!(
|
let full_remote_path =
|
||||||
"{}/{}",
|
PathBuf::from(format!("{}/{}", self.base_dir, file.remote_path.to_string_lossy()));
|
||||||
self.base_dir,
|
|
||||||
file.remote_path.to_string_lossy()
|
|
||||||
));
|
|
||||||
trace!("coping file: {file}");
|
trace!("coping file: {file}");
|
||||||
self.fs
|
self.fs.copy(file.local_path.as_path(), full_remote_path).await?;
|
||||||
.copy(file.local_path.as_path(), full_remote_path)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -993,20 +934,12 @@ impl<'a, FS: FileSystem> ScopedFilesystem<'a, FS> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn create_dir(&self, path: impl AsRef<Path>) -> Result<(), FileSystemError> {
|
async fn create_dir(&self, path: impl AsRef<Path>) -> Result<(), FileSystemError> {
|
||||||
let path = PathBuf::from(format!(
|
let path = PathBuf::from(format!("{}/{}", self.base_dir, path.as_ref().to_string_lossy()));
|
||||||
"{}/{}",
|
|
||||||
self.base_dir,
|
|
||||||
path.as_ref().to_string_lossy()
|
|
||||||
));
|
|
||||||
self.fs.create_dir(path).await
|
self.fs.create_dir(path).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_dir_all(&self, path: impl AsRef<Path>) -> Result<(), FileSystemError> {
|
async fn create_dir_all(&self, path: impl AsRef<Path>) -> Result<(), FileSystemError> {
|
||||||
let path = PathBuf::from(format!(
|
let path = PathBuf::from(format!("{}/{}", self.base_dir, path.as_ref().to_string_lossy()));
|
||||||
"{}/{}",
|
|
||||||
self.base_dir,
|
|
||||||
path.as_ref().to_string_lossy()
|
|
||||||
));
|
|
||||||
self.fs.create_dir_all(path).await
|
self.fs.create_dir_all(path).await
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,27 +1043,17 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_node_with_dependencies(name: &str, dependencies: Option<Vec<&NodeSpec>>) -> NodeSpec {
|
fn get_node_with_dependencies(name: &str, dependencies: Option<Vec<&NodeSpec>>) -> NodeSpec {
|
||||||
let mut spec = NodeSpec {
|
let mut spec = NodeSpec { name: name.to_string(), ..Default::default() };
|
||||||
name: name.to_string(),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
if let Some(dependencies) = dependencies {
|
if let Some(dependencies) = dependencies {
|
||||||
for node in dependencies {
|
for node in dependencies {
|
||||||
spec.args.push(
|
spec.args.push(format!("{{{{ZOMBIE:{}:someField}}}}", node.name).as_str().into());
|
||||||
format!("{{{{ZOMBIE:{}:someField}}}}", node.name)
|
|
||||||
.as_str()
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spec
|
spec
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_levels(actual_levels: Vec<Vec<&NodeSpec>>, expected_levels: Vec<Vec<&str>>) {
|
fn verify_levels(actual_levels: Vec<Vec<&NodeSpec>>, expected_levels: Vec<Vec<&str>>) {
|
||||||
actual_levels
|
actual_levels.iter().zip(expected_levels).for_each(|(actual_level, expected_level)| {
|
||||||
.iter()
|
|
||||||
.zip(expected_levels)
|
|
||||||
.for_each(|(actual_level, expected_level)| {
|
|
||||||
assert_eq!(actual_level.len(), expected_level.len());
|
assert_eq!(actual_level.len(), expected_level.len());
|
||||||
actual_level
|
actual_level
|
||||||
.iter()
|
.iter()
|
||||||
@@ -1218,10 +1141,8 @@ mod tests {
|
|||||||
let network_config = generate(false, Some("cargo")).unwrap();
|
let network_config = generate(false, Some("cargo")).unwrap();
|
||||||
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
||||||
|
|
||||||
let global_settings = GlobalSettingsBuilder::new()
|
let global_settings =
|
||||||
.with_spawn_concurrency(4)
|
GlobalSettingsBuilder::new().with_spawn_concurrency(4).build().unwrap();
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
spec.set_global_settings(global_settings);
|
spec.set_global_settings(global_settings);
|
||||||
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
||||||
@@ -1237,15 +1158,12 @@ mod tests {
|
|||||||
let network_config = generate(false, Some("cargo")).unwrap();
|
let network_config = generate(false, Some("cargo")).unwrap();
|
||||||
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
||||||
|
|
||||||
let global_settings = GlobalSettingsBuilder::new()
|
let global_settings =
|
||||||
.with_spawn_concurrency(4)
|
GlobalSettingsBuilder::new().with_spawn_concurrency(4).build().unwrap();
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
spec.set_global_settings(global_settings);
|
spec.set_global_settings(global_settings);
|
||||||
let node = spec.relaychain.nodes.first_mut().unwrap();
|
let node = spec.relaychain.nodes.first_mut().unwrap();
|
||||||
node.args
|
node.args.push("--bootnodes {{ZOMBIE:bob:multiAddress')}}".into());
|
||||||
.push("--bootnodes {{ZOMBIE:bob:multiAddress')}}".into());
|
|
||||||
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
||||||
assert_eq!(concurrency, 1);
|
assert_eq!(concurrency, 1);
|
||||||
assert!(limited);
|
assert!(limited);
|
||||||
@@ -1271,8 +1189,7 @@ mod tests {
|
|||||||
let network_config = generate(false, Some("cargo")).unwrap();
|
let network_config = generate(false, Some("cargo")).unwrap();
|
||||||
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
let mut spec = NetworkSpec::from_config(&network_config).await.unwrap();
|
||||||
let node = spec.relaychain.nodes.first_mut().unwrap();
|
let node = spec.relaychain.nodes.first_mut().unwrap();
|
||||||
node.args
|
node.args.push("--bootnodes {{ZOMBIE:bob:multiAddress')}}".into());
|
||||||
.push("--bootnodes {{ZOMBIE:bob:multiAddress')}}".into());
|
|
||||||
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
let (concurrency, limited) = calculate_concurrency(&spec).unwrap();
|
||||||
assert_eq!(concurrency, 1);
|
assert_eq!(concurrency, 1);
|
||||||
assert!(limited);
|
assert!(limited);
|
||||||
|
|||||||
+26
-74
@@ -167,11 +167,8 @@ impl<T: FileSystem> Network<T> {
|
|||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
node_spec.available_args_output = Some(
|
node_spec.available_args_output =
|
||||||
self.initial_spec
|
Some(self.initial_spec.node_available_args_output(&node_spec, self.ns.clone()).await?);
|
||||||
.node_available_args_output(&node_spec, self.ns.clone())
|
|
||||||
.await?,
|
|
||||||
);
|
|
||||||
|
|
||||||
let base_dir = self.ns.base_dir().to_string_lossy();
|
let base_dir = self.ns.base_dir().to_string_lossy();
|
||||||
let scoped_fs = ScopedFilesystem::new(&self.filesystem, &base_dir);
|
let scoped_fs = ScopedFilesystem::new(&self.filesystem, &base_dir);
|
||||||
@@ -208,8 +205,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Let's make sure node is up before adding
|
// Let's make sure node is up before adding
|
||||||
node.wait_until_is_up(self.initial_spec.global_settings.network_spawn_timeout())
|
node.wait_until_is_up(self.initial_spec.global_settings.network_spawn_timeout()).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Add node to relaychain data
|
// Add node to relaychain data
|
||||||
self.add_running_node(node.clone(), None).await;
|
self.add_running_node(node.clone(), None).await;
|
||||||
@@ -259,11 +255,8 @@ impl<T: FileSystem> Network<T> {
|
|||||||
.iter()
|
.iter()
|
||||||
.find(|para| para.id == para_id)
|
.find(|para| para.id == para_id)
|
||||||
.ok_or(anyhow::anyhow!(format!("parachain: {para_id} not found!")))?;
|
.ok_or(anyhow::anyhow!(format!("parachain: {para_id} not found!")))?;
|
||||||
let role = if spec.is_cumulus_based {
|
let role =
|
||||||
ZombieRole::CumulusCollator
|
if spec.is_cumulus_based { ZombieRole::CumulusCollator } else { ZombieRole::Collator };
|
||||||
} else {
|
|
||||||
ZombieRole::Collator
|
|
||||||
};
|
|
||||||
let chain_context = ChainDefaultContext {
|
let chain_context = ChainDefaultContext {
|
||||||
default_command: spec.default_command.as_ref(),
|
default_command: spec.default_command.as_ref(),
|
||||||
default_image: spec.default_image.as_ref(),
|
default_image: spec.default_image.as_ref(),
|
||||||
@@ -339,17 +332,13 @@ impl<T: FileSystem> Network<T> {
|
|||||||
spec.is_evm_based,
|
spec.is_evm_based,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
node_spec.available_args_output = Some(
|
node_spec.available_args_output =
|
||||||
self.initial_spec
|
Some(self.initial_spec.node_available_args_output(&node_spec, self.ns.clone()).await?);
|
||||||
.node_available_args_output(&node_spec, self.ns.clone())
|
|
||||||
.await?,
|
|
||||||
);
|
|
||||||
|
|
||||||
let node = spawner::spawn_node(&node_spec, global_files_to_inject, &ctx).await?;
|
let node = spawner::spawn_node(&node_spec, global_files_to_inject, &ctx).await?;
|
||||||
|
|
||||||
// Let's make sure node is up before adding
|
// Let's make sure node is up before adding
|
||||||
node.wait_until_is_up(self.initial_spec.global_settings.network_spawn_timeout())
|
node.wait_until_is_up(self.initial_spec.global_settings.network_spawn_timeout()).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
parachain.collators.push(node.clone());
|
parachain.collators.push(node.clone());
|
||||||
self.add_running_node(node, None).await;
|
self.add_running_node(node, None).await;
|
||||||
@@ -366,12 +355,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
.nodes_iter()
|
.nodes_iter()
|
||||||
.map(|node| node.spec())
|
.map(|node| node.spec())
|
||||||
.flat_map(|spec| {
|
.flat_map(|spec| {
|
||||||
[
|
[spec.ws_port.0, spec.rpc_port.0, spec.prometheus_port.0, spec.p2p_port.0]
|
||||||
spec.ws_port.0,
|
|
||||||
spec.rpc_port.0,
|
|
||||||
spec.prometheus_port.0,
|
|
||||||
spec.p2p_port.0,
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@@ -384,11 +368,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
.map(|(id, paras)| (*id, paras.len().saturating_sub(1) as u8))
|
.map(|(id, paras)| (*id, paras.len().saturating_sub(1) as u8))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let context = ValidationContext {
|
let context = ValidationContext { used_ports, used_nodes_names, used_para_ids };
|
||||||
used_ports,
|
|
||||||
used_nodes_names,
|
|
||||||
used_para_ids,
|
|
||||||
};
|
|
||||||
let context = Rc::new(RefCell::new(context));
|
let context = Rc::new(RefCell::new(context));
|
||||||
|
|
||||||
ParachainConfigBuilder::new_with_running(context)
|
ParachainConfigBuilder::new_with_running(context)
|
||||||
@@ -464,9 +444,8 @@ impl<T: FileSystem> Network<T> {
|
|||||||
relay_chain_id.as_str().try_into()?,
|
relay_chain_id.as_str().try_into()?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let chain_spec_raw_path = para_spec
|
let chain_spec_raw_path =
|
||||||
.build_chain_spec(&relay_chain_id, &self.ns, &scoped_fs)
|
para_spec.build_chain_spec(&relay_chain_id, &self.ns, &scoped_fs).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Para artifacts
|
// Para artifacts
|
||||||
let para_path_prefix = if let Some(custom_prefix) = custom_parchain_fs_prefix {
|
let para_path_prefix = if let Some(custom_prefix) = custom_parchain_fs_prefix {
|
||||||
@@ -530,9 +509,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
.relaychain()
|
.relaychain()
|
||||||
.nodes
|
.nodes
|
||||||
.first()
|
.first()
|
||||||
.ok_or(anyhow::anyhow!(
|
.ok_or(anyhow::anyhow!("At least one node of the relaychain should be running"))?
|
||||||
"At least one node of the relaychain should be running"
|
|
||||||
))?
|
|
||||||
.ws_uri();
|
.ws_uri();
|
||||||
|
|
||||||
if para_config.registration_strategy() == Some(&RegistrationStrategy::UsingExtrinsic) {
|
if para_config.registration_strategy() == Some(&RegistrationStrategy::UsingExtrinsic) {
|
||||||
@@ -542,16 +519,12 @@ impl<T: FileSystem> Network<T> {
|
|||||||
wasm_path: para_spec
|
wasm_path: para_spec
|
||||||
.genesis_wasm
|
.genesis_wasm
|
||||||
.artifact_path()
|
.artifact_path()
|
||||||
.ok_or(anyhow::anyhow!(
|
.ok_or(anyhow::anyhow!("artifact path for wasm must be set at this point",))?
|
||||||
"artifact path for wasm must be set at this point",
|
|
||||||
))?
|
|
||||||
.to_path_buf(),
|
.to_path_buf(),
|
||||||
state_path: para_spec
|
state_path: para_spec
|
||||||
.genesis_state
|
.genesis_state
|
||||||
.artifact_path()
|
.artifact_path()
|
||||||
.ok_or(anyhow::anyhow!(
|
.ok_or(anyhow::anyhow!("artifact path for state must be set at this point",))?
|
||||||
"artifact path for state must be set at this point",
|
|
||||||
))?
|
|
||||||
.to_path_buf(),
|
.to_path_buf(),
|
||||||
node_ws_url: first_node_url.to_string(),
|
node_ws_url: first_node_url.to_string(),
|
||||||
onboard_as_para: para_spec.onboard_as_parachain,
|
onboard_as_para: para_spec.onboard_as_parachain,
|
||||||
@@ -630,17 +603,13 @@ impl<T: FileSystem> Network<T> {
|
|||||||
.parachains
|
.parachains
|
||||||
.iter()
|
.iter()
|
||||||
.find(|p| p.id == para_id)
|
.find(|p| p.id == para_id)
|
||||||
.ok_or(anyhow::anyhow!(
|
.ok_or(anyhow::anyhow!("no parachain with id = {para_id} available",))?;
|
||||||
"no parachain with id = {para_id} available",
|
|
||||||
))?;
|
|
||||||
let para_genesis_config = para.get_genesis_config()?;
|
let para_genesis_config = para.get_genesis_config()?;
|
||||||
let first_node_url = self
|
let first_node_url = self
|
||||||
.relaychain()
|
.relaychain()
|
||||||
.nodes
|
.nodes
|
||||||
.first()
|
.first()
|
||||||
.ok_or(anyhow::anyhow!(
|
.ok_or(anyhow::anyhow!("At least one node of the relaychain should be running"))?
|
||||||
"At least one node of the relaychain should be running"
|
|
||||||
))?
|
|
||||||
.ws_uri();
|
.ws_uri();
|
||||||
let register_para_options: RegisterParachainOptions = RegisterParachainOptions {
|
let register_para_options: RegisterParachainOptions = RegisterParachainOptions {
|
||||||
id: para_id,
|
id: para_id,
|
||||||
@@ -668,16 +637,9 @@ impl<T: FileSystem> Network<T> {
|
|||||||
return Ok(node);
|
return Ok(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
let list = self
|
let list = self.nodes_iter().map(|n| &n.name).cloned().collect::<Vec<_>>().join(", ");
|
||||||
.nodes_iter()
|
|
||||||
.map(|n| &n.name)
|
|
||||||
.cloned()
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
Err(anyhow::anyhow!(
|
Err(anyhow::anyhow!("can't find node with name: {name:?}, should be one of {list}"))
|
||||||
"can't find node with name: {name:?}, should be one of {list}"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_node_mut(
|
pub fn get_node_mut(
|
||||||
@@ -746,10 +708,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// * `unique_id` - unique id of the parachain
|
/// * `unique_id` - unique id of the parachain
|
||||||
pub fn parachain_by_unique_id(&self, unique_id: impl AsRef<str>) -> Option<&Parachain> {
|
pub fn parachain_by_unique_id(&self, unique_id: impl AsRef<str>) -> Option<&Parachain> {
|
||||||
self.parachains
|
self.parachains.values().flat_map(|p| p.iter()).find(|p| p.unique_id == unique_id.as_ref())
|
||||||
.values()
|
|
||||||
.flat_map(|p| p.iter())
|
|
||||||
.find(|p| p.unique_id == unique_id.as_ref())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parachains(&self) -> Vec<&Parachain> {
|
pub fn parachains(&self) -> Vec<&Parachain> {
|
||||||
@@ -757,20 +716,15 @@ impl<T: FileSystem> Network<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn nodes_iter(&self) -> impl Iterator<Item = &NetworkNode> {
|
pub(crate) fn nodes_iter(&self) -> impl Iterator<Item = &NetworkNode> {
|
||||||
self.relay.nodes.iter().chain(
|
self.relay
|
||||||
self.parachains
|
.nodes
|
||||||
.values()
|
.iter()
|
||||||
.flat_map(|p| p.iter())
|
.chain(self.parachains.values().flat_map(|p| p.iter()).flat_map(|p| &p.collators))
|
||||||
.flat_map(|p| &p.collators),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn nodes_iter_mut(&mut self) -> impl Iterator<Item = &mut NetworkNode> {
|
pub(crate) fn nodes_iter_mut(&mut self) -> impl Iterator<Item = &mut NetworkNode> {
|
||||||
self.relay.nodes.iter_mut().chain(
|
self.relay.nodes.iter_mut().chain(
|
||||||
self.parachains
|
self.parachains.values_mut().flat_map(|p| p.iter_mut()).flat_map(|p| &mut p.collators),
|
||||||
.values_mut()
|
|
||||||
.flat_map(|p| p.iter_mut())
|
|
||||||
.flat_map(|p| &mut p.collators),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,9 +738,7 @@ impl<T: FileSystem> Network<T> {
|
|||||||
/// * `Ok()` if the node is up before timeout occured.
|
/// * `Ok()` if the node is up before timeout occured.
|
||||||
/// * `Err(e)` if timeout or other error occurred while waiting.
|
/// * `Err(e)` if timeout or other error occurred while waiting.
|
||||||
pub async fn wait_until_is_up(&self, timeout_secs: u64) -> Result<(), anyhow::Error> {
|
pub async fn wait_until_is_up(&self, timeout_secs: u64) -> Result<(), anyhow::Error> {
|
||||||
let handles = self
|
let handles = self.nodes_iter().map(|node| node.wait_until_is_up(timeout_secs));
|
||||||
.nodes_iter()
|
|
||||||
.map(|node| node.wait_until_is_up(timeout_secs));
|
|
||||||
|
|
||||||
futures::future::try_join_all(handles).await?;
|
futures::future::try_join_all(handles).await?;
|
||||||
|
|
||||||
|
|||||||
@@ -104,11 +104,7 @@ impl LogLineCountOptions {
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
wait_until_timeout_elapses: bool,
|
wait_until_timeout_elapses: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self { predicate: Arc::new(predicate), timeout, wait_until_timeout_elapses }
|
||||||
predicate: Arc::new(predicate),
|
|
||||||
timeout,
|
|
||||||
wait_until_timeout_elapses,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn no_occurences_within_timeout(timeout: Duration) -> Self {
|
pub fn no_occurences_within_timeout(timeout: Duration) -> Self {
|
||||||
@@ -220,9 +216,7 @@ impl NetworkNode {
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| anyhow!("Error awaiting http_client to ws be ready, err: {e}"))?;
|
.map_err(|e| anyhow!("Error awaiting http_client to ws be ready, err: {e}"))?;
|
||||||
|
|
||||||
self.try_client()
|
self.try_client().await.map_err(|e| anyhow!("Can't create a subxt client, err: {e}"))
|
||||||
.await
|
|
||||||
.map_err(|e| anyhow!("Can't create a subxt client, err: {e}"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait until get the [online client](subxt::client::OnlineClient) for the node with a defined timeout
|
/// Wait until get the [online client](subxt::client::OnlineClient) for the node with a defined timeout
|
||||||
@@ -231,10 +225,7 @@ impl NetworkNode {
|
|||||||
timeout_secs: impl Into<u64>,
|
timeout_secs: impl Into<u64>,
|
||||||
) -> Result<OnlineClient<Config>, anyhow::Error> {
|
) -> Result<OnlineClient<Config>, anyhow::Error> {
|
||||||
debug!("waiting until subxt client is ready");
|
debug!("waiting until subxt client is ready");
|
||||||
tokio::time::timeout(
|
tokio::time::timeout(Duration::from_secs(timeout_secs.into()), self.wait_client::<Config>())
|
||||||
Duration::from_secs(timeout_secs.into()),
|
|
||||||
self.wait_client::<Config>(),
|
|
||||||
)
|
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,9 +377,7 @@ impl NetworkNode {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// timeout
|
// timeout
|
||||||
Err(anyhow!(
|
Err(anyhow!("Timeout ({secs}), waiting for metric {metric_name} pass the predicate"))
|
||||||
"Timeout ({secs}), waiting for metric {metric_name} pass the predicate"
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,10 +474,7 @@ impl NetworkNode {
|
|||||||
options: LogLineCountOptions,
|
options: LogLineCountOptions,
|
||||||
) -> Result<LogLineCount, anyhow::Error> {
|
) -> Result<LogLineCount, anyhow::Error> {
|
||||||
let substring = substring.into();
|
let substring = substring.into();
|
||||||
debug!(
|
debug!("waiting until match lines count within {} seconds", options.timeout.as_secs_f64());
|
||||||
"waiting until match lines count within {} seconds",
|
|
||||||
options.timeout.as_secs_f64()
|
|
||||||
);
|
|
||||||
|
|
||||||
let start = tokio::time::Instant::now();
|
let start = tokio::time::Instant::now();
|
||||||
|
|
||||||
@@ -626,16 +612,11 @@ mod tests {
|
|||||||
|
|
||||||
impl MockNode {
|
impl MockNode {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self { logs: Arc::new(Mutex::new(vec![])) }
|
||||||
logs: Arc::new(Mutex::new(vec![])),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn logs_push(&self, lines: Vec<impl Into<String>>) {
|
fn logs_push(&self, lines: Vec<impl Into<String>>) {
|
||||||
self.logs
|
self.logs.lock().unwrap().extend(lines.into_iter().map(|l| l.into()));
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.extend(lines.into_iter().map(|l| l.into()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,9 +744,8 @@ mod tests {
|
|||||||
wait_until_timeout_elapses: false,
|
wait_until_timeout_elapses: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let log_line_count = mock_node
|
let log_line_count =
|
||||||
.wait_log_line_count_with_timeout("system ready", false, options)
|
mock_node.wait_log_line_count_with_timeout("system ready", false, options).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
assert!(matches!(log_line_count, LogLineCount::TargetReached(1)));
|
assert!(matches!(log_line_count, LogLineCount::TargetReached(1)));
|
||||||
|
|
||||||
@@ -844,9 +824,8 @@ mod tests {
|
|||||||
wait_until_timeout_elapses: false,
|
wait_until_timeout_elapses: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
let log_line_count = mock_node
|
let log_line_count =
|
||||||
.wait_log_line_count_with_timeout("system ready", false, options)
|
mock_node.wait_log_line_count_with_timeout("system ready", false, options).await?;
|
||||||
.await?;
|
|
||||||
|
|
||||||
assert!(matches!(log_line_count, LogLineCount::TargetFailed(1)));
|
assert!(matches!(log_line_count, LogLineCount::TargetFailed(1)));
|
||||||
|
|
||||||
|
|||||||
+2
-11
@@ -31,11 +31,7 @@ impl ChainUpgrade for Relaychain {
|
|||||||
async fn runtime_upgrade(&self, options: RuntimeUpgradeOptions) -> Result<(), anyhow::Error> {
|
async fn runtime_upgrade(&self, options: RuntimeUpgradeOptions) -> Result<(), anyhow::Error> {
|
||||||
// check if the node is valid first
|
// check if the node is valid first
|
||||||
let node = if let Some(node_name) = &options.node_name {
|
let node = if let Some(node_name) = &options.node_name {
|
||||||
if let Some(node) = self
|
if let Some(node) = self.nodes().into_iter().find(|node| node.name() == node_name) {
|
||||||
.nodes()
|
|
||||||
.into_iter()
|
|
||||||
.find(|node| node.name() == node_name)
|
|
||||||
{
|
|
||||||
node
|
node
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Node: {node_name} is not part of the set of nodes"));
|
return Err(anyhow!("Node: {node_name} is not part of the set of nodes"));
|
||||||
@@ -55,12 +51,7 @@ impl ChainUpgrade for Relaychain {
|
|||||||
|
|
||||||
impl Relaychain {
|
impl Relaychain {
|
||||||
pub(crate) fn new(chain: String, chain_id: String, chain_spec_path: PathBuf) -> Self {
|
pub(crate) fn new(chain: String, chain_id: String, chain_spec_path: PathBuf) -> Self {
|
||||||
Self {
|
Self { chain, chain_id, chain_spec_path, nodes: Default::default() }
|
||||||
chain,
|
|
||||||
chain_id,
|
|
||||||
chain_spec_path,
|
|
||||||
nodes: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
|
|||||||
+14
-49
@@ -48,11 +48,7 @@ impl ChainUpgrade for Parachain {
|
|||||||
async fn runtime_upgrade(&self, options: RuntimeUpgradeOptions) -> Result<(), anyhow::Error> {
|
async fn runtime_upgrade(&self, options: RuntimeUpgradeOptions) -> Result<(), anyhow::Error> {
|
||||||
// check if the node is valid first
|
// check if the node is valid first
|
||||||
let node = if let Some(node_name) = &options.node_name {
|
let node = if let Some(node_name) = &options.node_name {
|
||||||
if let Some(node) = self
|
if let Some(node) = self.collators().into_iter().find(|node| node.name() == node_name) {
|
||||||
.collators()
|
|
||||||
.into_iter()
|
|
||||||
.find(|node| node.name() == node_name)
|
|
||||||
{
|
|
||||||
node
|
node
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow!("Node: {node_name} is not part of the set of nodes"));
|
return Err(anyhow!("Node: {node_name} is not part of the set of nodes"));
|
||||||
@@ -159,23 +155,14 @@ impl Parachain {
|
|||||||
let genesis_state = scoped_fs
|
let genesis_state = scoped_fs
|
||||||
.read_to_string(options.state_path)
|
.read_to_string(options.state_path)
|
||||||
.await
|
.await
|
||||||
.expect(&format!(
|
.expect(&format!("State Path should be ok by this point {THIS_IS_A_BUG}"));
|
||||||
"State Path should be ok by this point {THIS_IS_A_BUG}"
|
|
||||||
));
|
|
||||||
let wasm_data = scoped_fs
|
let wasm_data = scoped_fs
|
||||||
.read_to_string(options.wasm_path)
|
.read_to_string(options.wasm_path)
|
||||||
.await
|
.await
|
||||||
.expect(&format!(
|
.expect(&format!("Wasm Path should be ok by this point {THIS_IS_A_BUG}"));
|
||||||
"Wasm Path should be ok by this point {THIS_IS_A_BUG}"
|
|
||||||
));
|
|
||||||
|
|
||||||
wait_ws_ready(options.node_ws_url.as_str())
|
wait_ws_ready(options.node_ws_url.as_str()).await.map_err(|_| {
|
||||||
.await
|
anyhow::anyhow!("Error waiting for ws to be ready, at {}", options.node_ws_url.as_str())
|
||||||
.map_err(|_| {
|
|
||||||
anyhow::anyhow!(
|
|
||||||
"Error waiting for ws to be ready, at {}",
|
|
||||||
options.node_ws_url.as_str()
|
|
||||||
)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let api: OnlineClient<BizinikiwConfig> = get_client_from_url(&options.node_ws_url).await?;
|
let api: OnlineClient<BizinikiwConfig> = get_client_from_url(&options.node_ws_url).await?;
|
||||||
@@ -186,14 +173,8 @@ impl Parachain {
|
|||||||
vec![
|
vec![
|
||||||
Value::primitive(options.id.into()),
|
Value::primitive(options.id.into()),
|
||||||
Value::named_composite([
|
Value::named_composite([
|
||||||
(
|
("genesis_head", Value::from_bytes(hex::decode(&genesis_state[2..])?)),
|
||||||
"genesis_head",
|
("validation_code", Value::from_bytes(hex::decode(&wasm_data[2..])?)),
|
||||||
Value::from_bytes(hex::decode(&genesis_state[2..])?),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"validation_code",
|
|
||||||
Value::from_bytes(hex::decode(&wasm_data[2..])?),
|
|
||||||
),
|
|
||||||
("para_kind", Value::bool(options.onboard_as_para)),
|
("para_kind", Value::bool(options.onboard_as_para)),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
@@ -204,10 +185,7 @@ impl Parachain {
|
|||||||
|
|
||||||
// TODO: uncomment below and fix the sign and submit (and follow afterwards until
|
// TODO: uncomment below and fix the sign and submit (and follow afterwards until
|
||||||
// finalized block) to register the parachain
|
// finalized block) to register the parachain
|
||||||
let mut tx = api
|
let mut tx = api.tx().sign_and_submit_then_watch_default(&sudo_call, &sudo).await?;
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, &sudo)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Below we use the low level API to replicate the `wait_for_in_block` behaviour
|
// Below we use the low level API to replicate the `wait_for_in_block` behaviour
|
||||||
// which was removed in subxt 0.33.0. See https://github.com/paritytech/subxt/pull/1237.
|
// which was removed in subxt 0.33.0. See https://github.com/paritytech/subxt/pull/1237.
|
||||||
@@ -274,10 +252,7 @@ mod tests {
|
|||||||
assert_eq!(para.unique_id, "100");
|
assert_eq!(para.unique_id, "100");
|
||||||
assert_eq!(para.chain_id, Some("rococo-local".to_string()));
|
assert_eq!(para.chain_id, Some("rococo-local".to_string()));
|
||||||
assert_eq!(para.chain, None);
|
assert_eq!(para.chain, None);
|
||||||
assert_eq!(
|
assert_eq!(para.chain_spec_path, Some(PathBuf::from("/tmp/rococo-local.json")));
|
||||||
para.chain_spec_path,
|
|
||||||
Some(PathBuf::from("/tmp/rococo-local.json"))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -300,18 +275,11 @@ mod tests {
|
|||||||
let para_spec =
|
let para_spec =
|
||||||
TeyrchainSpec::from_config(¶_config, "rococo-local".try_into().unwrap()).unwrap();
|
TeyrchainSpec::from_config(¶_config, "rococo-local".try_into().unwrap()).unwrap();
|
||||||
let fs = support::fs::in_memory::InMemoryFileSystem::new(HashMap::default());
|
let fs = support::fs::in_memory::InMemoryFileSystem::new(HashMap::default());
|
||||||
let scoped_fs = ScopedFilesystem {
|
let scoped_fs = ScopedFilesystem { fs: &fs, base_dir: "/tmp/some" };
|
||||||
fs: &fs,
|
|
||||||
base_dir: "/tmp/some",
|
|
||||||
};
|
|
||||||
|
|
||||||
let files = vec![TransferedFile::new(
|
let files =
|
||||||
PathBuf::from("/tmp/some"),
|
vec![TransferedFile::new(PathBuf::from("/tmp/some"), PathBuf::from("/tmp/some"))];
|
||||||
PathBuf::from("/tmp/some"),
|
let para = Parachain::from_spec(¶_spec, &files, &scoped_fs).await.unwrap();
|
||||||
)];
|
|
||||||
let para = Parachain::from_spec(¶_spec, &files, &scoped_fs)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
println!("{para:#?}");
|
println!("{para:#?}");
|
||||||
assert_eq!(para.para_id, 100);
|
assert_eq!(para.para_id, 100);
|
||||||
assert_eq!(para.unique_id, "100");
|
assert_eq!(para.unique_id, "100");
|
||||||
@@ -320,10 +288,7 @@ mod tests {
|
|||||||
// one file should be added.
|
// one file should be added.
|
||||||
assert_eq!(para.files_to_inject.len(), 1);
|
assert_eq!(para.files_to_inject.len(), 1);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
para.bootnodes_addresses()
|
para.bootnodes_addresses().iter().map(|addr| addr.to_string()).collect::<Vec<_>>(),
|
||||||
.iter()
|
|
||||||
.map(|addr| addr.to_string())
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
bootnode_addresses
|
bootnode_addresses
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-3
@@ -18,9 +18,7 @@ pub struct Metrics {
|
|||||||
|
|
||||||
impl Metrics {
|
impl Metrics {
|
||||||
fn new(endpoint: impl Into<Url>) -> Self {
|
fn new(endpoint: impl Into<Url>) -> Self {
|
||||||
Self {
|
Self { endpoint: endpoint.into() }
|
||||||
endpoint: endpoint.into(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_metrics(
|
async fn fetch_metrics(
|
||||||
|
|||||||
@@ -53,19 +53,12 @@ impl NetworkSpec {
|
|||||||
Ok(NetworkSpec {
|
Ok(NetworkSpec {
|
||||||
relaychain,
|
relaychain,
|
||||||
parachains,
|
parachains,
|
||||||
hrmp_channels: network_config
|
hrmp_channels: network_config.hrmp_channels().into_iter().cloned().collect(),
|
||||||
.hrmp_channels()
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
global_settings: network_config.global_settings().clone(),
|
global_settings: network_config.global_settings().clone(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let errs_str = errs
|
let errs_str =
|
||||||
.into_iter()
|
errs.into_iter().map(|e| e.to_string()).collect::<Vec<String>>().join("\n");
|
||||||
.map(|e| e.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n");
|
|
||||||
Err(OrchestratorError::InvalidConfig(errs_str))
|
Err(OrchestratorError::InvalidConfig(errs_str))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,24 +100,18 @@ impl NetworkSpec {
|
|||||||
let node = if let Some(node) = node {
|
let node = if let Some(node) = node {
|
||||||
Some(node)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
let node = self
|
let node = self.parachains.iter().find_map(|para| para.collators.iter().find(cmp_fn));
|
||||||
.parachains
|
|
||||||
.iter()
|
|
||||||
.find_map(|para| para.collators.iter().find(cmp_fn));
|
|
||||||
|
|
||||||
node
|
node
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = if let Some(node) = node {
|
let output = if let Some(node) = node {
|
||||||
node.available_args_output.clone().expect(&format!(
|
node.available_args_output
|
||||||
"args_output should be set for running nodes {THIS_IS_A_BUG}"
|
.clone()
|
||||||
))
|
.expect(&format!("args_output should be set for running nodes {THIS_IS_A_BUG}"))
|
||||||
} else {
|
} else {
|
||||||
// we need to compute the args output
|
// we need to compute the args output
|
||||||
let image = node_spec
|
let image = node_spec.image.as_ref().map(|image| image.as_str().to_string());
|
||||||
.image
|
|
||||||
.as_ref()
|
|
||||||
.map(|image| image.as_str().to_string());
|
|
||||||
let command = node_spec.command.as_str().to_string();
|
let command = node_spec.command.as_str().to_string();
|
||||||
|
|
||||||
ns.get_node_available_args((command, image)).await?
|
ns.get_node_available_args((command, image)).await?
|
||||||
@@ -201,10 +188,7 @@ impl NetworkSpec {
|
|||||||
fn collect_network_nodes(&mut self) -> Vec<&mut NodeSpec> {
|
fn collect_network_nodes(&mut self) -> Vec<&mut NodeSpec> {
|
||||||
vec![
|
vec![
|
||||||
self.relaychain.nodes.iter_mut().collect::<Vec<_>>(),
|
self.relaychain.nodes.iter_mut().collect::<Vec<_>>(),
|
||||||
self.parachains
|
self.parachains.iter_mut().flat_map(|para| para.collators.iter_mut()).collect(),
|
||||||
.iter_mut()
|
|
||||||
.flat_map(|para| para.collators.iter_mut())
|
|
||||||
.collect(),
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
@@ -223,10 +207,7 @@ impl NetworkSpec {
|
|||||||
.image
|
.image
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|image| {
|
.map(|image| {
|
||||||
(
|
(Some(image.as_str().to_string()), node.command.as_str().to_string())
|
||||||
Some(image.as_str().to_string()),
|
|
||||||
node.command.as_str().to_string(),
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| (None, node.command.as_str().to_string()));
|
.unwrap_or_else(|| (None, node.command.as_str().to_string()));
|
||||||
|
|
||||||
@@ -255,9 +236,8 @@ impl NetworkSpec {
|
|||||||
let command = command.clone();
|
let command = command.clone();
|
||||||
async move {
|
async move {
|
||||||
// get node available args output from image/command
|
// get node available args output from image/command
|
||||||
let available_args = ns
|
let available_args =
|
||||||
.get_node_available_args((command.clone(), image.clone()))
|
ns.get_node_available_args((command.clone(), image.clone())).await?;
|
||||||
.await?;
|
|
||||||
debug!(
|
debug!(
|
||||||
"retrieved available args for image: {:?}, command: {}",
|
"retrieved available args for image: {:?}, command: {}",
|
||||||
image, command
|
image, command
|
||||||
@@ -279,9 +259,7 @@ impl NetworkSpec {
|
|||||||
for (image, command, available_args_output) in available_args_outputs {
|
for (image, command, available_args_output) in available_args_outputs {
|
||||||
let nodes = image_command_to_nodes_mapping
|
let nodes = image_command_to_nodes_mapping
|
||||||
.get_mut(&(image, command))
|
.get_mut(&(image, command))
|
||||||
.expect(&format!(
|
.expect(&format!("node image/command key should exist {THIS_IS_A_BUG}"));
|
||||||
"node image/command key should exist {THIS_IS_A_BUG}"
|
|
||||||
));
|
|
||||||
|
|
||||||
for node in nodes {
|
for node in nodes {
|
||||||
node.available_args_output = Some(available_args_output.clone());
|
node.available_args_output = Some(available_args_output.clone());
|
||||||
|
|||||||
@@ -162,11 +162,7 @@ impl NodeSpec {
|
|||||||
// If `args` is set at `node` level use them
|
// If `args` is set at `node` level use them
|
||||||
// otherwise use the default_args (can be empty).
|
// otherwise use the default_args (can be empty).
|
||||||
let args: Vec<Arg> = if node_config.args().is_empty() {
|
let args: Vec<Arg> = if node_config.args().is_empty() {
|
||||||
chain_context
|
chain_context.default_args.iter().map(|x| x.to_owned().clone()).collect()
|
||||||
.default_args
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.to_owned().clone())
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
node_config.args().into_iter().cloned().collect()
|
node_config.args().into_iter().cloned().collect()
|
||||||
};
|
};
|
||||||
@@ -180,9 +176,7 @@ impl NodeSpec {
|
|||||||
|
|
||||||
if evm_based {
|
if evm_based {
|
||||||
if let Some(session_key) = node_config.override_eth_key() {
|
if let Some(session_key) = node_config.override_eth_key() {
|
||||||
accounts
|
accounts.accounts.insert("eth".into(), NodeAccount::new(session_key, session_key));
|
||||||
.accounts
|
|
||||||
.insert("eth".into(), NodeAccount::new(session_key, session_key));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,11 +209,7 @@ impl NodeSpec {
|
|||||||
is_bootnode: node_config.is_bootnode(),
|
is_bootnode: node_config.is_bootnode(),
|
||||||
initial_balance: node_config.initial_balance(),
|
initial_balance: node_config.initial_balance(),
|
||||||
env: node_config.env().into_iter().cloned().collect(),
|
env: node_config.env().into_iter().cloned().collect(),
|
||||||
bootnodes_addresses: node_config
|
bootnodes_addresses: node_config.bootnodes_addresses().into_iter().cloned().collect(),
|
||||||
.bootnodes_addresses()
|
|
||||||
.into_iter()
|
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
resources: node_config.resources().cloned(),
|
resources: node_config.resources().cloned(),
|
||||||
p2p_cert_hash: node_config.p2p_cert_hash().map(str::to_string),
|
p2p_cert_hash: node_config.p2p_cert_hash().map(str::to_string),
|
||||||
db_snapshot: db_snapshot.cloned(),
|
db_snapshot: db_snapshot.cloned(),
|
||||||
@@ -261,10 +251,7 @@ impl NodeSpec {
|
|||||||
} else if let Some(cmd) = chain_context.default_command {
|
} else if let Some(cmd) = chain_context.default_command {
|
||||||
cmd.clone()
|
cmd.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(OrchestratorError::InvalidNodeConfig(
|
return Err(OrchestratorError::InvalidNodeConfig(name, "command".to_string()));
|
||||||
name,
|
|
||||||
"command".to_string(),
|
|
||||||
));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let subcommand = options.subcommand.clone();
|
let subcommand = options.subcommand.clone();
|
||||||
@@ -272,11 +259,7 @@ impl NodeSpec {
|
|||||||
// If `args` is set at `node` level use them
|
// If `args` is set at `node` level use them
|
||||||
// otherwise use the default_args (can be empty).
|
// otherwise use the default_args (can be empty).
|
||||||
let args: Vec<Arg> = if options.args.is_empty() {
|
let args: Vec<Arg> = if options.args.is_empty() {
|
||||||
chain_context
|
chain_context.default_args.iter().map(|x| x.to_owned().clone()).collect()
|
||||||
.default_args
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.to_owned().clone())
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
options.args
|
options.args
|
||||||
};
|
};
|
||||||
@@ -284,18 +267,13 @@ impl NodeSpec {
|
|||||||
let (key, peer_id) = generators::generate_node_identity(&name)?;
|
let (key, peer_id) = generators::generate_node_identity(&name)?;
|
||||||
|
|
||||||
let mut name_capitalized = name.clone();
|
let mut name_capitalized = name.clone();
|
||||||
let seed = format!(
|
let seed = format!("//{}{name_capitalized}", name_capitalized.remove(0).to_uppercase());
|
||||||
"//{}{name_capitalized}",
|
|
||||||
name_capitalized.remove(0).to_uppercase()
|
|
||||||
);
|
|
||||||
let accounts = generators::generate_node_keys(&seed)?;
|
let accounts = generators::generate_node_keys(&seed)?;
|
||||||
let mut accounts = NodeAccounts { seed, accounts };
|
let mut accounts = NodeAccounts { seed, accounts };
|
||||||
|
|
||||||
if evm_based {
|
if evm_based {
|
||||||
if let Some(session_key) = options.override_eth_key.as_ref() {
|
if let Some(session_key) = options.override_eth_key.as_ref() {
|
||||||
accounts
|
accounts.accounts.insert("eth".into(), NodeAccount::new(session_key, session_key));
|
||||||
.accounts
|
|
||||||
.insert("eth".into(), NodeAccount::new(session_key, session_key));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,9 +322,7 @@ impl NodeSpec {
|
|||||||
pub(crate) fn supports_arg(&self, arg: impl AsRef<str>) -> bool {
|
pub(crate) fn supports_arg(&self, arg: impl AsRef<str>) -> bool {
|
||||||
self.available_args_output
|
self.available_args_output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect(&format!(
|
.expect(&format!("available args should be present at this point {THIS_IS_A_BUG}"))
|
||||||
"available args should be present at this point {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.contains(arg.as_ref())
|
.contains(arg.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-37
@@ -121,20 +121,14 @@ impl TeyrchainSpec {
|
|||||||
|
|
||||||
let chain_spec = if config.is_cumulus_based() {
|
let chain_spec = if config.is_cumulus_based() {
|
||||||
// we need a chain-spec
|
// we need a chain-spec
|
||||||
let chain_name = if let Some(chain_name) = config.chain() {
|
let chain_name =
|
||||||
chain_name.as_str()
|
if let Some(chain_name) = config.chain() { chain_name.as_str() } else { "" };
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
|
|
||||||
let chain_spec_builder = if chain_name.is_empty() {
|
let chain_spec_builder = if chain_name.is_empty() {
|
||||||
// if the chain don't have name use the unique_id for the name of the file
|
// if the chain don't have name use the unique_id for the name of the file
|
||||||
ChainSpec::new(
|
ChainSpec::new(
|
||||||
config.unique_id().to_string(),
|
config.unique_id().to_string(),
|
||||||
Context::Para {
|
Context::Para { relay_chain, para_id: config.id() },
|
||||||
relay_chain,
|
|
||||||
para_id: config.id(),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let chain_spec_file_name = if config.unique_id().contains('-') {
|
let chain_spec_file_name = if config.unique_id().contains('-') {
|
||||||
@@ -144,10 +138,7 @@ impl TeyrchainSpec {
|
|||||||
};
|
};
|
||||||
ChainSpec::new(
|
ChainSpec::new(
|
||||||
chain_spec_file_name,
|
chain_spec_file_name,
|
||||||
Context::Para {
|
Context::Para { relay_chain, para_id: config.id() },
|
||||||
relay_chain,
|
|
||||||
para_id: config.id(),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let chain_spec_builder = chain_spec_builder.set_chain_name(chain_name);
|
let chain_spec_builder = chain_spec_builder.set_chain_name(chain_name);
|
||||||
@@ -226,11 +217,8 @@ impl TeyrchainSpec {
|
|||||||
ParaArtifactBuildOption::Path(path.to_string()),
|
ParaArtifactBuildOption::Path(path.to_string()),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let cmd = if let Some(cmd) = config.genesis_state_generator() {
|
let cmd =
|
||||||
cmd.cmd()
|
if let Some(cmd) = config.genesis_state_generator() { cmd.cmd() } else { main_cmd };
|
||||||
} else {
|
|
||||||
main_cmd
|
|
||||||
};
|
|
||||||
ParaArtifact::new(
|
ParaArtifact::new(
|
||||||
ParaArtifactType::State,
|
ParaArtifactType::State,
|
||||||
ParaArtifactBuildOption::Command(cmd.as_str().into()),
|
ParaArtifactBuildOption::Command(cmd.as_str().into()),
|
||||||
@@ -249,10 +237,7 @@ impl TeyrchainSpec {
|
|||||||
} else {
|
} else {
|
||||||
main_cmd.as_str()
|
main_cmd.as_str()
|
||||||
};
|
};
|
||||||
ParaArtifact::new(
|
ParaArtifact::new(ParaArtifactType::Wasm, ParaArtifactBuildOption::Command(cmd.into()))
|
||||||
ParaArtifactType::Wasm,
|
|
||||||
ParaArtifactBuildOption::Command(cmd.into()),
|
|
||||||
)
|
|
||||||
.image(main_image.clone())
|
.image(main_image.clone())
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -344,13 +329,9 @@ impl TeyrchainSpec {
|
|||||||
chain_spec.build(ns, scoped_fs).await?;
|
chain_spec.build(ns, scoped_fs).await?;
|
||||||
debug!("parachain chain-spec built!");
|
debug!("parachain chain-spec built!");
|
||||||
|
|
||||||
chain_spec
|
chain_spec.customize_para(&cloned, relay_chain_id, scoped_fs).await?;
|
||||||
.customize_para(&cloned, relay_chain_id, scoped_fs)
|
|
||||||
.await?;
|
|
||||||
debug!("parachain chain-spec customized!");
|
debug!("parachain chain-spec customized!");
|
||||||
chain_spec
|
chain_spec.build_raw(ns, scoped_fs, Some(relay_chain_id.try_into()?)).await?;
|
||||||
.build_raw(ns, scoped_fs, Some(relay_chain_id.try_into()?))
|
|
||||||
.await?;
|
|
||||||
debug!("parachain chain-spec raw built!");
|
debug!("parachain chain-spec raw built!");
|
||||||
|
|
||||||
// override wasm if needed
|
// override wasm if needed
|
||||||
@@ -360,17 +341,12 @@ impl TeyrchainSpec {
|
|||||||
|
|
||||||
// override raw spec if needed
|
// override raw spec if needed
|
||||||
if let Some(ref raw_spec_override) = self.raw_spec_override {
|
if let Some(ref raw_spec_override) = self.raw_spec_override {
|
||||||
chain_spec
|
chain_spec.override_raw_spec(scoped_fs, raw_spec_override).await?;
|
||||||
.override_raw_spec(scoped_fs, raw_spec_override)
|
|
||||||
.await?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let chain_spec_raw_path =
|
let chain_spec_raw_path = chain_spec.raw_path().ok_or(
|
||||||
chain_spec
|
OrchestratorError::InvariantError("chain-spec raw path should be set now"),
|
||||||
.raw_path()
|
)?;
|
||||||
.ok_or(OrchestratorError::InvariantError(
|
|
||||||
"chain-spec raw path should be set now",
|
|
||||||
))?;
|
|
||||||
|
|
||||||
Some(chain_spec_raw_path.to_path_buf())
|
Some(chain_spec_raw_path.to_path_buf())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -21,10 +21,7 @@ pub struct NodeAccount {
|
|||||||
|
|
||||||
impl NodeAccount {
|
impl NodeAccount {
|
||||||
pub fn new(addr: impl Into<String>, pk: impl Into<String>) -> Self {
|
pub fn new(addr: impl Into<String>, pk: impl Into<String>) -> Self {
|
||||||
Self {
|
Self { address: addr.into(), public_key: pk.into() }
|
||||||
address: addr.into(),
|
|
||||||
public_key: pk.into(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,10 +32,7 @@ pub struct NodeAccounts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||||
pub struct ParkedPort(
|
pub struct ParkedPort(pub(crate) Port, #[serde(skip)] pub(crate) Arc<RwLock<Option<TcpListener>>>);
|
||||||
pub(crate) Port,
|
|
||||||
#[serde(skip)] pub(crate) Arc<RwLock<Option<TcpListener>>>,
|
|
||||||
);
|
|
||||||
|
|
||||||
impl ParkedPort {
|
impl ParkedPort {
|
||||||
pub(crate) fn new(port: u16, listener: TcpListener) -> ParkedPort {
|
pub(crate) fn new(port: u16, listener: TcpListener) -> ParkedPort {
|
||||||
@@ -84,11 +78,7 @@ pub struct RuntimeUpgradeOptions {
|
|||||||
|
|
||||||
impl RuntimeUpgradeOptions {
|
impl RuntimeUpgradeOptions {
|
||||||
pub fn new(wasm: AssetLocation) -> Self {
|
pub fn new(wasm: AssetLocation) -> Self {
|
||||||
Self {
|
Self { wasm, node_name: None, seed: None }
|
||||||
wasm,
|
|
||||||
node_name: None,
|
|
||||||
seed: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|||||||
+20
-50
@@ -63,15 +63,10 @@ where
|
|||||||
// (parachain_id) should be set then.
|
// (parachain_id) should be set then.
|
||||||
if node.is_validator && (ctx.parachain.is_none() || ctx.parachain_id.is_some()) {
|
if node.is_validator && (ctx.parachain.is_none() || ctx.parachain_id.is_some()) {
|
||||||
// Generate keystore for node
|
// Generate keystore for node
|
||||||
let node_files_path = if let Some(para) = ctx.parachain {
|
let node_files_path =
|
||||||
para.id.to_string()
|
if let Some(para) = ctx.parachain { para.id.to_string() } else { node.name.clone() };
|
||||||
} else {
|
let asset_hub_polkadot =
|
||||||
node.name.clone()
|
ctx.parachain_id.map(|id| id.starts_with("asset-hub-polkadot")).unwrap_or_default();
|
||||||
};
|
|
||||||
let asset_hub_polkadot = ctx
|
|
||||||
.parachain_id
|
|
||||||
.map(|id| id.starts_with("asset-hub-polkadot"))
|
|
||||||
.unwrap_or_default();
|
|
||||||
let keystore_key_types = node.keystore_key_types.iter().map(String::as_str).collect();
|
let keystore_key_types = node.keystore_key_types.iter().map(String::as_str).collect();
|
||||||
let key_filenames = generators::generate_node_keystore(
|
let key_filenames = generators::generate_node_keystore(
|
||||||
&node.accounts,
|
&node.accounts,
|
||||||
@@ -85,15 +80,13 @@ where
|
|||||||
|
|
||||||
// Paths returned are relative to the base dir, we need to convert into
|
// Paths returned are relative to the base dir, we need to convert into
|
||||||
// fullpaths to inject them in the nodes.
|
// fullpaths to inject them in the nodes.
|
||||||
let remote_keystore_chain_id = if let Some(id) = ctx.parachain_id {
|
let remote_keystore_chain_id =
|
||||||
id
|
if let Some(id) = ctx.parachain_id { id } else { ctx.chain_id };
|
||||||
} else {
|
|
||||||
ctx.chain_id
|
|
||||||
};
|
|
||||||
|
|
||||||
let keystore_path = node.keystore_path.clone().unwrap_or(PathBuf::from(format!(
|
let keystore_path = node
|
||||||
"/data/chains/{remote_keystore_chain_id}/keystore",
|
.keystore_path
|
||||||
)));
|
.clone()
|
||||||
|
.unwrap_or(PathBuf::from(format!("/data/chains/{remote_keystore_chain_id}/keystore",)));
|
||||||
|
|
||||||
for key_filename in key_filenames {
|
for key_filename in key_filenames {
|
||||||
let f = TransferedFile::new(
|
let f = TransferedFile::new(
|
||||||
@@ -113,11 +106,7 @@ where
|
|||||||
let base_dir = format!("{}/{}", ctx.ns.base_dir().to_string_lossy(), &node.name);
|
let base_dir = format!("{}/{}", ctx.ns.base_dir().to_string_lossy(), &node.name);
|
||||||
|
|
||||||
let (cfg_path, data_path, relay_data_path) = if !ctx.ns.capabilities().prefix_with_full_path {
|
let (cfg_path, data_path, relay_data_path) = if !ctx.ns.capabilities().prefix_with_full_path {
|
||||||
(
|
(NODE_CONFIG_DIR.into(), NODE_DATA_DIR.into(), NODE_RELAY_DATA_DIR.into())
|
||||||
NODE_CONFIG_DIR.into(),
|
|
||||||
NODE_DATA_DIR.into(),
|
|
||||||
NODE_RELAY_DATA_DIR.into(),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let cfg_path = format!("{}{NODE_CONFIG_DIR}", &base_dir);
|
let cfg_path = format!("{}{NODE_CONFIG_DIR}", &base_dir);
|
||||||
let data_path = format!("{}{NODE_DATA_DIR}", &base_dir);
|
let data_path = format!("{}{NODE_DATA_DIR}", &base_dir);
|
||||||
@@ -148,9 +137,9 @@ where
|
|||||||
generators::generate_node_command(node, gen_opts, maybe_para_id)
|
generators::generate_node_command(node, gen_opts, maybe_para_id)
|
||||||
},
|
},
|
||||||
ZombieRole::CumulusCollator => {
|
ZombieRole::CumulusCollator => {
|
||||||
let para = ctx.parachain.expect(&format!(
|
let para = ctx
|
||||||
"parachain must be part of the context {THIS_IS_A_BUG}"
|
.parachain
|
||||||
));
|
.expect(&format!("parachain must be part of the context {THIS_IS_A_BUG}"));
|
||||||
collator_full_node_prom_port = node.full_node_prometheus_port.as_ref().map(|p| p.0);
|
collator_full_node_prom_port = node.full_node_prometheus_port.as_ref().map(|p| p.0);
|
||||||
|
|
||||||
generators::generate_node_command_cumulus(node, gen_opts, para.id)
|
generators::generate_node_command_cumulus(node, gen_opts, para.id)
|
||||||
@@ -166,12 +155,7 @@ where
|
|||||||
.map(|arg| apply_running_network_replacements(arg, &ctx.nodes_by_name))
|
.map(|arg| apply_running_network_replacements(arg, &ctx.nodes_by_name))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
info!(
|
info!("🚀 {}, spawning.... with command: {} {}", node.name, program, args.join(" "));
|
||||||
"🚀 {}, spawning.... with command: {} {}",
|
|
||||||
node.name,
|
|
||||||
program,
|
|
||||||
args.join(" ")
|
|
||||||
);
|
|
||||||
|
|
||||||
let ports = if ctx.ns.capabilities().use_default_ports_in_cmd {
|
let ports = if ctx.ns.capabilities().use_default_ports_in_cmd {
|
||||||
// should use default ports to as internal
|
// should use default ports to as internal
|
||||||
@@ -181,20 +165,12 @@ where
|
|||||||
(PROMETHEUS_PORT, node.prometheus_port.0),
|
(PROMETHEUS_PORT, node.prometheus_port.0),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
[
|
[(P2P_PORT, P2P_PORT), (RPC_PORT, RPC_PORT), (PROMETHEUS_PORT, PROMETHEUS_PORT)]
|
||||||
(P2P_PORT, P2P_PORT),
|
|
||||||
(RPC_PORT, RPC_PORT),
|
|
||||||
(PROMETHEUS_PORT, PROMETHEUS_PORT),
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let spawn_ops = SpawnNodeOptions::new(node.name.clone(), program)
|
let spawn_ops = SpawnNodeOptions::new(node.name.clone(), program)
|
||||||
.args(args)
|
.args(args)
|
||||||
.env(
|
.env(node.env.iter().map(|var| (var.name.clone(), var.value.clone())))
|
||||||
node.env
|
|
||||||
.iter()
|
|
||||||
.map(|var| (var.name.clone(), var.value.clone())),
|
|
||||||
)
|
|
||||||
.injected_files(files_to_inject)
|
.injected_files(files_to_inject)
|
||||||
.created_paths(created_paths)
|
.created_paths(created_paths)
|
||||||
.db_snapshot(node.db_snapshot.clone())
|
.db_snapshot(node.db_snapshot.clone())
|
||||||
@@ -220,17 +196,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let running_node = ctx.ns.spawn_node(&spawn_ops).await.with_context(|| {
|
let running_node = ctx.ns.spawn_node(&spawn_ops).await.with_context(|| {
|
||||||
format!(
|
format!("Failed to spawn node: {} with opts: {:#?}", node.name, spawn_ops)
|
||||||
"Failed to spawn node: {} with opts: {:#?}",
|
|
||||||
node.name, spawn_ops
|
|
||||||
)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut ip_to_use = if let Some(local_ip) = ctx.global_settings.local_ip() {
|
let mut ip_to_use =
|
||||||
*local_ip
|
if let Some(local_ip) = ctx.global_settings.local_ip() { *local_ip } else { LOCALHOST };
|
||||||
} else {
|
|
||||||
LOCALHOST
|
|
||||||
};
|
|
||||||
|
|
||||||
let (rpc_port_external, prometheus_port_external, p2p_external);
|
let (rpc_port_external, prometheus_port_external, p2p_external);
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,11 @@ impl<Config: pezkuwi_subxt::Config + Send + Sync> ClientFromUrl for OnlineClient
|
|||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl ClientFromUrl for RpcClient {
|
impl ClientFromUrl for RpcClient {
|
||||||
async fn from_secure_url(url: &str) -> Result<Self, pezkuwi_subxt::Error> {
|
async fn from_secure_url(url: &str) -> Result<Self, pezkuwi_subxt::Error> {
|
||||||
Self::from_url(url)
|
Self::from_url(url).await.map_err(pezkuwi_subxt::Error::from)
|
||||||
.await
|
|
||||||
.map_err(pezkuwi_subxt::Error::from)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn from_insecure_url(url: &str) -> Result<Self, pezkuwi_subxt::Error> {
|
async fn from_insecure_url(url: &str) -> Result<Self, pezkuwi_subxt::Error> {
|
||||||
Self::from_insecure_url(url)
|
Self::from_insecure_url(url).await.map_err(pezkuwi_subxt::Error::from)
|
||||||
.await
|
|
||||||
.map_err(pezkuwi_subxt::Error::from)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-18
@@ -9,10 +9,7 @@ pub async fn upgrade(
|
|||||||
wasm_data: &[u8],
|
wasm_data: &[u8],
|
||||||
sudo: &Keypair,
|
sudo: &Keypair,
|
||||||
) -> Result<(), anyhow::Error> {
|
) -> Result<(), anyhow::Error> {
|
||||||
debug!(
|
debug!("Upgrading runtime, using node: {} with endpoting {}", node.name, node.ws_uri);
|
||||||
"Upgrading runtime, using node: {} with endpoting {}",
|
|
||||||
node.name, node.ws_uri
|
|
||||||
);
|
|
||||||
let api: OnlineClient<BizinikiwConfig> = node.wait_client().await?;
|
let api: OnlineClient<BizinikiwConfig> = node.wait_client().await?;
|
||||||
|
|
||||||
let upgrade = pezkuwi_subxt::dynamic::tx(
|
let upgrade = pezkuwi_subxt::dynamic::tx(
|
||||||
@@ -33,10 +30,7 @@ pub async fn upgrade(
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tx = api
|
let mut tx = api.tx().sign_and_submit_then_watch_default(&sudo_call, sudo).await?;
|
||||||
.tx()
|
|
||||||
.sign_and_submit_then_watch_default(&sudo_call, sudo)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// Below we use the low level API to replicate the `wait_for_in_block` behaviour
|
// Below we use the low level API to replicate the `wait_for_in_block` behaviour
|
||||||
// which was removed in subxt 0.33.0. See https://github.com/paritytech/subxt/pull/1237.
|
// which was removed in subxt 0.33.0. See https://github.com/paritytech/subxt/pull/1237.
|
||||||
@@ -45,16 +39,9 @@ pub async fn upgrade(
|
|||||||
match &status {
|
match &status {
|
||||||
TxStatus::InBestBlock(tx_in_block) | TxStatus::InFinalizedBlock(tx_in_block) => {
|
TxStatus::InBestBlock(tx_in_block) | TxStatus::InFinalizedBlock(tx_in_block) => {
|
||||||
let _result = tx_in_block.wait_for_success().await?;
|
let _result = tx_in_block.wait_for_success().await?;
|
||||||
let block_status = if status.as_finalized().is_some() {
|
let block_status =
|
||||||
"Finalized"
|
if status.as_finalized().is_some() { "Finalized" } else { "Best" };
|
||||||
} else {
|
info!("[{}] In block: {:#?}", block_status, tx_in_block.block_hash());
|
||||||
"Best"
|
|
||||||
};
|
|
||||||
info!(
|
|
||||||
"[{}] In block: {:#?}",
|
|
||||||
block_status,
|
|
||||||
tx_in_block.block_hash()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
TxStatus::Error { message }
|
TxStatus::Error { message }
|
||||||
| TxStatus::Invalid { message }
|
| TxStatus::Invalid { message }
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ pub fn parse(input: &str) -> Result<MetricMap, ParserError> {
|
|||||||
let mut pairs = MetricsParser::parse(Rule::statement, input)
|
let mut pairs = MetricsParser::parse(Rule::statement, input)
|
||||||
.map_err(|e| ParserError::ParseError(Box::new(e)))?;
|
.map_err(|e| ParserError::ParseError(Box::new(e)))?;
|
||||||
|
|
||||||
let root = pairs
|
let root = pairs.next().ok_or(ParserError::ParseRootNodeError(pairs.as_str().to_string()))?;
|
||||||
.next()
|
|
||||||
.ok_or(ParserError::ParseRootNodeError(pairs.as_str().to_string()))?;
|
|
||||||
for token in root.into_inner() {
|
for token in root.into_inner() {
|
||||||
if token.as_rule() == Rule::block {
|
if token.as_rule() == Rule::block {
|
||||||
let inner = token.into_inner();
|
let inner = token.into_inner();
|
||||||
@@ -148,15 +146,10 @@ mod tests {
|
|||||||
&1_f64
|
&1_f64
|
||||||
);
|
);
|
||||||
// with prefix and no chain
|
// with prefix and no chain
|
||||||
assert_eq!(
|
assert_eq!(metrics.get("polkadot_node_is_active_validator").unwrap(), &1_f64);
|
||||||
metrics.get("polkadot_node_is_active_validator").unwrap(),
|
|
||||||
&1_f64
|
|
||||||
);
|
|
||||||
// no prefix with chain
|
// no prefix with chain
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
metrics
|
metrics.get("node_is_active_validator{chain=\"rococo_local_testnet\"}").unwrap(),
|
||||||
.get("node_is_active_validator{chain=\"rococo_local_testnet\"}")
|
|
||||||
.unwrap(),
|
|
||||||
&1_f64
|
&1_f64
|
||||||
);
|
);
|
||||||
// no prefix without chain
|
// no prefix without chain
|
||||||
|
|||||||
@@ -106,11 +106,7 @@ impl ContainerRunOptions {
|
|||||||
{
|
{
|
||||||
ContainerRunOptions {
|
ContainerRunOptions {
|
||||||
image: image.to_string(),
|
image: image.to_string(),
|
||||||
command: command
|
command: command.clone().into_iter().map(|s| s.into()).collect::<Vec<_>>(),
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|s| s.into())
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
env: None,
|
env: None,
|
||||||
volume_mounts: None,
|
volume_mounts: None,
|
||||||
name: None,
|
name: None,
|
||||||
@@ -125,11 +121,7 @@ impl ContainerRunOptions {
|
|||||||
where
|
where
|
||||||
S: Into<String> + std::fmt::Debug + Send + Clone,
|
S: Into<String> + std::fmt::Debug + Send + Clone,
|
||||||
{
|
{
|
||||||
self.env = Some(
|
self.env = Some(env.into_iter().map(|(name, value)| (name.into(), value.into())).collect());
|
||||||
env.into_iter()
|
|
||||||
.map(|(name, value)| (name.into(), value.into()))
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,23 +178,13 @@ impl DockerClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn client_binary(&self) -> String {
|
pub fn client_binary(&self) -> String {
|
||||||
String::from(if self.using_podman {
|
String::from(if self.using_podman { "podman" } else { "docker" })
|
||||||
"podman"
|
|
||||||
} else {
|
|
||||||
"docker"
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn is_using_podman() -> Result<bool> {
|
async fn is_using_podman() -> Result<bool> {
|
||||||
if let Ok(output) = tokio::process::Command::new("docker")
|
if let Ok(output) = tokio::process::Command::new("docker").arg("version").output().await {
|
||||||
.arg("version")
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
// detect whether we're actually running podman with docker emulation
|
// detect whether we're actually running podman with docker emulation
|
||||||
return Ok(String::from_utf8_lossy(&output.stdout)
|
return Ok(String::from_utf8_lossy(&output.stdout).to_lowercase().contains("podman"));
|
||||||
.to_lowercase()
|
|
||||||
.contains("podman"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tokio::process::Command::new("podman")
|
tokio::process::Command::new("podman")
|
||||||
@@ -326,12 +308,7 @@ impl DockerClient {
|
|||||||
|
|
||||||
cmd.arg(name);
|
cmd.arg(name);
|
||||||
|
|
||||||
cmd.args(
|
cmd.args(command.clone().into_iter().map(|s| <S as Into<String>>::into(s)));
|
||||||
command
|
|
||||||
.clone()
|
|
||||||
.into_iter()
|
|
||||||
.map(|s| <S as Into<String>>::into(s)),
|
|
||||||
);
|
|
||||||
|
|
||||||
trace!("cmd is : {:?}", cmd);
|
trace!("cmd is : {:?}", cmd);
|
||||||
|
|
||||||
@@ -348,10 +325,7 @@ impl DockerClient {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
if !result.status.success() {
|
if !result.status.success() {
|
||||||
return Ok(Err((
|
return Ok(Err((result.status, String::from_utf8_lossy(&result.stderr).to_string())));
|
||||||
result.status,
|
|
||||||
String::from_utf8_lossy(&result.stderr).to_string(),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Ok(String::from_utf8_lossy(&result.stdout).to_string()))
|
Ok(Ok(String::from_utf8_lossy(&result.stdout).to_string()))
|
||||||
@@ -438,10 +412,8 @@ impl DockerClient {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
info!("{:?}", container_names);
|
info!("{:?}", container_names);
|
||||||
let futures = container_names
|
let futures =
|
||||||
.iter()
|
container_names.iter().map(|name| self.container_rm(name)).collect::<Vec<_>>();
|
||||||
.map(|name| self.container_rm(name))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
try_join_all(futures).await?;
|
try_join_all(futures).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -452,12 +424,7 @@ impl DockerClient {
|
|||||||
"127.0.0.1".into()
|
"127.0.0.1".into()
|
||||||
} else {
|
} else {
|
||||||
let mut cmd = tokio::process::Command::new("docker");
|
let mut cmd = tokio::process::Command::new("docker");
|
||||||
cmd.args(vec![
|
cmd.args(vec!["inspect", "-f", "{{ .NetworkSettings.IPAddress }}", container_name]);
|
||||||
"inspect",
|
|
||||||
"-f",
|
|
||||||
"{{ .NetworkSettings.IPAddress }}",
|
|
||||||
container_name,
|
|
||||||
]);
|
|
||||||
|
|
||||||
trace!("CMD: {cmd:?}");
|
trace!("CMD: {cmd:?}");
|
||||||
|
|
||||||
@@ -478,17 +445,9 @@ impl DockerClient {
|
|||||||
|
|
||||||
async fn get_containers(&self) -> Result<Vec<Container>> {
|
async fn get_containers(&self) -> Result<Vec<Container>> {
|
||||||
let containers = if self.using_podman {
|
let containers = if self.using_podman {
|
||||||
self.get_podman_containers()
|
self.get_podman_containers().await?.into_iter().map(Container::Podman).collect()
|
||||||
.await?
|
|
||||||
.into_iter()
|
|
||||||
.map(Container::Podman)
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
self.get_docker_containers()
|
self.get_docker_containers().await?.into_iter().map(Container::Docker).collect()
|
||||||
.await?
|
|
||||||
.into_iter()
|
|
||||||
.map(Container::Docker)
|
|
||||||
.collect()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(containers)
|
Ok(containers)
|
||||||
|
|||||||
@@ -131,16 +131,11 @@ where
|
|||||||
PathBuf::from_iter([&self.base_dir, &PathBuf::from("zombie-wrapper.sh")]);
|
PathBuf::from_iter([&self.base_dir, &PathBuf::from("zombie-wrapper.sh")]);
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem
|
||||||
.write(
|
.write(&local_zombie_wrapper_path, include_str!("../shared/scripts/zombie-wrapper.sh"))
|
||||||
&local_zombie_wrapper_path,
|
|
||||||
include_str!("../shared/scripts/zombie-wrapper.sh"),
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let local_helper_binaries_downloader_path = PathBuf::from_iter([
|
let local_helper_binaries_downloader_path =
|
||||||
&self.base_dir,
|
PathBuf::from_iter([&self.base_dir, &PathBuf::from("helper-binaries-downloader.sh")]);
|
||||||
&PathBuf::from("helper-binaries-downloader.sh"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem
|
||||||
.write(
|
.write(
|
||||||
@@ -351,10 +346,7 @@ where
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(node.name().to_string(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(node.name().to_string(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -375,10 +367,7 @@ where
|
|||||||
|
|
||||||
let node = DockerNode::attach_to_live(options).await?;
|
let node = DockerNode::attach_to_live(options).await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(node.name().to_string(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(node.name().to_string(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -386,9 +375,7 @@ where
|
|||||||
async fn generate_files(&self, options: GenerateFilesOptions) -> Result<(), ProviderError> {
|
async fn generate_files(&self, options: GenerateFilesOptions) -> Result<(), ProviderError> {
|
||||||
debug!("generate files options {options:#?}");
|
debug!("generate files options {options:#?}");
|
||||||
|
|
||||||
let node_name = options
|
let node_name = options.temp_name.unwrap_or_else(|| format!("temp-{}", Uuid::new_v4()));
|
||||||
.temp_name
|
|
||||||
.unwrap_or_else(|| format!("temp-{}", Uuid::new_v4()));
|
|
||||||
let node_image = options.image.expect(&format!(
|
let node_image = options.image.expect(&format!(
|
||||||
"image should be present when generating files with docker provider {THIS_IS_A_BUG}"
|
"image should be present when generating files with docker provider {THIS_IS_A_BUG}"
|
||||||
));
|
));
|
||||||
@@ -402,21 +389,11 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for GenerateFileCommand {
|
for GenerateFileCommand { program, args, env, local_output_path } in options.commands {
|
||||||
program,
|
|
||||||
args,
|
|
||||||
env,
|
|
||||||
local_output_path,
|
|
||||||
} in options.commands
|
|
||||||
{
|
|
||||||
let local_output_full_path = format!(
|
let local_output_full_path = format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
self.base_dir.to_string_lossy(),
|
self.base_dir.to_string_lossy(),
|
||||||
if local_output_path.starts_with("/") {
|
if local_output_path.starts_with("/") { "" } else { "/" },
|
||||||
""
|
|
||||||
} else {
|
|
||||||
"/"
|
|
||||||
},
|
|
||||||
local_output_path.to_string_lossy()
|
local_output_path.to_string_lossy()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -440,11 +417,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn destroy(&self) -> Result<(), ProviderError> {
|
async fn destroy(&self) -> Result<(), ProviderError> {
|
||||||
let _ = self
|
let _ =
|
||||||
.docker_client
|
self.docker_client.namespaced_containers_rm(&self.name).await.map_err(|err| {
|
||||||
.namespaced_containers_rm(&self.name)
|
ProviderError::DeleteNamespaceFailed(self.name.clone(), err.into())
|
||||||
.await
|
})?;
|
||||||
.map_err(|err| ProviderError::DeleteNamespaceFailed(self.name.clone(), err.into()))?;
|
|
||||||
|
|
||||||
if let Some(provider) = self.provider.upgrade() {
|
if let Some(provider) = self.provider.upgrade() {
|
||||||
provider.namespaces.write().await.remove(&self.name);
|
provider.namespaces.write().await.remove(&self.name);
|
||||||
|
|||||||
@@ -237,14 +237,8 @@ where
|
|||||||
format!("{}-helper-binaries", self.namespace_name()),
|
format!("{}-helper-binaries", self.namespace_name()),
|
||||||
"/helpers".to_string(),
|
"/helpers".to_string(),
|
||||||
),
|
),
|
||||||
(
|
(self.config_dir.to_string_lossy().into_owned(), "/cfg".to_string()),
|
||||||
self.config_dir.to_string_lossy().into_owned(),
|
(self.data_dir.to_string_lossy().into_owned(), "/data".to_string()),
|
||||||
"/cfg".to_string(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
self.data_dir.to_string_lossy().into_owned(),
|
|
||||||
"/data".to_string(),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
self.relay_data_dir.to_string_lossy().into_owned(),
|
self.relay_data_dir.to_string_lossy().into_owned(),
|
||||||
"/relay-data".to_string(),
|
"/relay-data".to_string(),
|
||||||
@@ -435,11 +429,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn log_cmd(&self) -> String {
|
fn log_cmd(&self) -> String {
|
||||||
format!(
|
format!("{} logs -f {}", self.docker_client.client_binary(), self.container_name)
|
||||||
"{} logs -f {}",
|
|
||||||
self.docker_client.client_binary(),
|
|
||||||
self.container_name
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path_in_node(&self, file: &Path) -> PathBuf {
|
fn path_in_node(&self, file: &Path) -> PathBuf {
|
||||||
@@ -470,23 +460,14 @@ where
|
|||||||
&self,
|
&self,
|
||||||
options: RunCommandOptions,
|
options: RunCommandOptions,
|
||||||
) -> Result<ExecutionResult, ProviderError> {
|
) -> Result<ExecutionResult, ProviderError> {
|
||||||
debug!(
|
debug!("running command for {} with options {:?}", self.name, options);
|
||||||
"running command for {} with options {:?}",
|
|
||||||
self.name, options
|
|
||||||
);
|
|
||||||
let command = [vec![options.program], options.args].concat();
|
let command = [vec![options.program], options.args].concat();
|
||||||
|
|
||||||
self.docker_client
|
self.docker_client
|
||||||
.container_exec(
|
.container_exec(
|
||||||
&self.container_name,
|
&self.container_name,
|
||||||
vec!["sh", "-c", &command.join(" ")],
|
vec!["sh", "-c", &command.join(" ")],
|
||||||
Some(
|
Some(options.env.iter().map(|(k, v)| (k.as_ref(), v.as_ref())).collect()),
|
||||||
options
|
|
||||||
.env
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.as_ref(), v.as_ref()))
|
|
||||||
.collect(),
|
|
||||||
),
|
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -565,11 +546,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn ip(&self) -> Result<IpAddr, ProviderError> {
|
async fn ip(&self) -> Result<IpAddr, ProviderError> {
|
||||||
let ip = self
|
let ip = self.docker_client.container_ip(&self.container_name).await.map_err(|err| {
|
||||||
.docker_client
|
|
||||||
.container_ip(&self.container_name)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
ProviderError::InvalidConfig(format!("Error getting container ip, err: {err}"))
|
ProviderError::InvalidConfig(format!("Error getting container ip, err: {err}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|||||||
@@ -105,10 +105,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -127,10 +124,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -151,10 +145,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,20 +121,12 @@ impl KubernetesClient {
|
|||||||
labels: Some(labels),
|
labels: Some(labels),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
data: Some(BTreeMap::from([(
|
data: Some(BTreeMap::from([(file_name.to_string(), file_contents.to_string())])),
|
||||||
file_name.to_string(),
|
|
||||||
file_contents.to_string(),
|
|
||||||
)])),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
config_maps
|
config_maps.create(&PostParams::default(), &config_map).await.map_err(|err| {
|
||||||
.create(&PostParams::default(), &config_map)
|
Error::from(anyhow!("error while creating config map {name} for {file_name}: {err}"))
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
Error::from(anyhow!(
|
|
||||||
"error while creating config map {name} for {file_name}: {err}"
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.wait_created(config_maps, name).await?;
|
self.wait_created(config_maps, name).await?;
|
||||||
@@ -169,9 +161,8 @@ impl KubernetesClient {
|
|||||||
trace!("Pod {name} checking for ready state!");
|
trace!("Pod {name} checking for ready state!");
|
||||||
let wait_ready = await_condition(pods, name, helpers::is_pod_ready());
|
let wait_ready = await_condition(pods, name, helpers::is_pod_ready());
|
||||||
// TODO: we should use the `node_spawn_timeout` from global settings here.
|
// TODO: we should use the `node_spawn_timeout` from global settings here.
|
||||||
let _ = tokio::time::timeout(Duration::from_secs(600), wait_ready)
|
let _ =
|
||||||
.await
|
tokio::time::timeout(Duration::from_secs(600), wait_ready).await.map_err(|err| {
|
||||||
.map_err(|err| {
|
|
||||||
Error::from(anyhow!("error while awaiting pod {name} running: {err}"))
|
Error::from(anyhow!("error while awaiting pod {name} running: {err}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -181,14 +172,7 @@ impl KubernetesClient {
|
|||||||
|
|
||||||
pub(super) async fn pod_logs(&self, namespace: &str, name: &str) -> Result<String> {
|
pub(super) async fn pod_logs(&self, namespace: &str, name: &str) -> Result<String> {
|
||||||
Api::<Pod>::namespaced(self.inner.clone(), namespace)
|
Api::<Pod>::namespaced(self.inner.clone(), namespace)
|
||||||
.logs(
|
.logs(name, &LogParams { pretty: true, timestamps: true, ..Default::default() })
|
||||||
name,
|
|
||||||
&LogParams {
|
|
||||||
pretty: true,
|
|
||||||
timestamps: true,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|err| Error::from(anyhow!("error while getting logs for pod {name}: {err}")))
|
.map_err(|err| Error::from(anyhow!("error while getting logs for pod {name}: {err}")))
|
||||||
}
|
}
|
||||||
@@ -199,9 +183,8 @@ impl KubernetesClient {
|
|||||||
.await
|
.await
|
||||||
.map_err(|err| Error::from(anyhow!("error while getting pod {name}: {err}")))?;
|
.map_err(|err| Error::from(anyhow!("error while getting pod {name}: {err}")))?;
|
||||||
|
|
||||||
let status = pod.status.ok_or(Error::from(anyhow!(
|
let status =
|
||||||
"error while getting status for pod {name}"
|
pod.status.ok_or(Error::from(anyhow!("error while getting status for pod {name}")))?;
|
||||||
)))?;
|
|
||||||
Ok(status)
|
Ok(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,9 +207,7 @@ impl KubernetesClient {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
Error::from(anyhow!(
|
Error::from(anyhow!("error while getting a log stream for {name}: {err}"))
|
||||||
"error while getting a log stream for {name}: {err}"
|
|
||||||
))
|
|
||||||
})?
|
})?
|
||||||
.compat(),
|
.compat(),
|
||||||
))
|
))
|
||||||
@@ -243,25 +224,21 @@ impl KubernetesClient {
|
|||||||
{
|
{
|
||||||
trace!("running command: {command:?} on pod {name} for ns {namespace}");
|
trace!("running command: {command:?} on pod {name} for ns {namespace}");
|
||||||
let mut process = Api::<Pod>::namespaced(self.inner.clone(), namespace)
|
let mut process = Api::<Pod>::namespaced(self.inner.clone(), namespace)
|
||||||
.exec(
|
.exec(name, command, &AttachParams::default().stdout(true).stderr(true))
|
||||||
name,
|
|
||||||
command,
|
|
||||||
&AttachParams::default().stdout(true).stderr(true),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|err| Error::from(anyhow!("error while exec in the pod {name}: {err}")))?;
|
.map_err(|err| Error::from(anyhow!("error while exec in the pod {name}: {err}")))?;
|
||||||
|
|
||||||
let stdout_stream = process.stdout().expect(&format!(
|
let stdout_stream = process
|
||||||
"stdout shouldn't be None when true passed to exec {THIS_IS_A_BUG}"
|
.stdout()
|
||||||
));
|
.expect(&format!("stdout shouldn't be None when true passed to exec {THIS_IS_A_BUG}"));
|
||||||
let stdout = tokio_util::io::ReaderStream::new(stdout_stream)
|
let stdout = tokio_util::io::ReaderStream::new(stdout_stream)
|
||||||
.filter_map(|r| async { r.ok().and_then(|v| String::from_utf8(v.to_vec()).ok()) })
|
.filter_map(|r| async { r.ok().and_then(|v| String::from_utf8(v.to_vec()).ok()) })
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.await
|
.await
|
||||||
.join("");
|
.join("");
|
||||||
let stderr_stream = process.stderr().expect(&format!(
|
let stderr_stream = process
|
||||||
"stderr shouldn't be None when true passed to exec {THIS_IS_A_BUG}"
|
.stderr()
|
||||||
));
|
.expect(&format!("stderr shouldn't be None when true passed to exec {THIS_IS_A_BUG}"));
|
||||||
let stderr = tokio_util::io::ReaderStream::new(stderr_stream)
|
let stderr = tokio_util::io::ReaderStream::new(stderr_stream)
|
||||||
.filter_map(|r| async { r.ok().and_then(|v| String::from_utf8(v.to_vec()).ok()) })
|
.filter_map(|r| async { r.ok().and_then(|v| String::from_utf8(v.to_vec()).ok()) })
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@@ -270,16 +247,12 @@ impl KubernetesClient {
|
|||||||
|
|
||||||
let status = process
|
let status = process
|
||||||
.take_status()
|
.take_status()
|
||||||
.expect(&format!(
|
.expect(&format!("first call to status shouldn't fail {THIS_IS_A_BUG}"))
|
||||||
"first call to status shouldn't fail {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// await process to finish
|
// await process to finish
|
||||||
process.join().await.map_err(|err| {
|
process.join().await.map_err(|err| {
|
||||||
Error::from(anyhow!(
|
Error::from(anyhow!("error while joining process during exec for {name}: {err}"))
|
||||||
"error while joining process during exec for {name}: {err}"
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
@@ -334,12 +307,8 @@ impl KubernetesClient {
|
|||||||
.await
|
.await
|
||||||
.map_err(|err| Error::from(anyhow!("error when deleting pod {name}: {err}")))?;
|
.map_err(|err| Error::from(anyhow!("error when deleting pod {name}: {err}")))?;
|
||||||
|
|
||||||
await_condition(pods, name, conditions::is_deleted(name))
|
await_condition(pods, name, conditions::is_deleted(name)).await.map_err(|err| {
|
||||||
.await
|
Error::from(anyhow!("error when waiting for pod {name} to be deleted: {err}"))
|
||||||
.map_err(|err| {
|
|
||||||
Error::from(anyhow!(
|
|
||||||
"error when waiting for pod {name} to be deleted: {err}"
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -381,12 +350,8 @@ impl KubernetesClient {
|
|||||||
remote_port: u16,
|
remote_port: u16,
|
||||||
) -> Result<(u16, JoinHandle<()>)> {
|
) -> Result<(u16, JoinHandle<()>)> {
|
||||||
let pods = Api::<Pod>::namespaced(self.inner.clone(), namespace);
|
let pods = Api::<Pod>::namespaced(self.inner.clone(), namespace);
|
||||||
let bind = TcpListener::bind((LOCALHOST, local_port))
|
let bind = TcpListener::bind((LOCALHOST, local_port)).await.map_err(|err| {
|
||||||
.await
|
Error::from(anyhow!("error binding port {local_port} for pod {name}: {err}"))
|
||||||
.map_err(|err| {
|
|
||||||
Error::from(anyhow!(
|
|
||||||
"error binding port {local_port} for pod {name}: {err}"
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
let local_port = bind.local_addr().map_err(|err| Error(err.into()))?.port();
|
let local_port = bind.local_addr().map_err(|err| Error(err.into()))?.port();
|
||||||
let name = name.to_string();
|
let name = name.to_string();
|
||||||
@@ -523,15 +488,10 @@ impl KubernetesClient {
|
|||||||
let ar = ApiResource::from_gvk(&gvk);
|
let ar = ApiResource::from_gvk(&gvk);
|
||||||
let api: Api<DynamicObject> = Api::namespaced_with(self.inner.clone(), namespace, &ar);
|
let api: Api<DynamicObject> = Api::namespaced_with(self.inner.clone(), namespace, &ar);
|
||||||
|
|
||||||
api.create(
|
api.create(&PostParams::default(), &serde_yaml::from_str(raw_manifest).unwrap())
|
||||||
&PostParams::default(),
|
|
||||||
&serde_yaml::from_str(raw_manifest).unwrap(),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
Error::from(anyhow!(
|
Error::from(anyhow!("error while creating static-config {raw_manifest}: {err}"))
|
||||||
"error while creating static-config {raw_manifest}: {err}"
|
|
||||||
))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -175,25 +175,13 @@ where
|
|||||||
async fn initialize_k8s(&self) -> Result<(), ProviderError> {
|
async fn initialize_k8s(&self) -> Result<(), ProviderError> {
|
||||||
// TODO (javier): check with Hamid if we are using this labels in any scheduling logic.
|
// TODO (javier): check with Hamid if we are using this labels in any scheduling logic.
|
||||||
let labels = BTreeMap::from([
|
let labels = BTreeMap::from([
|
||||||
(
|
("jobId".to_string(), env::var("CI_JOB_ID").unwrap_or("".to_string())),
|
||||||
"jobId".to_string(),
|
("projectName".to_string(), env::var("CI_PROJECT_NAME").unwrap_or("".to_string())),
|
||||||
env::var("CI_JOB_ID").unwrap_or("".to_string()),
|
("projectId".to_string(), env::var("CI_PROJECT_ID").unwrap_or("".to_string())),
|
||||||
),
|
|
||||||
(
|
|
||||||
"projectName".to_string(),
|
|
||||||
env::var("CI_PROJECT_NAME").unwrap_or("".to_string()),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"projectId".to_string(),
|
|
||||||
env::var("CI_PROJECT_ID").unwrap_or("".to_string()),
|
|
||||||
),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let manifest = self
|
let manifest =
|
||||||
.k8s_client
|
self.k8s_client.create_namespace(&self.name, labels).await.map_err(|err| {
|
||||||
.create_namespace(&self.name, labels)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
ProviderError::CreateNamespaceFailed(self.name.to_string(), err.into())
|
ProviderError::CreateNamespaceFailed(self.name.to_string(), err.into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -204,9 +192,7 @@ where
|
|||||||
let dest_path =
|
let dest_path =
|
||||||
PathBuf::from_iter([&self.base_dir, &PathBuf::from("namespace_manifest.yaml")]);
|
PathBuf::from_iter([&self.base_dir, &PathBuf::from("namespace_manifest.yaml")]);
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.write(dest_path, serialized_manifest).await?;
|
||||||
.write(dest_path, serialized_manifest)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -218,10 +204,7 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Apply NetworkPolicy manifest
|
// Apply NetworkPolicy manifest
|
||||||
self.k8s_client
|
self.k8s_client.create_static_resource(&self.name, &np_manifest).await.map_err(|err| {
|
||||||
.create_static_resource(&self.name, &np_manifest)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
ProviderError::CreateNamespaceFailed(self.name.to_string(), err.into())
|
ProviderError::CreateNamespaceFailed(self.name.to_string(), err.into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -254,10 +237,7 @@ where
|
|||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
image: Some(FILE_SERVER_IMAGE.to_string()),
|
image: Some(FILE_SERVER_IMAGE.to_string()),
|
||||||
image_pull_policy: Some("Always".to_string()),
|
image_pull_policy: Some("Always".to_string()),
|
||||||
ports: Some(vec![ContainerPort {
|
ports: Some(vec![ContainerPort { container_port: 80, ..Default::default() }]),
|
||||||
container_port: 80,
|
|
||||||
..Default::default()
|
|
||||||
}]),
|
|
||||||
startup_probe: Some(Probe {
|
startup_probe: Some(Probe {
|
||||||
http_get: Some(HTTPGetAction {
|
http_get: Some(HTTPGetAction {
|
||||||
path: Some("/".to_string()),
|
path: Some("/".to_string()),
|
||||||
@@ -285,21 +265,14 @@ where
|
|||||||
let pod_serialized_manifest = serde_yaml::to_string(&pod_manifest)
|
let pod_serialized_manifest = serde_yaml::to_string(&pod_manifest)
|
||||||
.map_err(|err| ProviderError::FileServerSetupError(err.into()))?;
|
.map_err(|err| ProviderError::FileServerSetupError(err.into()))?;
|
||||||
|
|
||||||
let pod_dest_path = PathBuf::from_iter([
|
let pod_dest_path =
|
||||||
&self.base_dir,
|
PathBuf::from_iter([&self.base_dir, &PathBuf::from("file_server_pod_manifest.yaml")]);
|
||||||
&PathBuf::from("file_server_pod_manifest.yaml"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.write(pod_dest_path, pod_serialized_manifest).await?;
|
||||||
.write(pod_dest_path, pod_serialized_manifest)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let service_spec = ServiceSpec {
|
let service_spec = ServiceSpec {
|
||||||
selector: Some(labels.clone()),
|
selector: Some(labels.clone()),
|
||||||
ports: Some(vec![ServicePort {
|
ports: Some(vec![ServicePort { port: 80, ..Default::default() }]),
|
||||||
port: 80,
|
|
||||||
..Default::default()
|
|
||||||
}]),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -317,9 +290,7 @@ where
|
|||||||
&PathBuf::from("file_server_service_manifest.yaml"),
|
&PathBuf::from("file_server_service_manifest.yaml"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.write(service_dest_path, serialized_service_manifest).await?;
|
||||||
.write(service_dest_path, serialized_service_manifest)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
self.setup_file_server_port_fwd(&name).await?;
|
self.setup_file_server_port_fwd(&name).await?;
|
||||||
|
|
||||||
@@ -366,9 +337,7 @@ where
|
|||||||
|
|
||||||
let dest_path = PathBuf::from_iter([&self.base_dir, &PathBuf::from(local_manifest_name)]);
|
let dest_path = PathBuf::from_iter([&self.base_dir, &PathBuf::from(local_manifest_name)]);
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.write(dest_path, serializer_manifest).await?;
|
||||||
.write(dest_path, serializer_manifest)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -496,10 +465,7 @@ where
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(node.name().to_string(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(node.name().to_string(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -520,10 +486,7 @@ where
|
|||||||
|
|
||||||
let node = KubernetesNode::attach_to_live(options).await?;
|
let node = KubernetesNode::attach_to_live(options).await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(node.name().to_string(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(node.name().to_string(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -531,9 +494,7 @@ where
|
|||||||
async fn generate_files(&self, options: GenerateFilesOptions) -> Result<(), ProviderError> {
|
async fn generate_files(&self, options: GenerateFilesOptions) -> Result<(), ProviderError> {
|
||||||
debug!("generate files options {options:#?}");
|
debug!("generate files options {options:#?}");
|
||||||
|
|
||||||
let node_name = options
|
let node_name = options.temp_name.unwrap_or_else(|| format!("temp-{}", Uuid::new_v4()));
|
||||||
.temp_name
|
|
||||||
.unwrap_or_else(|| format!("temp-{}", Uuid::new_v4()));
|
|
||||||
let node_image = options
|
let node_image = options
|
||||||
.image
|
.image
|
||||||
.expect(&format!("image should be present when generating files with kubernetes provider {THIS_IS_A_BUG}"));
|
.expect(&format!("image should be present when generating files with kubernetes provider {THIS_IS_A_BUG}"));
|
||||||
@@ -547,21 +508,11 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for GenerateFileCommand {
|
for GenerateFileCommand { program, args, env, local_output_path } in options.commands {
|
||||||
program,
|
|
||||||
args,
|
|
||||||
env,
|
|
||||||
local_output_path,
|
|
||||||
} in options.commands
|
|
||||||
{
|
|
||||||
let local_output_full_path = format!(
|
let local_output_full_path = format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
self.base_dir.to_string_lossy(),
|
self.base_dir.to_string_lossy(),
|
||||||
if local_output_path.starts_with("/") {
|
if local_output_path.starts_with("/") { "" } else { "/" },
|
||||||
""
|
|
||||||
} else {
|
|
||||||
"/"
|
|
||||||
},
|
|
||||||
local_output_path.to_string_lossy()
|
local_output_path.to_string_lossy()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -585,11 +536,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn destroy(&self) -> Result<(), ProviderError> {
|
async fn destroy(&self) -> Result<(), ProviderError> {
|
||||||
let _ = self
|
let _ =
|
||||||
.k8s_client
|
self.k8s_client.delete_namespace(&self.name).await.map_err(|err| {
|
||||||
.delete_namespace(&self.name)
|
ProviderError::DeleteNamespaceFailed(self.name.clone(), err.into())
|
||||||
.await
|
})?;
|
||||||
.map_err(|err| ProviderError::DeleteNamespaceFailed(self.name.clone(), err.into()))?;
|
|
||||||
|
|
||||||
if let Some(provider) = self.provider.upgrade() {
|
if let Some(provider) = self.provider.upgrade() {
|
||||||
provider.namespaces.write().await.remove(&self.name);
|
provider.namespaces.write().await.remove(&self.name);
|
||||||
|
|||||||
@@ -231,10 +231,7 @@ where
|
|||||||
|
|
||||||
async fn initialize_k8s(&self) -> Result<(), ProviderError> {
|
async fn initialize_k8s(&self) -> Result<(), ProviderError> {
|
||||||
let labels = BTreeMap::from([
|
let labels = BTreeMap::from([
|
||||||
(
|
("app.kubernetes.io/name".to_string(), self.name().to_string()),
|
||||||
"app.kubernetes.io/name".to_string(),
|
|
||||||
self.name().to_string(),
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"x-infra-instance".to_string(),
|
"x-infra-instance".to_string(),
|
||||||
env::var("X_INFRA_INSTANCE").unwrap_or("ondemand".to_string()),
|
env::var("X_INFRA_INSTANCE").unwrap_or("ondemand".to_string()),
|
||||||
@@ -312,9 +309,7 @@ where
|
|||||||
&PathBuf::from(format!("{}_svc_manifest.yaml", &self.name)),
|
&PathBuf::from(format!("{}_svc_manifest.yaml", &self.name)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.write(service_dest_path, serialized_service_manifest).await?;
|
||||||
.write(service_dest_path, serialized_service_manifest)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -471,12 +466,7 @@ where
|
|||||||
|
|
||||||
if res.status() != reqwest::StatusCode::OK {
|
if res.status() != reqwest::StatusCode::OK {
|
||||||
// we need to upload the file
|
// we need to upload the file
|
||||||
self.http_client
|
self.http_client.post(url.as_ref()).body(data).send().await.map_err(|err| {
|
||||||
.post(url.as_ref())
|
|
||||||
.body(data)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
ProviderError::UploadFile(location.to_string_lossy().to_string(), err.into())
|
ProviderError::UploadFile(location.to_string_lossy().to_string(), err.into())
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
@@ -491,9 +481,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(ProviderError::FileServerSetupError(anyhow!(
|
Err(ProviderError::FileServerSetupError(anyhow!("file server port not bound locally")))
|
||||||
"file server port not bound locally"
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn download_file(
|
async fn download_file(
|
||||||
@@ -507,12 +495,7 @@ where
|
|||||||
.pod_exec(
|
.pod_exec(
|
||||||
&self.namespace_name(),
|
&self.namespace_name(),
|
||||||
&self.name,
|
&self.name,
|
||||||
vec![
|
vec!["/cfg/curl", url, "--output", &remote_file_path.to_string_lossy()],
|
||||||
"/cfg/curl",
|
|
||||||
url,
|
|
||||||
"--output",
|
|
||||||
&remote_file_path.to_string_lossy(),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -538,11 +521,7 @@ where
|
|||||||
.pod_exec(
|
.pod_exec(
|
||||||
&self.namespace_name(),
|
&self.namespace_name(),
|
||||||
&self.name,
|
&self.name,
|
||||||
vec![
|
vec!["/cfg/coreutils", "sha256sum", &remote_file_path.to_string_lossy()],
|
||||||
"/cfg/coreutils",
|
|
||||||
"sha256sum",
|
|
||||||
&remote_file_path.to_string_lossy(),
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
@@ -657,10 +636,7 @@ where
|
|||||||
.await
|
.await
|
||||||
.map_err(|err| ProviderError::PortForwardError(local_port, remote_port, err.into()))?;
|
.map_err(|err| ProviderError::PortForwardError(local_port, remote_port, err.into()))?;
|
||||||
|
|
||||||
self.port_fwds
|
self.port_fwds.write().await.insert(remote_port, (port, task));
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(remote_port, (port, task));
|
|
||||||
|
|
||||||
Ok(Some(port))
|
Ok(Some(port))
|
||||||
}
|
}
|
||||||
@@ -682,11 +658,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.k8s_client
|
self.k8s_client
|
||||||
.pod_exec(
|
.pod_exec(&self.namespace_name(), &self.name, vec!["sh", "-c", &command.join(" ")])
|
||||||
&self.namespace_name(),
|
|
||||||
&self.name,
|
|
||||||
vec!["sh", "-c", &command.join(" ")],
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
ProviderError::RunCommandError(
|
ProviderError::RunCommandError(
|
||||||
@@ -704,9 +676,7 @@ where
|
|||||||
let file_name = options
|
let file_name = options
|
||||||
.local_script_path
|
.local_script_path
|
||||||
.file_name()
|
.file_name()
|
||||||
.expect(&format!(
|
.expect(&format!("file name should be present at this point {THIS_IS_A_BUG}"))
|
||||||
"file name should be present at this point {THIS_IS_A_BUG}"
|
|
||||||
))
|
|
||||||
.to_string_lossy();
|
.to_string_lossy();
|
||||||
|
|
||||||
self.run_command(RunCommandOptions {
|
self.run_command(RunCommandOptions {
|
||||||
@@ -747,9 +717,7 @@ where
|
|||||||
tokio::time::sleep(Duration::from_secs(i)).await;
|
tokio::time::sleep(Duration::from_secs(i)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = self
|
let res = self.download_file(url.as_ref(), remote_file_path, Some(&hash)).await;
|
||||||
.download_file(url.as_ref(), remote_file_path, Some(&hash))
|
|
||||||
.await;
|
|
||||||
|
|
||||||
last_err = res.err();
|
last_err = res.err();
|
||||||
|
|
||||||
@@ -803,10 +771,7 @@ where
|
|||||||
ProviderError::InvalidConfig(format!("Can not parse the pod ip: {ip}, err: {err}"))
|
ProviderError::InvalidConfig(format!("Can not parse the pod ip: {ip}, err: {err}"))
|
||||||
})?)
|
})?)
|
||||||
} else {
|
} else {
|
||||||
Err(ProviderError::InvalidConfig(format!(
|
Err(ProviderError::InvalidConfig(format!("Can not find ip of pod: {}", self.name())))
|
||||||
"Can not find ip of pod: {}",
|
|
||||||
self.name()
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-16
@@ -44,10 +44,7 @@ impl PodSpecBuilder {
|
|||||||
image: Some(image.to_string()),
|
image: Some(image.to_string()),
|
||||||
image_pull_policy: Some("Always".to_string()),
|
image_pull_policy: Some("Always".to_string()),
|
||||||
command: Some(
|
command: Some(
|
||||||
[
|
[vec!["/zombie-wrapper.sh".to_string(), program.to_string()], args.to_vec()]
|
||||||
vec!["/zombie-wrapper.sh".to_string(), program.to_string()],
|
|
||||||
args.to_vec(),
|
|
||||||
]
|
|
||||||
.concat(),
|
.concat(),
|
||||||
),
|
),
|
||||||
env: Some(
|
env: Some(
|
||||||
@@ -91,18 +88,9 @@ impl PodSpecBuilder {
|
|||||||
|
|
||||||
fn build_volumes() -> Vec<Volume> {
|
fn build_volumes() -> Vec<Volume> {
|
||||||
vec![
|
vec![
|
||||||
Volume {
|
Volume { name: "cfg".to_string(), ..Default::default() },
|
||||||
name: "cfg".to_string(),
|
Volume { name: "data".to_string(), ..Default::default() },
|
||||||
..Default::default()
|
Volume { name: "relay-data".to_string(), ..Default::default() },
|
||||||
},
|
|
||||||
Volume {
|
|
||||||
name: "data".to_string(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
Volume {
|
|
||||||
name: "relay-data".to_string(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
Volume {
|
Volume {
|
||||||
name: "zombie-wrapper-volume".to_string(),
|
name: "zombie-wrapper-volume".to_string(),
|
||||||
config_map: Some(ConfigMapVolumeSource {
|
config_map: Some(ConfigMapVolumeSource {
|
||||||
|
|||||||
@@ -89,10 +89,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -111,10 +108,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -135,10 +129,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,10 +166,7 @@ where
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(options.name.clone(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(options.name.clone(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -194,10 +191,7 @@ where
|
|||||||
as i32;
|
as i32;
|
||||||
let node = NativeNode::attach_to_live(options, pid).await?;
|
let node = NativeNode::attach_to_live(options, pid).await?;
|
||||||
|
|
||||||
self.nodes
|
self.nodes.write().await.insert(node.name().to_string(), node.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(node.name().to_string(), node.clone());
|
|
||||||
|
|
||||||
Ok(node)
|
Ok(node)
|
||||||
}
|
}
|
||||||
@@ -218,13 +212,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
for GenerateFileCommand {
|
for GenerateFileCommand { program, args, env, local_output_path } in options.commands {
|
||||||
program,
|
|
||||||
args,
|
|
||||||
env,
|
|
||||||
local_output_path,
|
|
||||||
} in options.commands
|
|
||||||
{
|
|
||||||
trace!(
|
trace!(
|
||||||
"🏗 building file {:?} in path {} with command {} {}",
|
"🏗 building file {:?} in path {} with command {} {}",
|
||||||
local_output_path.as_os_str(),
|
local_output_path.as_os_str(),
|
||||||
@@ -235,11 +223,7 @@ where
|
|||||||
let local_output_full_path = format!(
|
let local_output_full_path = format!(
|
||||||
"{}{}{}",
|
"{}{}{}",
|
||||||
self.base_dir.to_string_lossy(),
|
self.base_dir.to_string_lossy(),
|
||||||
if local_output_path.starts_with("/") {
|
if local_output_path.starts_with("/") { "" } else { "/" },
|
||||||
""
|
|
||||||
} else {
|
|
||||||
"/"
|
|
||||||
},
|
|
||||||
local_output_path.to_string_lossy()
|
local_output_path.to_string_lossy()
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -329,16 +313,11 @@ mod tests {
|
|||||||
let cmd = GenerateFileCommand::new(program, out_name.clone()).args(args);
|
let cmd = GenerateFileCommand::new(program, out_name.clone()).args(args);
|
||||||
let options = GenerateFilesOptions::new(vec![cmd], None, Some(expected_path.clone()));
|
let options = GenerateFilesOptions::new(vec![cmd], None, Some(expected_path.clone()));
|
||||||
|
|
||||||
ns.generate_files(options)
|
ns.generate_files(options).await.expect("generation should succeed");
|
||||||
.await
|
|
||||||
.expect("generation should succeed");
|
|
||||||
|
|
||||||
// Read produced file from namespace base_dir
|
// Read produced file from namespace base_dir
|
||||||
let produced_path = base_dir.join(out_name);
|
let produced_path = base_dir.join(out_name);
|
||||||
let produced = fs
|
let produced = fs.read_to_string(&produced_path).await.expect("should read produced file");
|
||||||
.read_to_string(&produced_path)
|
|
||||||
.await
|
|
||||||
.expect("should read produced file");
|
|
||||||
assert_eq!(produced, "{\"hello\":\"world\"}");
|
assert_eq!(produced, "{\"hello\":\"world\"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,15 +339,10 @@ mod tests {
|
|||||||
let cmd = GenerateFileCommand::new(program, out_name.clone()).args(args);
|
let cmd = GenerateFileCommand::new(program, out_name.clone()).args(args);
|
||||||
let options = GenerateFilesOptions::new(vec![cmd], None, None);
|
let options = GenerateFilesOptions::new(vec![cmd], None, None);
|
||||||
|
|
||||||
ns.generate_files(options)
|
ns.generate_files(options).await.expect("generation should succeed");
|
||||||
.await
|
|
||||||
.expect("generation should succeed");
|
|
||||||
|
|
||||||
let produced_path = base_dir.join(out_name);
|
let produced_path = base_dir.join(out_name);
|
||||||
let produced = fs
|
let produced = fs.read_to_string(&produced_path).await.expect("should read produced file");
|
||||||
.read_to_string(&produced_path)
|
|
||||||
.await
|
|
||||||
.expect("should read produced file");
|
|
||||||
assert_eq!(produced, "42");
|
assert_eq!(produced, "42");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-44
@@ -300,9 +300,7 @@ where
|
|||||||
let contents = self.filesystem.read(&full_path).await.unwrap();
|
let contents = self.filesystem.read(&full_path).await.unwrap();
|
||||||
let gz = GzDecoder::new(&contents[..]);
|
let gz = GzDecoder::new(&contents[..]);
|
||||||
let mut archive = Archive::new(gz);
|
let mut archive = Archive::new(gz);
|
||||||
archive
|
archive.unpack(self.base_dir.to_string_lossy().as_ref()).unwrap();
|
||||||
.unpack(self.base_dir.to_string_lossy().as_ref())
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
if std::env::var("ZOMBIE_RM_TGZ_AFTER_EXTRACT").is_ok() {
|
if std::env::var("ZOMBIE_RM_TGZ_AFTER_EXTRACT").is_ok() {
|
||||||
let res = fs::remove_file(&full_path).await;
|
let res = fs::remove_file(&full_path).await;
|
||||||
@@ -337,9 +335,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn initialize_process(&self) -> Result<(ChildStdout, ChildStderr), ProviderError> {
|
async fn initialize_process(&self) -> Result<(ChildStdout, ChildStderr), ProviderError> {
|
||||||
let filtered_env: HashMap<String, String> = env::vars()
|
let filtered_env: HashMap<String, String> =
|
||||||
.filter(|(k, _)| k == "TZ" || k == "LANG" || k == "PATH")
|
env::vars().filter(|(k, _)| k == "TZ" || k == "LANG" || k == "PATH").collect();
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut process = Command::new(&self.program)
|
let mut process = Command::new(&self.program)
|
||||||
.args(&self.args)
|
.args(&self.args)
|
||||||
@@ -353,14 +350,10 @@ where
|
|||||||
.current_dir(&self.base_dir)
|
.current_dir(&self.base_dir)
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|err| ProviderError::NodeSpawningFailed(self.name.to_string(), err.into()))?;
|
.map_err(|err| ProviderError::NodeSpawningFailed(self.name.to_string(), err.into()))?;
|
||||||
let stdout = process
|
let stdout =
|
||||||
.stdout
|
process.stdout.take().expect(&format!("infaillible, stdout is piped {THIS_IS_A_BUG}"));
|
||||||
.take()
|
let stderr =
|
||||||
.expect(&format!("infaillible, stdout is piped {THIS_IS_A_BUG}"));
|
process.stderr.take().expect(&format!("infaillible, stderr is piped {THIS_IS_A_BUG}"));
|
||||||
let stderr = process
|
|
||||||
.stderr
|
|
||||||
.take()
|
|
||||||
.expect(&format!("infaillible, stderr is piped {THIS_IS_A_BUG}"));
|
|
||||||
|
|
||||||
let pid = Pid::from_raw(
|
let pid = Pid::from_raw(
|
||||||
process
|
process
|
||||||
@@ -392,10 +385,7 @@ where
|
|||||||
let filesystem = self.filesystem.clone();
|
let filesystem = self.filesystem.clone();
|
||||||
let log_path = self.log_path.clone();
|
let log_path = self.log_path.clone();
|
||||||
|
|
||||||
self.log_writing_task
|
self.log_writing_task.write().await.replace(tokio::spawn(async move {
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.replace(tokio::spawn(async move {
|
|
||||||
loop {
|
loop {
|
||||||
while let Some(Ok(data)) = rx.recv().await {
|
while let Some(Ok(data)) = rx.recv().await {
|
||||||
// TODO: find a better way instead of ignoring error ?
|
// TODO: find a better way instead of ignoring error ?
|
||||||
@@ -464,9 +454,7 @@ where
|
|||||||
.process_handle
|
.process_handle
|
||||||
.write()
|
.write()
|
||||||
.map_err(|_e| ProviderError::FailedToAcquireLock(self.name.clone()))?;
|
.map_err(|_e| ProviderError::FailedToAcquireLock(self.name.clone()))?;
|
||||||
guard
|
guard.take().ok_or_else(|| anyhow!("no process was attached for the node"))?
|
||||||
.take()
|
|
||||||
.ok_or_else(|| anyhow!("no process was attached for the node"))?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match process_handle {
|
match process_handle {
|
||||||
@@ -532,11 +520,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn path_in_node(&self, file: &Path) -> PathBuf {
|
fn path_in_node(&self, file: &Path) -> PathBuf {
|
||||||
let full_path = format!(
|
let full_path = format!("{}/{}", self.base_dir.to_string_lossy(), file.to_string_lossy());
|
||||||
"{}/{}",
|
|
||||||
self.base_dir.to_string_lossy(),
|
|
||||||
file.to_string_lossy()
|
|
||||||
);
|
|
||||||
PathBuf::from(full_path)
|
PathBuf::from(full_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,10 +553,7 @@ where
|
|||||||
if result.status.success() {
|
if result.status.success() {
|
||||||
Ok(Ok(String::from_utf8_lossy(&result.stdout).to_string()))
|
Ok(Ok(String::from_utf8_lossy(&result.stdout).to_string()))
|
||||||
} else {
|
} else {
|
||||||
Ok(Err((
|
Ok(Err((result.status, String::from_utf8_lossy(&result.stderr).to_string())))
|
||||||
result.status,
|
|
||||||
String::from_utf8_lossy(&result.stderr).to_string(),
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -594,16 +575,11 @@ where
|
|||||||
"Can't retrieve filename from script with path: {:?}",
|
"Can't retrieve filename from script with path: {:?}",
|
||||||
options.local_script_path
|
options.local_script_path
|
||||||
)))?;
|
)))?;
|
||||||
let remote_script_path = format!(
|
let remote_script_path =
|
||||||
"{}/{}",
|
format!("{}/{}", self.scripts_dir.to_string_lossy(), script_file_name);
|
||||||
self.scripts_dir.to_string_lossy(),
|
|
||||||
script_file_name
|
|
||||||
);
|
|
||||||
|
|
||||||
// copy and set script's execute permission
|
// copy and set script's execute permission
|
||||||
self.filesystem
|
self.filesystem.copy(local_script_path, &remote_script_path).await?;
|
||||||
.copy(local_script_path, &remote_script_path)
|
|
||||||
.await?;
|
|
||||||
self.filesystem.set_mode(&remote_script_path, 0o744).await?;
|
self.filesystem.set_mode(&remote_script_path, 0o744).await?;
|
||||||
|
|
||||||
// execute script
|
// execute script
|
||||||
@@ -627,9 +603,7 @@ where
|
|||||||
remote_file_path.to_string_lossy()
|
remote_file_path.to_string_lossy()
|
||||||
));
|
));
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.copy(local_file_path, &namespaced_remote_file_path).await?;
|
||||||
.copy(local_file_path, &namespaced_remote_file_path)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
self.run_command(
|
self.run_command(
|
||||||
RunCommandOptions::new("chmod")
|
RunCommandOptions::new("chmod")
|
||||||
@@ -658,9 +632,7 @@ where
|
|||||||
remote_file_path.to_string_lossy()
|
remote_file_path.to_string_lossy()
|
||||||
));
|
));
|
||||||
|
|
||||||
self.filesystem
|
self.filesystem.copy(namespaced_remote_file_path, local_file_path).await?;
|
||||||
.copy(namespaced_remote_file_path, local_file_path)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,10 +88,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -109,10 +106,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
@@ -132,10 +126,7 @@ where
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.namespaces
|
self.namespaces.write().await.insert(namespace.name().to_string(), namespace.clone());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(namespace.name().to_string(), namespace.clone());
|
|
||||||
|
|
||||||
Ok(namespace)
|
Ok(namespace)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,21 +44,16 @@ pub async fn extract_execution_result(
|
|||||||
pub fn extract_namespace_info(
|
pub fn extract_namespace_info(
|
||||||
json_value: &serde_json::Value,
|
json_value: &serde_json::Value,
|
||||||
) -> Result<(PathBuf, String), ProviderError> {
|
) -> Result<(PathBuf, String), ProviderError> {
|
||||||
let base_dir = json_value
|
let base_dir =
|
||||||
.get("local_base_dir")
|
json_value.get("local_base_dir").and_then(|v| v.as_str()).map(PathBuf::from).ok_or(
|
||||||
.and_then(|v| v.as_str())
|
ProviderError::InvalidConfig(
|
||||||
.map(PathBuf::from)
|
|
||||||
.ok_or(ProviderError::InvalidConfig(
|
|
||||||
"`field local_base_dir` is missing from zombie.json".to_string(),
|
"`field local_base_dir` is missing from zombie.json".to_string(),
|
||||||
))?;
|
),
|
||||||
|
)?;
|
||||||
|
|
||||||
let name =
|
let name = json_value.get("ns").and_then(|v| v.as_str()).ok_or(
|
||||||
json_value
|
ProviderError::InvalidConfig("field `ns` is missing from zombie.json".to_string()),
|
||||||
.get("ns")
|
)?;
|
||||||
.and_then(|v| v.as_str())
|
|
||||||
.ok_or(ProviderError::InvalidConfig(
|
|
||||||
"field `ns` is missing from zombie.json".to_string(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
Ok((base_dir, name.to_string()))
|
Ok((base_dir, name.to_string()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,10 +126,7 @@ impl SpawnNodeOptions {
|
|||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
I: IntoIterator<Item = P>,
|
I: IntoIterator<Item = P>,
|
||||||
{
|
{
|
||||||
self.created_paths = created_paths
|
self.created_paths = created_paths.into_iter().map(|path| path.as_ref().into()).collect();
|
||||||
.into_iter()
|
|
||||||
.map(|path| path.as_ref().into())
|
|
||||||
.collect();
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +261,7 @@ impl RunCommandOptions {
|
|||||||
where
|
where
|
||||||
S: AsRef<str>,
|
S: AsRef<str>,
|
||||||
{
|
{
|
||||||
Self {
|
Self { program: program.as_ref().to_string(), args: vec![], env: vec![] }
|
||||||
program: program.as_ref().to_string(),
|
|
||||||
args: vec![],
|
|
||||||
env: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn args<S, I>(mut self, args: I) -> Self
|
pub fn args<S, I>(mut self, args: I) -> Self
|
||||||
@@ -304,11 +297,7 @@ impl RunScriptOptions {
|
|||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Self {
|
Self { local_script_path: local_script_path.as_ref().into(), args: vec![], env: vec![] }
|
||||||
local_script_path: local_script_path.as_ref().into(),
|
|
||||||
args: vec![],
|
|
||||||
env: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn args<S, I>(mut self, args: I) -> Self
|
pub fn args<S, I>(mut self, args: I) -> Self
|
||||||
|
|||||||
+5
-20
@@ -36,40 +36,25 @@ async fn rococo_local_with_omni_node_and_wasm_runtime() {
|
|||||||
|
|
||||||
// wait 2 blocks
|
// wait 2 blocks
|
||||||
let alice = network.get_node("alice").unwrap();
|
let alice = network.get_node("alice").unwrap();
|
||||||
assert!(alice
|
assert!(alice.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64).await.is_ok());
|
||||||
.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64)
|
|
||||||
.await
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// omni-collator-1
|
// omni-collator-1
|
||||||
let collator = network.get_node("omni-collator-1").unwrap();
|
let collator = network.get_node("omni-collator-1").unwrap();
|
||||||
let client = collator
|
let client = collator.wait_client::<subxt::PolkadotConfig>().await.unwrap();
|
||||||
.wait_client::<subxt::PolkadotConfig>()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// wait 1 blocks
|
// wait 1 blocks
|
||||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||||
while let Some(block) = blocks.next().await {
|
while let Some(block) = blocks.next().await {
|
||||||
println!(
|
println!("Block (omni-collator-1) #{}", block.unwrap().header().number);
|
||||||
"Block (omni-collator-1) #{}",
|
|
||||||
block.unwrap().header().number
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// omni-collator-2
|
// omni-collator-2
|
||||||
let collator = network.get_node("omni-collator-2").unwrap();
|
let collator = network.get_node("omni-collator-2").unwrap();
|
||||||
let client = collator
|
let client = collator.wait_client::<subxt::PolkadotConfig>().await.unwrap();
|
||||||
.wait_client::<subxt::PolkadotConfig>()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// wait 1 blocks
|
// wait 1 blocks
|
||||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||||
while let Some(block) = blocks.next().await {
|
while let Some(block) = blocks.next().await {
|
||||||
println!(
|
println!("Block (omni-collator-2) #{}", block.unwrap().header().number);
|
||||||
"Block (omni-collator-2) #{}",
|
|
||||||
block.unwrap().header().number
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-20
@@ -37,40 +37,25 @@ async fn polkadot_local_with_chain_spec_runtime() {
|
|||||||
|
|
||||||
// wait 2 blocks
|
// wait 2 blocks
|
||||||
let alice = network.get_node("alice").unwrap();
|
let alice = network.get_node("alice").unwrap();
|
||||||
assert!(alice
|
assert!(alice.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64).await.is_ok());
|
||||||
.wait_metric(BEST_BLOCK_METRIC, |b| b > 2_f64)
|
|
||||||
.await
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
// asset-hub-collator-1
|
// asset-hub-collator-1
|
||||||
let collator = network.get_node("asset-hub-collator-1").unwrap();
|
let collator = network.get_node("asset-hub-collator-1").unwrap();
|
||||||
let client = collator
|
let client = collator.wait_client::<subxt::PolkadotConfig>().await.unwrap();
|
||||||
.wait_client::<subxt::PolkadotConfig>()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// wait 1 blocks
|
// wait 1 blocks
|
||||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||||
while let Some(block) = blocks.next().await {
|
while let Some(block) = blocks.next().await {
|
||||||
println!(
|
println!("Block (asset-hub-collator-1) #{}", block.unwrap().header().number);
|
||||||
"Block (asset-hub-collator-1) #{}",
|
|
||||||
block.unwrap().header().number
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// asset-hub-collator-2
|
// asset-hub-collator-2
|
||||||
let collator = network.get_node("asset-hub-collator-2").unwrap();
|
let collator = network.get_node("asset-hub-collator-2").unwrap();
|
||||||
let client = collator
|
let client = collator.wait_client::<subxt::PolkadotConfig>().await.unwrap();
|
||||||
.wait_client::<subxt::PolkadotConfig>()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// wait 1 blocks
|
// wait 1 blocks
|
||||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(1);
|
||||||
while let Some(block) = blocks.next().await {
|
while let Some(block) = blocks.next().await {
|
||||||
println!(
|
println!("Block (asset-hub-collator-2) #{}", block.unwrap().header().number);
|
||||||
"Block (asset-hub-collator-2) #{}",
|
|
||||||
block.unwrap().header().number
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,5 @@ async fn ci_native_smoke_should_works() {
|
|||||||
// Get a ref to the node
|
// Get a ref to the node
|
||||||
let alice = network.get_node("alice").unwrap();
|
let alice = network.get_node("alice").unwrap();
|
||||||
// wait 10 blocks
|
// wait 10 blocks
|
||||||
alice
|
alice.wait_metric(BEST_BLOCK_METRIC, |x| x > 9_f64).await.unwrap();
|
||||||
.wait_metric(BEST_BLOCK_METRIC, |x| x > 9_f64)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-38
@@ -29,8 +29,7 @@ fn small_network() -> NetworkConfig {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
.with_global_settings(|g| {
|
.with_global_settings(|g| {
|
||||||
g.with_base_dir(PathBuf::from("/tmp/zombie-1"))
|
g.with_base_dir(PathBuf::from("/tmp/zombie-1")).with_tear_down_on_failure(false)
|
||||||
.with_tear_down_on_failure(false)
|
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@@ -67,10 +66,7 @@ async fn ci_k8s_basic_functionalities_should_works() {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
alice
|
alice.wait_log_line_count("*rted #1*", true, 10).await.unwrap();
|
||||||
.wait_log_line_count("*rted #1*", true, 10)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// check best block through metrics with timeout
|
// check best block through metrics with timeout
|
||||||
assert!(alice
|
assert!(alice
|
||||||
@@ -102,19 +98,13 @@ async fn ci_k8s_basic_functionalities_should_works() {
|
|||||||
drop(client);
|
drop(client);
|
||||||
|
|
||||||
// check best block through metrics
|
// check best block through metrics
|
||||||
let best_block = alice
|
let best_block = alice.reports("block_height{status=\"best\"}").await.unwrap();
|
||||||
.reports("block_height{status=\"best\"}")
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(best_block >= 2.0, "Current best {best_block}");
|
assert!(best_block >= 2.0, "Current best {best_block}");
|
||||||
|
|
||||||
// collator
|
// collator
|
||||||
let collator = network.get_node("collator").unwrap();
|
let collator = network.get_node("collator").unwrap();
|
||||||
let client = collator
|
let client = collator.wait_client::<subxt::PolkadotConfig>().await.unwrap();
|
||||||
.wait_client::<subxt::PolkadotConfig>()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// wait 3 blocks
|
// wait 3 blocks
|
||||||
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(3);
|
let mut blocks = client.blocks().subscribe_finalized().await.unwrap().take(3);
|
||||||
@@ -123,55 +113,37 @@ async fn ci_k8s_basic_functionalities_should_works() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add node
|
// add node
|
||||||
let opts = AddNodeOptions {
|
let opts = AddNodeOptions { rpc_port: Some(9444), is_validator: true, ..Default::default() };
|
||||||
rpc_port: Some(9444),
|
|
||||||
is_validator: true,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
network.add_node("new1", opts).await.unwrap();
|
network.add_node("new1", opts).await.unwrap();
|
||||||
|
|
||||||
// add collator
|
// add collator
|
||||||
let col_opts = AddCollatorOptions {
|
let col_opts = AddCollatorOptions {
|
||||||
command: Some("polkadot-parachain".try_into().unwrap()),
|
command: Some("polkadot-parachain".try_into().unwrap()),
|
||||||
image: Some(
|
image: Some("docker.io/parity/polkadot-parachain:1.7.0".try_into().unwrap()),
|
||||||
"docker.io/parity/polkadot-parachain:1.7.0"
|
|
||||||
.try_into()
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
network
|
network.add_collator("new-col-1", col_opts, 2000).await.unwrap();
|
||||||
.add_collator("new-col-1", col_opts, 2000)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// pause / resume
|
// pause / resume
|
||||||
let alice = network.get_node("alice").unwrap();
|
let alice = network.get_node("alice").unwrap();
|
||||||
alice.pause().await.unwrap();
|
alice.pause().await.unwrap();
|
||||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||||
|
|
||||||
let res_err = alice
|
let res_err = alice.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32).await;
|
||||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
assert!(res_err.is_err());
|
assert!(res_err.is_err());
|
||||||
|
|
||||||
alice.resume().await.unwrap();
|
alice.resume().await.unwrap();
|
||||||
alice
|
alice.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32).await.unwrap();
|
||||||
.wait_metric_with_timeout(BEST_BLOCK_METRIC, |x| x > 5_f64, 5_u32)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// timeout connecting ws
|
// timeout connecting ws
|
||||||
let collator = network.get_node("collator").unwrap();
|
let collator = network.get_node("collator").unwrap();
|
||||||
collator.pause().await.unwrap();
|
collator.pause().await.unwrap();
|
||||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||||
|
|
||||||
let r = collator
|
let r = collator.wait_client_with_timeout::<subxt::PolkadotConfig>(1_u32).await;
|
||||||
.wait_client_with_timeout::<subxt::PolkadotConfig>(1_u32)
|
|
||||||
.await;
|
|
||||||
assert!(r.is_err());
|
assert!(r.is_err());
|
||||||
|
|
||||||
// tear down (optional if you don't detach the network)
|
// tear down (optional if you don't detach the network)
|
||||||
|
|||||||
+33
-108
@@ -24,10 +24,7 @@ impl InMemoryFile {
|
|||||||
where
|
where
|
||||||
C: AsRef<[u8]>,
|
C: AsRef<[u8]>,
|
||||||
{
|
{
|
||||||
Self::File {
|
Self::File { mode: 0o664, contents: contents.as_ref().to_vec() }
|
||||||
mode: 0o664,
|
|
||||||
contents: contents.as_ref().to_vec(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
@@ -67,9 +64,7 @@ pub struct InMemoryFileSystem {
|
|||||||
|
|
||||||
impl InMemoryFileSystem {
|
impl InMemoryFileSystem {
|
||||||
pub fn new(files: HashMap<OsString, InMemoryFile>) -> Self {
|
pub fn new(files: HashMap<OsString, InMemoryFile>) -> Self {
|
||||||
Self {
|
Self { files: Arc::new(RwLock::new(files)) }
|
||||||
files: Arc::new(RwLock::new(files)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,18 +89,14 @@ impl FileSystem for InMemoryFileSystem {
|
|||||||
for path in path.ancestors().skip(1) {
|
for path in path.ancestors().skip(1) {
|
||||||
match self.files.read().await.get(path.as_os_str()) {
|
match self.files.read().await.get(path.as_os_str()) {
|
||||||
Some(InMemoryFile::Directory { .. }) => continue,
|
Some(InMemoryFile::Directory { .. }) => continue,
|
||||||
Some(InMemoryFile::File { .. }) => Err(anyhow!(
|
Some(InMemoryFile::File { .. }) => {
|
||||||
"ancestor {:?} is not a directory",
|
Err(anyhow!("ancestor {:?} is not a directory", path.as_os_str(),))?
|
||||||
path.as_os_str(),
|
},
|
||||||
))?,
|
|
||||||
None => Err(anyhow!("ancestor {:?} doesn't exists", path.as_os_str(),))?,
|
None => Err(anyhow!("ancestor {:?} doesn't exists", path.as_os_str(),))?,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
self.files
|
self.files.write().await.insert(os_path.to_owned(), InMemoryFile::dir());
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.insert(os_path.to_owned(), InMemoryFile::dir());
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -116,20 +107,14 @@ impl FileSystem for InMemoryFileSystem {
|
|||||||
{
|
{
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let mut files = self.files.write().await;
|
let mut files = self.files.write().await;
|
||||||
let ancestors = path
|
let ancestors = path.ancestors().collect::<Vec<&Path>>().into_iter().rev().skip(1);
|
||||||
.ancestors()
|
|
||||||
.collect::<Vec<&Path>>()
|
|
||||||
.into_iter()
|
|
||||||
.rev()
|
|
||||||
.skip(1);
|
|
||||||
|
|
||||||
for path in ancestors {
|
for path in ancestors {
|
||||||
match files.get(path.as_os_str()) {
|
match files.get(path.as_os_str()) {
|
||||||
Some(InMemoryFile::Directory { .. }) => continue,
|
Some(InMemoryFile::Directory { .. }) => continue,
|
||||||
Some(InMemoryFile::File { .. }) => Err(anyhow!(
|
Some(InMemoryFile::File { .. }) => {
|
||||||
"ancestor {:?} is not a directory",
|
Err(anyhow!("ancestor {:?} is not a directory", path.as_os_str().to_owned(),))?
|
||||||
path.as_os_str().to_owned(),
|
},
|
||||||
))?,
|
|
||||||
None => files.insert(path.as_os_str().to_owned(), InMemoryFile::dir()),
|
None => files.insert(path.as_os_str().to_owned(), InMemoryFile::dir()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -175,10 +160,9 @@ impl FileSystem for InMemoryFileSystem {
|
|||||||
for path in path.ancestors().skip(1) {
|
for path in path.ancestors().skip(1) {
|
||||||
match files.get(path.as_os_str()) {
|
match files.get(path.as_os_str()) {
|
||||||
Some(InMemoryFile::Directory { .. }) => continue,
|
Some(InMemoryFile::Directory { .. }) => continue,
|
||||||
Some(InMemoryFile::File { .. }) => Err(anyhow!(
|
Some(InMemoryFile::File { .. }) => {
|
||||||
"ancestor {:?} is not a directory",
|
Err(anyhow!("ancestor {:?} is not a directory", path.as_os_str()))?
|
||||||
path.as_os_str()
|
},
|
||||||
))?,
|
|
||||||
None => Err(anyhow!("ancestor {:?} doesn't exists", path.as_os_str()))?,
|
None => Err(anyhow!("ancestor {:?} doesn't exists", path.as_os_str()))?,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -246,10 +230,7 @@ impl FileSystem for InMemoryFileSystem {
|
|||||||
where
|
where
|
||||||
P: AsRef<Path> + Send,
|
P: AsRef<Path> + Send,
|
||||||
{
|
{
|
||||||
self.files
|
self.files.read().await.contains_key(path.as_ref().as_os_str())
|
||||||
.read()
|
|
||||||
.await
|
|
||||||
.contains_key(path.as_ref().as_os_str())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,10 +292,7 @@ mod tests {
|
|||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(OsString::from_str("/path").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path").unwrap(), InMemoryFile::dir()),
|
||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/path/to/my").unwrap(), InMemoryFile::dir()),
|
||||||
OsString::from_str("/path/to/my").unwrap(),
|
|
||||||
InMemoryFile::dir(),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
fs.create_dir("/path/to/my/dir").await.unwrap();
|
fs.create_dir("/path/to/my/dir").await.unwrap();
|
||||||
@@ -350,10 +328,7 @@ mod tests {
|
|||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(OsString::from_str("/path").unwrap(), InMemoryFile::empty()),
|
(OsString::from_str("/path").unwrap(), InMemoryFile::empty()),
|
||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/path/to/my").unwrap(), InMemoryFile::dir()),
|
||||||
OsString::from_str("/path/to/my").unwrap(),
|
|
||||||
InMemoryFile::dir(),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs.create_dir("/path/to/my/dir").await.unwrap_err();
|
let err = fs.create_dir("/path/to/my/dir").await.unwrap_err();
|
||||||
@@ -525,10 +500,7 @@ mod tests {
|
|||||||
|
|
||||||
let err = fs.read_to_string("/myfile").await.unwrap_err();
|
let err = fs.read_to_string("/myfile").await.unwrap_err();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(err.to_string(), "invalid utf-8 encoding for file \"/myfile\"");
|
||||||
err.to_string(),
|
|
||||||
"invalid utf-8 encoding for file \"/myfile\""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -554,10 +526,7 @@ mod tests {
|
|||||||
async fn write_should_overwrite_file_content_if_file_exists() {
|
async fn write_should_overwrite_file_content_if_file_exists() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
fs.write("/myfile", "my new file content").await.unwrap();
|
fs.write("/myfile", "my new file content").await.unwrap();
|
||||||
@@ -592,10 +561,7 @@ mod tests {
|
|||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs
|
let err = fs.write("/path/to/myfile", "my file content").await.unwrap_err();
|
||||||
.write("/path/to/myfile", "my file content")
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(fs.files.read().await.len(), 2);
|
assert_eq!(fs.files.read().await.len(), 2);
|
||||||
assert_eq!(err.to_string(), "ancestor \"/path\" doesn't exists");
|
assert_eq!(err.to_string(), "ancestor \"/path\" doesn't exists");
|
||||||
@@ -609,10 +575,7 @@ mod tests {
|
|||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs
|
let err = fs.write("/path/to/myfile", "my file content").await.unwrap_err();
|
||||||
.write("/path/to/myfile", "my file content")
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(fs.files.read().await.len(), 3);
|
assert_eq!(fs.files.read().await.len(), 3);
|
||||||
assert_eq!(err.to_string(), "ancestor \"/path\" is not a directory");
|
assert_eq!(err.to_string(), "ancestor \"/path\" is not a directory");
|
||||||
@@ -622,15 +585,10 @@ mod tests {
|
|||||||
async fn append_should_update_file_content_if_file_exists() {
|
async fn append_should_update_file_content_if_file_exists() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
fs.append("/myfile", " has been updated with new things")
|
fs.append("/myfile", " has been updated with new things").await.unwrap();
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(fs.files.read().await.len(), 2);
|
assert_eq!(fs.files.read().await.len(), 2);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
@@ -680,10 +638,7 @@ mod tests {
|
|||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs
|
let err = fs.append("/path/to/myfile", "my file content").await.unwrap_err();
|
||||||
.append("/path/to/myfile", "my file content")
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(fs.files.read().await.len(), 2);
|
assert_eq!(fs.files.read().await.len(), 2);
|
||||||
assert_eq!(err.to_string(), "ancestor \"/path\" doesn't exists");
|
assert_eq!(err.to_string(), "ancestor \"/path\" doesn't exists");
|
||||||
@@ -697,10 +652,7 @@ mod tests {
|
|||||||
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/path/to").unwrap(), InMemoryFile::dir()),
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs
|
let err = fs.append("/path/to/myfile", "my file content").await.unwrap_err();
|
||||||
.append("/path/to/myfile", "my file content")
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
assert_eq!(fs.files.read().await.len(), 3);
|
assert_eq!(fs.files.read().await.len(), 3);
|
||||||
assert_eq!(err.to_string(), "ancestor \"/path\" is not a directory");
|
assert_eq!(err.to_string(), "ancestor \"/path\" is not a directory");
|
||||||
@@ -710,10 +662,7 @@ mod tests {
|
|||||||
async fn copy_should_creates_new_destination_file_if_it_doesnt_exists() {
|
async fn copy_should_creates_new_destination_file_if_it_doesnt_exists() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
fs.copy("/myfile", "/myfilecopy").await.unwrap();
|
fs.copy("/myfile", "/myfilecopy").await.unwrap();
|
||||||
@@ -728,14 +677,8 @@ mod tests {
|
|||||||
async fn copy_should_updates_the_file_content_of_the_destination_file_if_it_already_exists() {
|
async fn copy_should_updates_the_file_content_of_the_destination_file_if_it_already_exists() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my new file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
(OsString::from_str("/myfilecopy").unwrap(), InMemoryFile::file("my file content")),
|
||||||
InMemoryFile::file("my new file content"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
OsString::from_str("/myfilecopy").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
fs.copy("/myfile", "/myfilecopy").await.unwrap();
|
fs.copy("/myfile", "/myfilecopy").await.unwrap();
|
||||||
@@ -774,14 +717,8 @@ mod tests {
|
|||||||
async fn copy_should_returns_an_error_if_destination_file_is_a_directory() {
|
async fn copy_should_returns_an_error_if_destination_file_is_a_directory() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
(OsString::from_str("/myfilecopy").unwrap(), InMemoryFile::dir()),
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
OsString::from_str("/myfilecopy").unwrap(),
|
|
||||||
InMemoryFile::dir(),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs.copy("/myfile", "/myfilecopy").await.unwrap_err();
|
let err = fs.copy("/myfile", "/myfilecopy").await.unwrap_err();
|
||||||
@@ -794,10 +731,7 @@ mod tests {
|
|||||||
) {
|
) {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs.copy("/myfile", "/somedir/myfilecopy").await.unwrap_err();
|
let err = fs.copy("/myfile", "/somedir/myfilecopy").await.unwrap_err();
|
||||||
@@ -811,14 +745,8 @@ mod tests {
|
|||||||
) {
|
) {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
(OsString::from_str("/mypath").unwrap(), InMemoryFile::empty()),
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
OsString::from_str("/mypath").unwrap(),
|
|
||||||
InMemoryFile::empty(),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let err = fs.copy("/myfile", "/mypath/myfilecopy").await.unwrap_err();
|
let err = fs.copy("/myfile", "/mypath/myfilecopy").await.unwrap_err();
|
||||||
@@ -831,10 +759,7 @@ mod tests {
|
|||||||
async fn set_mode_should_update_the_file_mode_at_path() {
|
async fn set_mode_should_update_the_file_mode_at_path() {
|
||||||
let fs = InMemoryFileSystem::new(HashMap::from([
|
let fs = InMemoryFileSystem::new(HashMap::from([
|
||||||
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
(OsString::from_str("/").unwrap(), InMemoryFile::dir()),
|
||||||
(
|
(OsString::from_str("/myfile").unwrap(), InMemoryFile::file("my file content")),
|
||||||
OsString::from_str("/myfile").unwrap(),
|
|
||||||
InMemoryFile::file("my file content"),
|
|
||||||
),
|
|
||||||
]));
|
]));
|
||||||
assert!(
|
assert!(
|
||||||
matches!(fs.files.read().await.get(&OsString::from_str("/myfile").unwrap()).unwrap(), InMemoryFile::File { mode, .. } if *mode == 0o664)
|
matches!(fs.files.read().await.get(&OsString::from_str("/myfile").unwrap()).unwrap(), InMemoryFile::File { mode, .. } if *mode == 0o664)
|
||||||
|
|||||||
+5
-18
@@ -59,9 +59,7 @@ impl FileSystem for LocalFileSystem {
|
|||||||
.await
|
.await
|
||||||
.map_err(Into::<FileSystemError>::into)?;
|
.map_err(Into::<FileSystemError>::into)?;
|
||||||
|
|
||||||
file.write_all(contents)
|
file.write_all(contents).await.map_err(Into::<FileSystemError>::into)?;
|
||||||
.await
|
|
||||||
.map_err(Into::<FileSystemError>::into)?;
|
|
||||||
|
|
||||||
file.flush().await.and(Ok(())).map_err(Into::into)
|
file.flush().await.and(Ok(())).map_err(Into::into)
|
||||||
}
|
}
|
||||||
@@ -71,19 +69,14 @@ impl FileSystem for LocalFileSystem {
|
|||||||
P1: AsRef<Path> + Send,
|
P1: AsRef<Path> + Send,
|
||||||
P2: AsRef<Path> + Send,
|
P2: AsRef<Path> + Send,
|
||||||
{
|
{
|
||||||
tokio::fs::copy(from, to)
|
tokio::fs::copy(from, to).await.and(Ok(())).map_err(Into::into)
|
||||||
.await
|
|
||||||
.and(Ok(()))
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_mode<P>(&self, path: P, mode: u32) -> FileSystemResult<()>
|
async fn set_mode<P>(&self, path: P, mode: u32) -> FileSystemResult<()>
|
||||||
where
|
where
|
||||||
P: AsRef<Path> + Send,
|
P: AsRef<Path> + Send,
|
||||||
{
|
{
|
||||||
tokio::fs::set_permissions(path, Permissions::from_mode(mode))
|
tokio::fs::set_permissions(path, Permissions::from_mode(mode)).await.map_err(Into::into)
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exists<P>(&self, path: P) -> bool
|
async fn exists<P>(&self, path: P) -> bool
|
||||||
@@ -351,10 +344,7 @@ mod tests {
|
|||||||
|
|
||||||
fs.set_mode(&path, 0o400).await.unwrap();
|
fs.set_mode(&path, 0o400).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode(), FILE_BITS + 0o400);
|
||||||
std::fs::metadata(&path).unwrap().permissions().mode(),
|
|
||||||
FILE_BITS + 0o400
|
|
||||||
);
|
|
||||||
teardown(test_dir);
|
teardown(test_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,10 +358,7 @@ mod tests {
|
|||||||
|
|
||||||
fs.set_mode(&path, 0o700).await.unwrap();
|
fs.set_mode(&path, 0o700).await.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode(), DIR_BITS + 0o700);
|
||||||
std::fs::metadata(&path).unwrap().permissions().mode(),
|
|
||||||
DIR_BITS + 0o700
|
|
||||||
);
|
|
||||||
teardown(test_dir);
|
teardown(test_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -78,9 +78,7 @@ pub fn apply_running_network_replacements(text: &str, network: &serde_json::Valu
|
|||||||
pub fn get_tokens_to_replace(text: &str) -> HashSet<String> {
|
pub fn get_tokens_to_replace(text: &str) -> HashSet<String> {
|
||||||
let mut tokens = HashSet::new();
|
let mut tokens = HashSet::new();
|
||||||
|
|
||||||
TOKEN_PLACEHOLDER
|
TOKEN_PLACEHOLDER.captures_iter(text).for_each(|caps: Captures| {
|
||||||
.captures_iter(text)
|
|
||||||
.for_each(|caps: Captures| {
|
|
||||||
tokens.insert(caps[1].to_string());
|
tokens.insert(caps[1].to_string());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+14
-21
@@ -1,26 +1,19 @@
|
|||||||
# https://rust-lang.github.io/rustfmt/?version=v1.7.0
|
# Pezkuwi ZombieNet SDK - Stable Rustfmt Configuration
|
||||||
|
# Only stable features for compatibility with CI
|
||||||
|
|
||||||
# general
|
# Basic (stable)
|
||||||
indent_style = "Block"
|
hard_tabs = true
|
||||||
|
max_width = 100
|
||||||
|
use_small_heuristics = "Max"
|
||||||
|
|
||||||
# rewriting
|
# Imports (stable)
|
||||||
condense_wildcard_suffixes = true
|
reorder_imports = true
|
||||||
|
reorder_modules = true
|
||||||
|
|
||||||
|
# Consistency (stable)
|
||||||
|
newline_style = "Unix"
|
||||||
|
|
||||||
|
# Misc (stable)
|
||||||
match_block_trailing_comma = true
|
match_block_trailing_comma = true
|
||||||
use_field_init_shorthand = true
|
use_field_init_shorthand = true
|
||||||
use_try_shorthand = true
|
use_try_shorthand = true
|
||||||
|
|
||||||
# normalization
|
|
||||||
normalize_comments = true
|
|
||||||
normalize_doc_attributes = true
|
|
||||||
|
|
||||||
# reordering
|
|
||||||
reorder_impl_items = true
|
|
||||||
reorder_imports = true
|
|
||||||
reorder_modules = true
|
|
||||||
imports_granularity = "Crate"
|
|
||||||
group_imports = "StdExternalCrate"
|
|
||||||
|
|
||||||
# additional formating
|
|
||||||
format_code_in_doc_comments = true
|
|
||||||
format_macro_matchers = true
|
|
||||||
format_macro_bodies = true
|
|
||||||
|
|||||||
Reference in New Issue
Block a user