Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions kindelia/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ anyhow = { version = "1.0.66", features = ["backtrace"] }
dirs = "4.0.0"
hex = "0.4"
derive_builder = "0.11.2"
include_dir = "0.7.3"

# CLI / configuration
clap = { version = "4.0.18", features = ["derive"] }
clap_complete = "4.0.3"
clap-num = "1.0.2"
toml = "0.5.9"

# Datastructures
Expand All @@ -49,6 +51,9 @@ warp = "0.3"
tokio = { version = "1.19.1", features = ["sync"] }


# Errors
thiserror = "1.0.37"

[dev-dependencies]
assert_cmd = "1.0.1"
fastrand = "1.7.0"
Expand Down
2 changes: 1 addition & 1 deletion kindelia/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ dir = "~/.kindelia/state"
[node.network]
network_id = "0xCAFE0006"

[node.networks.0xCAFE0006]
[node.network.0xCAFE0006]
initial_peers = [
"64.227.110.69",
"188.166.3.140",
Expand Down
13 changes: 13 additions & 0 deletions kindelia/genesis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# About this directory

The `genesis/networks` directory holds genesis block files, one per network.

Important! All files inside the `networks` sub-directory get compiled into the
`kindelia` executable. So please do not put any other type of file inside and
observe the naming convention.

The files are named to match hexadecimal network identifiers as specified
in the config file with extension `.kdl`. For example, `network/0xCAFE0006.kdl` corresponds to network `0xCAFE0006`.

Typically a new network is created by bumping this value, eg creating the
file `networks/0xCAFE0007.kdl`. Also `../default.toml` should be updated to match.
File renamed without changes.
9 changes: 8 additions & 1 deletion kindelia/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::PathBuf;

use clap::{Parser, Subcommand};
use clap_complete::Shell;
use clap_num::maybe_hex;
Comment thread
dan-da marked this conversation as resolved.

use kindelia_common::Name;
use kindelia_core::api::LimitStats;
Expand Down Expand Up @@ -120,6 +121,9 @@ pub enum CliCommand {
/// Whether to consider size and mana in the execution.
#[clap(long)]
sudo: bool,
/// Path to genesis file. else use default genesis for tests.
#[clap(short, long)]
genesis: Option<PathBuf>,
},
/// Checks for statements in kdl file
Check {
Expand Down Expand Up @@ -205,8 +209,11 @@ pub enum CliCommand {
#[clap(long)]
data_dir: Option<PathBuf>,
/// Network id / magic number.
#[clap(long)]
#[clap(long, value_parser=maybe_hex::<u32>)]
network_id: Option<u32>,
/// File containing genesis statements.
#[clap(long)]
genesis: Option<PathBuf>,
},
/// Generate auto-completion for a shell.
Completion {
Expand Down
31 changes: 18 additions & 13 deletions kindelia/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ where
}
if let (Some(prop_path), Some(config_values)) = (self.prop, config_values) {
// If config file and argument prop path are set, read from config file
return Self::resolve_from_config_aux(config_values, &prop_path);
if let Some(v) = Self::resolve_from_config_aux(config_values, &prop_path)?
{
return Ok(v);
}
}
(self.default_value)()
}
Expand All @@ -66,10 +69,13 @@ where
{
if let Some(prop_path) = self.prop {
if let Some(config_values) = config_values {
Self::resolve_from_config_aux(config_values, &prop_path)
} else {
(self.default_value)()
if let Some(v) =
Self::resolve_from_config_aux(config_values, &prop_path)?
{
return Ok(v);
}
}
(self.default_value)()
} else {
Err(anyhow!(
"Cannot resolve from config file config without 'prop' field set"
Expand Down Expand Up @@ -105,18 +111,17 @@ where
fn resolve_from_config_aux(
config_values: &toml::Value,
prop_path: &str,
) -> anyhow::Result<T>
) -> anyhow::Result<Option<T>>
where
T: ArgumentFrom<toml::Value>,
{
let value = Self::get_prop(config_values, prop_path).context(anyhow!(
"Could not find prop '{}' in config file.",
prop_path
))?;
T::arg_from(value).context(anyhow!(
"Could not convert value of '{}' into desired type",
prop_path,
))
match Self::get_prop(config_values, prop_path) {
Some(value) => Ok(Some(T::arg_from(value).context(anyhow!(
"Could not convert value of '{}' into desired type",
prop_path,
))?)),
None => Ok(None),
}
}

fn get_prop(mut value: &toml::Value, prop_path: &str) -> Option<toml::Value> {
Expand Down
30 changes: 30 additions & 0 deletions kindelia/src/genesis.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use include_dir::{include_dir, Dir};
use thiserror::Error;

#[derive(Error, Debug)]
pub enum GenesisCodeError {
#[error("Unknown network: {0}.")]
UnknownNetwork(u32),

#[error("Invalid Utf8 in genesis block for network: {network_id:?}.")]
InvalidUtf8 { network_id: u32, source: std::str::Utf8Error },
}

// Todo: it would be cleaner to return the contents as &[u8] without
// UTF8 conversion. However the result ultimately gets passed to
// parse_code() as &str, so the UTF-8 conversion has to happen somewhere.
// Likely the correct thing would be to change parse_code to accept
// &[u8] instead.
pub fn genesis_code(network_id: u32) -> Result<&'static str, GenesisCodeError> {
const GENESIS_DIR: Dir<'_> =
include_dir!("$CARGO_MANIFEST_DIR/genesis/networks");

let fname = format!("{:#02X}.kdl", network_id);
let contents = GENESIS_DIR
.get_file(&fname)
.ok_or(GenesisCodeError::UnknownNetwork(network_id))?
.contents();

std::str::from_utf8(contents)
.map_err(|e| GenesisCodeError::InvalidUtf8 { network_id, source: e })
}
Loading