Skip to content

Commit

Permalink
[feature] #2422: Add public sharable configuration
Browse files Browse the repository at this point in the history
Signed-off-by: Shanin Roman <[email protected]>
  • Loading branch information
Erigara committed Jul 5, 2022
1 parent 9bfa772 commit 961f602
Show file tree
Hide file tree
Showing 22 changed files with 1,851 additions and 34 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

16 changes: 12 additions & 4 deletions cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,37 @@
use std::{fmt::Debug, fs::File, io::BufReader, path::Path};

use eyre::{Result, WrapErr};
use iroha_config::derive::Configurable;
use iroha_config::derive::{Configurable, View};
use iroha_core::{
block_sync::config::BlockSyncConfiguration, genesis::config::GenesisConfiguration,
kura::config::KuraConfiguration, queue::Configuration as QueueConfiguration,
sumeragi::config::SumeragiConfiguration,
wsv::config::Configuration as WorldStateViewConfiguration,
};
use iroha_crypto::prelude::*;
use iroha_data_model::prelude::*;
use iroha_data_model::{
config::{
network::Configuration as PublicNetworkConfiguration, Configuration as PublicConfiguration,
},
prelude::*,
};
use iroha_logger::Configuration as LoggerConfiguration;
use serde::{Deserialize, Serialize};

use super::torii::config::ToriiConfiguration;

/// Configuration parameters container.
#[derive(Debug, Clone, Deserialize, Serialize, Configurable)]
#[derive(Debug, Clone, Deserialize, Serialize, Configurable, View)]
#[serde(default)]
#[serde(rename_all = "UPPERCASE")]
#[config(env_prefix = "IROHA_")]
#[view(PublicConfiguration)]
pub struct Configuration {
/// Public key of this peer.
#[config(serde_as_str)]
pub public_key: PublicKey,
/// Private key of this peer.
#[view(ignore)]
pub private_key: PrivateKey,
/// Disable coloring of the backtrace and error report on panic.
pub disable_panic_terminal_colors: bool,
Expand Down Expand Up @@ -87,10 +94,11 @@ impl Default for Configuration {
}

/// Network Configuration parameters container.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Configurable)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Configurable, View)]
#[serde(default)]
#[serde(rename_all = "UPPERCASE")]
#[config(env_prefix = "IROHA_NETWORK_")]
#[view(PublicNetworkConfiguration)]
pub struct NetworkConfiguration {
/// Buffer capacity of actor's MPSC channel
pub actor_channel_capacity: u32,
Expand Down
9 changes: 6 additions & 3 deletions cli/src/torii/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Configuration as well as the default values for the URLs used for the main endpoints: `p2p`, `telemetry`, but not `api`.
use iroha_config::derive::Configurable;
use iroha_data_model::uri::DEFAULT_API_URL;
use iroha_config::derive::{Configurable, View};
use iroha_data_model::{
config::torii::Configuration as PublicToriiConfiguration, uri::DEFAULT_API_URL,
};
use serde::{Deserialize, Serialize};

/// Default socket for p2p communication
Expand All @@ -15,10 +17,11 @@ pub const DEFAULT_TORII_MAX_CONTENT_LENGTH: u32 = 2_u32.pow(12) * 4000;
/// Structure that defines the configuration parameters of `Torii` which is the routing module.
/// For example the `p2p_addr`, which is used for consensus and block-synchronisation purposes,
/// as well as `max_transaction_size`.
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Configurable)]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Configurable, View)]
#[serde(rename_all = "UPPERCASE")]
#[serde(default)]
#[config(env_prefix = "TORII_")]
#[view(PublicToriiConfiguration)]
pub struct ToriiConfiguration {
/// Torii URL for p2p communication for consensus and block synchronization purposes.
pub p2p_addr: String,
Expand Down
128 changes: 128 additions & 0 deletions config/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,131 @@ fn impl_configurable(ast: &DeriveInput) -> TokenStream {
};
out.into()
}

struct ViewType {
ident: Ident,
}

impl Parse for ViewType {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
ident: input.parse()?,
})
}
}

struct ViewIgnore {
_ident: Ident,
}

impl ViewIgnore {
const IGNORE: &'static str = "ignore";
}

impl Parse for ViewIgnore {
fn parse(input: ParseStream) -> syn::Result<Self> {
Ok(Self {
_ident: parse_const_ident(input, Self::IGNORE)?,
})
}
}

/// Derive conversation between type and it's view. Check other doc in `iroha_config` reexport.
#[proc_macro_derive(View, attributes(view))]
pub fn into_view_derive(input: TokenStream) -> TokenStream {
let ast = match syn::parse(input) {
Ok(ast) => ast,
Err(err) => {
abort_call_site!("Failed to parse input Token Stream: {}", err)
}
};
impl_into_view(&ast)
}

#[allow(clippy::str_to_string)]
fn impl_into_view(ast: &DeriveInput) -> TokenStream {
let ty = &ast.ident;
#[allow(clippy::expect_used)]
let view = ast
.attrs
.iter()
.find_map(|attr| {
if !attr.path.is_ident("view") {
return None;
}
attr.parse_args::<ViewType>().ok()
})
.map(|view| view.ident)
.expect("Required to provide view type.");
let fields = if let Data::Struct(DataStruct {
fields: Fields::Named(fields),
..
}) = &ast.data
{
&fields.named
} else {
abort!(ast, "Only structs are supported");
};
// Filter-out fields with `#[view(ignore)]`
let fields = fields
.iter()
.filter(|field| {
field
.attrs
.iter()
.find_map(|attr| {
if !attr.path.is_ident("view") {
return None;
}
attr.parse_args::<ViewIgnore>().ok()
})
.is_none()
})
.collect::<Vec<_>>();
let field_idents = fields
.iter()
.map(|field| {
#[allow(clippy::expect_used)]
field
.ident
.as_ref()
.expect("Should always be set for named structures")
})
.collect::<Vec<_>>();
let out = quote! {
impl From<#view> for #ty {
fn from(config: #view) -> Self {
let #view {
#(
#field_idents,
)*
} = config;
// Important to write macro in uniform way.
#[allow(clippy::needless_update)]
Self {
#(
#field_idents: From::<_>::from(#field_idents),
)*
..Self::default()
}
}
}

impl From<#ty> for #view {
fn from(config: #ty) -> Self {
let #ty {
#(
#field_idents,
)*
..
} = config;
Self {
#(
#field_idents: From::<_>::from(#field_idents),
)*
}
}
}
};
out.into()
}
45 changes: 45 additions & 0 deletions config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,51 @@ pub mod derive {
/// assert_eq!(ip.ip, Ipv4Addr::new(127, 0, 0, 1));
/// ```
pub use iroha_config_derive::Configurable;
/// Derive macro for conversation between type and it's view which contains only subset of type's fields.
///
/// Works only with structs.
///
/// Assumptions:
/// - View's fields are subset of type's fields;
/// - Type implements `Default`.
///
/// ## Container attributes
///
/// ### `#[view(ViewType)]`
/// Sets container type view type.
///
/// ## Field attributes
/// ### `#[view(ignore)]`
/// Mark field to ignore it when converting to view type.
///
/// ## Examples
///
/// ```rust
/// use iroha_config::derive::View;
///
/// struct View {
/// a: u32,
/// }
///
/// #[derive(Default, View)]
/// #[view(View)]
/// struct Structure {
/// a: u32,
/// // `View` doesn't have field `b` so we must exclude it.
/// #[view(ignore)]
/// b: u32,
/// }
///
/// let view = View { a: 32 };
/// let structure: Structure = view.into();
/// assert_eq!(structure.a, 32);
/// assert_eq!(structure.b, u32::default());
///
/// let structure = Structure { a: 13, b: 37 };
/// let view: View = structure.into();
/// assert_eq!(view.a, 13);
/// ```
pub use iroha_config_derive::View;

/// Error related to deserializing specific field
#[derive(Debug, Display)]
Expand Down
4 changes: 2 additions & 2 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ default = ["bridge", "cli", "telemetry"]
# Interoperability with popular blockchain networks (Substrate, Ether, etc.)
bridge = []
# Support lightweight telemetry, including diagnostics
telemetry = []
telemetry = ["iroha_data_model/telemetry"]
# Support the included CLI
cli = []
# Support Decentralised Exchange, including functionality for atomic exchange instruction
dex = []
# Support developer-specific telemetry.
# Should not be enabled on production builds.
dev-telemetry = ["telemetry", "iroha_telemetry/dev-telemetry"]
dev-telemetry = ["telemetry", "iroha_telemetry/dev-telemetry", "iroha_data_model/dev-telemetry"]
# Support Prometheus metrics. See https://prometheus.io/.
expensive-telemetry = ["iroha_telemetry/metric-instrumentation"]

Expand Down
6 changes: 4 additions & 2 deletions core/src/block_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,18 +336,20 @@ pub mod message {

/// This module contains all configuration related logic.
pub mod config {
use iroha_config::derive::Configurable;
use iroha_config::derive::{Configurable, View};
use iroha_data_model::config::block_sync::Configuration as PublicBlockSyncConfiguration;
use serde::{Deserialize, Serialize};

const DEFAULT_BLOCK_BATCH_SIZE: u32 = 4;
const DEFAULT_GOSSIP_PERIOD_MS: u64 = 10000;
const DEFAULT_ACTOR_CHANNEL_CAPACITY: u32 = 100;

/// Configuration for `BlockSynchronizer`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Configurable)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Configurable, View)]
#[serde(rename_all = "UPPERCASE")]
#[serde(default)]
#[config(env_prefix = "BLOCK_SYNC_")]
#[view(PublicBlockSyncConfiguration)]
pub struct BlockSyncConfiguration {
/// The time between sending requests for latest block.
pub gossip_period_ms: u64,
Expand Down
7 changes: 5 additions & 2 deletions core/src/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,24 +325,27 @@ impl GenesisTransaction {

/// Module with genesis configuration logic.
pub mod config {
use iroha_config::derive::Configurable;
use iroha_config::derive::{Configurable, View};
use iroha_crypto::{KeyPair, PrivateKey, PublicKey};
use iroha_data_model::config::genesis::Configuration as PublicGenesisConfiguration;
use serde::{Deserialize, Serialize};

const DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT: u64 = 100;
const DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS: u64 = 500;
const DEFAULT_GENESIS_SUBMISSION_DELAY_MS: u64 = 1000;

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Configurable)]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Configurable, View)]
#[serde(default)]
#[serde(rename_all = "UPPERCASE")]
#[config(env_prefix = "IROHA_GENESIS_")]
#[view(PublicGenesisConfiguration)]
/// Configuration of the genesis block and the process of its submission.
pub struct GenesisConfiguration {
/// The genesis account public key, should be supplied to all peers.
#[config(serde_as_str)]
pub account_public_key: PublicKey,
/// Genesis account private key, only needed on the peer that submits the genesis block.
#[view(ignore)]
pub account_private_key: Option<PrivateKey>,
/// Number of attempts to connect to peers, while waiting for them to submit genesis.
#[serde(default = "default_wait_for_peers_retry_count_limit")]
Expand Down
Loading

0 comments on commit 961f602

Please sign in to comment.