From c94b8c88d73f398d46fc0d4de330c4286437a7fa Mon Sep 17 00:00:00 2001 From: Ilia Churin Date: Tue, 6 Sep 2022 22:19:24 +0900 Subject: [PATCH] [feature] #2627, #2589, #2614: Config finalisation, proxy entrypoint, kagami docgen Signed-off-by: Ilia Churin --- Cargo.lock | 1 + cli/src/lib.rs | 13 +- cli/src/samples.rs | 95 +++++------ client/src/client.rs | 53 ++++-- client/src/lib.rs | 30 ++-- client/tests/integration/config.rs | 18 +- client/tests/integration/mod.rs | 5 +- config/base/derive/src/documented.rs | 55 ++++-- config/base/derive/src/proxy.rs | 34 ++-- config/base/derive/src/utils.rs | 1 - config/base/derive/src/view.rs | 77 +++------ config/base/src/lib.rs | 18 +- config/src/block_sync.rs | 9 +- config/src/client.rs | 71 ++------ config/src/genesis.rs | 48 +----- config/src/iroha.rs | 128 +++++++++++--- config/src/kura.rs | 32 +--- config/src/logger.rs | 13 +- config/src/network.rs | 5 +- config/src/queue.rs | 11 +- config/src/sumeragi.rs | 82 ++++----- config/src/telemetry.rs | 23 +-- config/src/torii.rs | 13 +- config/src/wasm.rs | 10 +- config/src/wsv.rs | 19 ++- core/src/genesis.rs | 17 +- core/src/queue.rs | 45 +++-- core/src/smartcontracts/wasm.rs | 10 +- core/src/wsv.rs | 11 +- docs/source/references/config.md | 243 ++++++++++++--------------- futures/Cargo.toml | 1 + futures/tests/basic.rs | 13 +- logger/src/lib.rs | 2 +- logger/tests/setting_logger.rs | 16 +- logger/tests/telemetry.rs | 7 +- p2p/tests/integration/p2p.rs | 11 +- telemetry/src/ws.rs | 8 +- tools/kagami/src/main.rs | 7 +- 38 files changed, 661 insertions(+), 594 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a631e15f47a..98bd4b9005f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2105,6 +2105,7 @@ dependencies = [ name = "iroha_futures" version = "2.0.0-pre-rc.8" dependencies = [ + "iroha_config", "iroha_futures_derive", "iroha_logger", "rand 0.8.5", diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 72cb470c01b..9eb04e71f05 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -13,7 +13,10 @@ use std::{panic, path::PathBuf, sync::Arc}; use color_eyre::eyre::{eyre, Result, WrapErr}; use iroha_actor::{broker::*, prelude::*}; -use iroha_config::iroha::Configuration; +use iroha_config::{ + base::proxy::{LoadFromDisk, LoadFromEnv}, + iroha::{Configuration, ConfigurationProxy}, +}; use iroha_core::{ block_sync::{BlockSynchronizer, BlockSynchronizerTrait}, genesis::{GenesisNetwork, GenesisNetworkTrait, RawGenesisBlock}, @@ -124,11 +127,9 @@ where query_judge: QueryJudgeBoxed, ) -> Result { let broker = Broker::new(); - let mut config = match Configuration::from_path(&args.config_path) { - Ok(config) => config, - Err(_) => Configuration::default(), - }; - config.load_environment()?; + let mut proxy = ConfigurationProxy::from_path(&args.config_path)?; + proxy.load_environment()?; + let config = proxy.build()?; let telemetry = iroha_logger::init(&config.logger)?; iroha_logger::info!("Hyperledgerいろは2にようこそ!"); diff --git a/cli/src/samples.rs b/cli/src/samples.rs index fc5010715de..4b161fb046b 100644 --- a/cli/src/samples.rs +++ b/cli/src/samples.rs @@ -3,15 +3,9 @@ use std::{collections::HashSet, str::FromStr}; use iroha_config::{ - block_sync::Configuration as BlockSyncConfiguration, - genesis::Configuration as GenesisConfiguration, - iroha::Configuration, - kura::Configuration as KuraConfiguration, - queue::Configuration as QueueConfiguration, - sumeragi::{Configuration as SumeragiConfiguration, TrustedPeers}, - torii::{Configuration as ToriiConfiguration, DEFAULT_TORII_P2P_ADDR}, - wasm::Configuration as WasmConfiguration, - wsv::Configuration as WsvConfiguration, + iroha::{Configuration, ConfigurationProxy}, + sumeragi::TrustedPeers, + torii::{uri::DEFAULT_API_URL, DEFAULT_TORII_P2P_ADDR, DEFAULT_TORII_TELEMETRY_URL}, }; use iroha_crypto::{KeyPair, PublicKey}; use iroha_data_model::peer::Id as PeerId; @@ -65,48 +59,47 @@ pub fn get_config(trusted_peers: HashSet, key_pair: Option) -> .into(), }; iroha_logger::info!(?public_key); - Configuration { - public_key: public_key.clone(), - private_key: private_key.clone(), - kura: KuraConfiguration { - init_mode: iroha_config::kura::Mode::Strict, - ..KuraConfiguration::default() - }, - sumeragi: SumeragiConfiguration { - key_pair: KeyPair::new(public_key.clone(), private_key.clone()) - .expect("Key pair mismatch"), - peer_id: PeerId::new(DEFAULT_TORII_P2P_ADDR, &public_key), - trusted_peers: TrustedPeers { + ConfigurationProxy { + public_key: Some(public_key.clone()), + private_key: Some(private_key.clone()), + sumeragi: Some(iroha_config::sumeragi::ConfigurationProxy { + key_pair: None, + peer_id: None, + trusted_peers: Some(TrustedPeers { peers: trusted_peers, - }, - gossip_period_ms: 500, - ..SumeragiConfiguration::default() - }, - torii: ToriiConfiguration { - max_transaction_size: 0x8000, - ..ToriiConfiguration::default() - }, - block_sync: BlockSyncConfiguration { - block_batch_size: 1, - gossip_period_ms: 5000, - ..BlockSyncConfiguration::default() - }, - queue: QueueConfiguration { - maximum_transactions_in_block: 2, - ..QueueConfiguration::default() - }, - genesis: GenesisConfiguration { - account_public_key: public_key, - account_private_key: Some(private_key), - ..GenesisConfiguration::default() - }, - wsv: WsvConfiguration { - wasm_runtime_config: WasmConfiguration { - fuel_limit: 10_000_000, - ..WasmConfiguration::default() - }, - ..WsvConfiguration::default() - }, - ..Configuration::default() + }), + ..iroha_config::sumeragi::ConfigurationProxy::default() + }), + torii: Some(iroha_config::torii::ConfigurationProxy { + p2p_addr: Some(DEFAULT_TORII_P2P_ADDR.to_owned()), + api_url: Some(DEFAULT_API_URL.to_owned()), + telemetry_url: Some(DEFAULT_TORII_TELEMETRY_URL.to_owned()), + max_transaction_size: Some(0x8000), + ..iroha_config::torii::ConfigurationProxy::default() + }), + block_sync: Some(iroha_config::block_sync::ConfigurationProxy { + block_batch_size: Some(1), + gossip_period_ms: Some(500), + ..iroha_config::block_sync::ConfigurationProxy::default() + }), + queue: Some(iroha_config::queue::ConfigurationProxy { + maximum_transactions_in_block: Some(2), + ..iroha_config::queue::ConfigurationProxy::default() + }), + genesis: Some(iroha_config::genesis::ConfigurationProxy { + account_private_key: Some(Some(private_key)), + account_public_key: Some(public_key), + ..iroha_config::genesis::ConfigurationProxy::default() + }), + wsv: Some(iroha_config::wsv::ConfigurationProxy { + wasm_runtime_config: Some(iroha_config::wasm::ConfigurationProxy { + fuel_limit: Some(10_000_000), + ..iroha_config::wasm::ConfigurationProxy::default() + }), + ..iroha_config::wsv::ConfigurationProxy::default() + }), + ..ConfigurationProxy::default() } + .build() + .expect("Iroha config should build as all required fields were provided") } diff --git a/client/src/client.rs b/client/src/client.rs index 6999c70081c..45a1199555a 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1362,7 +1362,11 @@ mod tests { #![allow(clippy::restriction)] use std::str::FromStr; - use iroha_config::client::{BasicAuth, WebLogin}; + use iroha_config::{ + base::proxy::Builder, + client::{BasicAuth, ConfigurationProxy, WebLogin}, + torii::{uri::DEFAULT_API_URL, DEFAULT_TORII_TELEMETRY_URL}, + }; use super::*; @@ -1375,12 +1379,21 @@ mod tests { fn txs_same_except_for_nonce_have_different_hashes() { let (public_key, private_key) = KeyPair::generate().unwrap().into(); - let cfg = Configuration { - public_key, - private_key, - add_transaction_nonce: true, - ..Configuration::default() - }; + let cfg = ConfigurationProxy { + public_key: Some(public_key), + private_key: Some(private_key), + account_id: Some( + "alice@wonderland" + .parse() + .expect("Account ID should not fail"), + ), + torii_api_url: Some(SmallStr::from_str(DEFAULT_API_URL)), + torii_telemetry_url: Some(SmallStr::from_str(DEFAULT_TORII_TELEMETRY_URL)), + add_transaction_nonce: Some(true), + ..ConfigurationProxy::default() + } + .build() + .expect("Client config should build as all required fields were provided"); let client = Client::new(&cfg).expect("Invalid client configuration"); let build_transaction = || { @@ -1404,10 +1417,28 @@ mod tests { password: SmallStr::from_str(PASSWORD), }; - let cfg = Configuration { - basic_auth: Some(basic_auth), - ..Configuration::default() - }; + let cfg = ConfigurationProxy { + public_key: Some( + "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" + .parse() + .expect("Public key not in mulithash format"), + ), + private_key: Some(iroha_crypto::PrivateKey::from_hex( + iroha_crypto::Algorithm::Ed25519, + "9ac47abf59b356e0bd7dcbbbb4dec080e302156a48ca907e47cb6aea1d32719e7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" + ).expect("Private key not hex encoded")), + account_id: Some( + "alice@wonderland" + .parse() + .expect("Account ID should not fail"), + ), + torii_api_url: Some(SmallStr::from_str(DEFAULT_API_URL)), + torii_telemetry_url: Some(SmallStr::from_str(DEFAULT_TORII_TELEMETRY_URL)), + basic_auth: Some(Some(basic_auth)), + ..ConfigurationProxy::default() + } + .build() + .expect("Client config should build as all required fields were provided"); let client = Client::new(&cfg).expect("Invalid client configuration"); let value = client diff --git a/client/src/lib.rs b/client/src/lib.rs index 7b6aeeb82e5..68cf1d6180e 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1,7 +1,5 @@ //! Crate contains iroha client which talks to iroha network via http -pub use iroha_config::client::Configuration; - /// Module with iroha client itself pub mod client; /// Module with general communication primitives like an HTTP request builder. @@ -10,21 +8,31 @@ mod http_default; /// Module containing sample configurations for tests and benchmarks. pub mod samples { - use iroha_config::torii::uri; + use iroha_config::{ + base::proxy::Builder, + client::{Configuration, ConfigurationProxy}, + torii::{uri::DEFAULT_API_URL, DEFAULT_TORII_TELEMETRY_URL}, + }; use iroha_crypto::KeyPair; - - use super::Configuration; + use iroha_primitives::small::SmallStr; /// Get sample client configuration. #[allow(clippy::expect_used)] pub fn get_client_config(key_pair: &KeyPair) -> Configuration { let (public_key, private_key) = key_pair.clone().into(); - Configuration { - public_key, - private_key, - account_id: "alice@wonderland".parse().expect("Should not fail."), - torii_api_url: iroha_primitives::small::SmallStr::from_str(uri::DEFAULT_API_URL), - ..Configuration::default() + ConfigurationProxy { + public_key: Some(public_key), + private_key: Some(private_key), + account_id: Some( + "alice@wonderland" + .parse() + .expect("Account ID should not fail"), + ), + torii_api_url: Some(SmallStr::from_str(DEFAULT_API_URL)), + torii_telemetry_url: Some(SmallStr::from_str(DEFAULT_TORII_TELEMETRY_URL)), + ..ConfigurationProxy::default() } + .build() + .expect("Client config should build as all required fields were provided") } } diff --git a/client/tests/integration/config.rs b/client/tests/integration/config.rs index e01ce3e2244..ec1d1668a7f 100644 --- a/client/tests/integration/config.rs +++ b/client/tests/integration/config.rs @@ -2,7 +2,7 @@ use test_network::*; -use super::Configuration; +use super::{Builder, Configuration, ConfigurationProxy}; #[test] fn get_config() { @@ -13,10 +13,16 @@ fn get_config() { let field = test_client.get_config_docs(&["torii"]).unwrap().unwrap(); assert!(field.contains("IROHA_TORII")); - let cfg: Configuration = - serde_json::from_value(test_client.get_config_value().unwrap()).unwrap(); let test = Configuration::test(); - assert_eq!(cfg.block_sync, test.block_sync); - assert_eq!(cfg.network, test.network); - assert_eq!(cfg.telemetry, test.telemetry); + let cfg_proxy: ConfigurationProxy = + serde_json::from_value(test_client.get_config_value().unwrap()).unwrap(); + assert_eq!( + cfg_proxy.block_sync.unwrap().build().unwrap(), + test.block_sync + ); + assert_eq!(cfg_proxy.network.unwrap().build().unwrap(), test.network); + assert_eq!( + cfg_proxy.telemetry.unwrap().build().unwrap(), + test.telemetry + ); } diff --git a/client/tests/integration/mod.rs b/client/tests/integration/mod.rs index cbae044a513..e90670e3f98 100644 --- a/client/tests/integration/mod.rs +++ b/client/tests/integration/mod.rs @@ -1,4 +1,7 @@ -pub use iroha_config::iroha::Configuration; +pub use iroha_config::{ + base::proxy::Builder, + iroha::{Configuration, ConfigurationProxy}, +}; mod add_account; mod add_domain; diff --git a/config/base/derive/src/documented.rs b/config/base/derive/src/documented.rs index 069e1ae00e4..52dd8bb3c22 100644 --- a/config/base/derive/src/documented.rs +++ b/config/base/derive/src/documented.rs @@ -1,9 +1,9 @@ use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; -use syn::{Lit, LitStr, Meta}; +use syn::{parse_quote, Lit, LitStr, Meta, Path}; -use super::utils::StructWithFields; +use super::utils::{get_inner_type, StructWithFields}; pub fn impl_documented(ast: &StructWithFields) -> TokenStream { let name = &ast.ident; @@ -46,18 +46,29 @@ fn impl_get_doc_recursive(docs: Vec, ast: &StructWithFields) -> proc_mac .iter() .zip(docs) .map(|(field, documentation)| { - let inner_thing = field.has_inner; let ty = &field.ty; let ident = &field.ident; - if inner_thing { + let documented_trait: Path = parse_quote! { iroha_config_base::proxy::Documented }; + if field.has_inner && field.has_option { + let inner_ty = get_inner_type("Option", &field.ty); quote! { [stringify!(#ident)] => { let curr_doc = #documentation; - let inner_docs = <#ty as ::iroha_config_base::proxy::Documented>::get_inner_docs(); + let inner_docs = <#inner_ty as #documented_trait>::get_inner_docs(); let total_docs = format!("{}\n\nHas following fields:\n\n{}\n", curr_doc, inner_docs); Some(total_docs) }, - [stringify!(#ident), rest @ ..] => <#ty as ::iroha_config_base::proxy::Documented>::get_doc_recursive(rest)?, + [stringify!(#ident), rest @ ..] => <#inner_ty as #documented_trait>::get_doc_recursive(rest)?, + } + } else if field.has_inner { + quote! { + [stringify!(#ident)] => { + let curr_doc = #documentation; + let inner_docs = <#ty as #documented_trait>::get_inner_docs(); + let total_docs = format!("{}\n\nHas following fields:\n\n{}\n", curr_doc, inner_docs); + Some(total_docs) + }, + [stringify!(#ident), rest @ ..] => <#ty as #documented_trait>::get_doc_recursive(rest)?, } } else { quote! { [stringify!(#ident)] => Some(#documentation.to_owned()), } @@ -83,11 +94,16 @@ fn impl_get_doc_recursive(docs: Vec, ast: &StructWithFields) -> proc_mac fn impl_get_inner_docs(docs: Vec, ast: &StructWithFields) -> proc_macro2::TokenStream { let inserts = ast.fields.iter().zip(docs).map(|(field, documentation)| { - let inner_thing = field.has_inner; let ty = &field.ty; let ident = &field.ident; - let doc = if inner_thing { - quote! { <#ty as ::iroha_config_base::proxy::Documented>::get_inner_docs().as_str() } + let documented_trait: Path = parse_quote! { ::iroha_config_base::proxy::Documented }; + let doc = if field.has_inner && field.has_option { + let inner_ty = get_inner_type("Option", &field.ty); + quote! { + <#inner_ty as #documented_trait>::get_inner_docs().as_str() + } + } else if field.has_inner { + quote! { <#ty as #documented_trait>::get_inner_docs().as_str() } } else { quote! { #documentation.into() } }; @@ -113,9 +129,12 @@ fn impl_get_docs(docs: Vec, ast: &StructWithFields) -> proc_macro2::Toke let inserts = ast.fields.iter().zip(docs).map(|(field, documentation)| { let ident = &field.ident; let ty = &field.ty; - let inner_thing = field.has_inner; - let doc = if inner_thing { - quote! { <#ty as ::iroha_config_base::proxy::Documented>::get_docs().into() } + let documented_trait: Path = parse_quote! { iroha_config_base::proxy::Documented }; + let doc = if field.has_inner && field.has_option { + let inner_ty = get_inner_type("Option", &field.ty); + quote! { <#inner_ty as #documented_trait>::get_docs().into() } + } else if field.has_inner { + quote! { <#ty as #documented_trait>::get_docs().into() } } else { quote! { #documentation.into() } }; @@ -152,10 +171,18 @@ fn impl_get_recursive(ast: &StructWithFields) -> proc_macro2::TokenStream { let variants = ast.fields .iter() .map(|field | { - let inner_thing = field.has_inner; + // if ast.ident == "ConfigurationProxy" {println!("FIELD: {}, INNER: {}, OPTION: {}", field.ident, field.has_inner, field.has_option);} let ident = &field.ident; let l_value = &field.lvalue_read; - let inner_thing2 = if inner_thing { + let inner_thing2 = if field.has_inner && field.has_option { + let inner_ty = get_inner_type("Option", &field.ty); + let documented_trait: Path = parse_quote! { iroha_config_base::proxy::Documented }; + quote! { + [stringify!(#ident), rest @ ..] => { + <#inner_ty as #documented_trait>::get_recursive(#l_value.as_ref().expect("Should be instantiated"), rest)? + }, + } + } else if field.has_inner { quote! { [stringify!(#ident), rest @ ..] => { #l_value.get_recursive(rest)? diff --git a/config/base/derive/src/proxy.rs b/config/base/derive/src/proxy.rs index 37d0019beeb..8f0c0a8644e 100644 --- a/config/base/derive/src/proxy.rs +++ b/config/base/derive/src/proxy.rs @@ -7,23 +7,27 @@ use crate::utils; pub fn impl_proxy(ast: StructWithFields) -> TokenStream { // somewhat awkward conversion, could it be better? - let parent_name = ast.ident.clone(); + let parent_name = &ast.ident; let parent_ty: Type = parse_quote! { #parent_name }; let proxy_struct = gen_proxy_struct(ast); let loadenv_derive = quote! { ::iroha_config_base::derive::LoadFromEnv }; let disk_derive = quote! { ::iroha_config_base::derive::LoadFromDisk }; let builder_derive = quote! { ::iroha_config_base::derive::Builder }; let combine_derive = quote! { ::iroha_config_base::derive::Combine }; + let documented_derive = quote! { ::iroha_config_base::derive::Documented }; quote! { /// Proxy configuration structure to be used as an intermediate /// for config loading - #[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, + #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, #builder_derive, #loadenv_derive, #disk_derive, - #combine_derive)] + #combine_derive, + #documented_derive + )] #[builder(parent = #parent_ty)] #proxy_struct + } .into() } @@ -128,9 +132,12 @@ pub fn impl_load_from_disk(ast: &StructWithFields) -> TokenStream { impl #disk_trait for #proxy_name { type Error = #error_ty; fn from_path + std::fmt::Debug + Clone>(path: P) -> Result { - let file = std::fs::File::open(path)?; - let reader = std::io::BufReader::new(file); - serde_json::from_reader(reader)? + let mut file = std::fs::File::open(path)?; + // String has better parsing speed, see [issue](https://github.com/serde-rs/json/issues/160#issuecomment-253446892) + let mut s = String::new(); + std::io::Read::read_to_string(&mut file, &mut s)?; + let res: Self = serde_json::from_str(&s)?; + Ok(res) } } }.into() @@ -154,13 +161,20 @@ fn gen_proxy_struct(mut ast: StructWithFields) -> StructWithFields { field.ty = parse_quote! { Option<#ty> }; + // Fields that already wrap an option should have a + // custom deserializer so that json `null` becomes + // `Some(None)` and not just `None` + if field.has_option { + let de_helper = stringify! { ::iroha_config_base::proxy::some_option }; + let serde_attr: syn::Attribute = + parse_quote! { #[serde(default, deserialize_with = #de_helper)] }; + field.attrs.push(serde_attr); + } field.has_option = true; - // Also remove `#[serde(default = ..)]` if present - // as it breaks proxy deserialization - utils::remove_attr(&mut field.attrs, "serde"); }); ast.ident = format_ident!("{}Proxy", ast.ident); - // Removing as `..Proxy` has its own doc + // Removing struct-level docs as `..Proxy` has its own doc, + // but not the field documentation as they stay the same utils::remove_attr(&mut ast.attrs, "doc"); ast } diff --git a/config/base/derive/src/utils.rs b/config/base/derive/src/utils.rs index af2e8f718ae..7b835d0be5a 100644 --- a/config/base/derive/src/utils.rs +++ b/config/base/derive/src/utils.rs @@ -244,7 +244,6 @@ impl Parse for StructWithFields { .map(|field| StructField::from_ast(field, &env_prefix)) .collect(), env_prefix, - // parent_ty, _semi_token: input.parse()?, }) } diff --git a/config/base/derive/src/view.rs b/config/base/derive/src/view.rs index 759c9809194..f3ae0de2d53 100644 --- a/config/base/derive/src/view.rs +++ b/config/base/derive/src/view.rs @@ -12,7 +12,6 @@ pub fn impl_view(ast: StructWithFields) -> TokenStream { let original = original_struct(ast.clone()); let view = view_struct(ast); let impl_from = impl_from(&original, &view); - let impl_default = impl_default(&original, &view); let impl_has_view = impl_has_view(&original); let assertions = assertions(&view); let out = quote! { @@ -20,7 +19,6 @@ pub fn impl_view(ast: StructWithFields) -> TokenStream { #impl_has_view #view #impl_from - #impl_default #assertions }; out.into() @@ -46,8 +44,6 @@ mod gen { ast.attrs.push(syn::parse_quote!( #[doc = #view_doc] )); - // TODO: Remove `Default` from #[derive(..., Default, ...)] or #[derive(Default)] because we implement `Default` inside macro - // TODO: also add info with remove proxy ast.attrs .iter_mut() .filter(|attr| attr.path.is_ident("derive")) @@ -55,36 +51,31 @@ mod gen { let meta = attr .parse_meta() .expect("derive macro must be in one of the meta forms"); - match meta { - Meta::List(list) => { - let items: Vec = list - .nested - .into_iter() - .filter(|nested| { - if let NestedMeta::Meta(Meta::Path(path)) = nested { - // TODO: check here - if path.is_ident("Default") - || path.is_ident("Documented") - || path.is_ident("Proxy") - { - return false; - } + if let Meta::List(list) = meta { + let items: Vec = list + .nested + .into_iter() + .filter(|nested| { + if let NestedMeta::Meta(Meta::Path(path)) = nested { + // remove derives that are needed on the `Configuration` + // or `ConfigurationProxy`, but not needed on `ConfigruationView` + if path.is_ident("LoadFromEnv") + || path.is_ident("Builder") + || path.is_ident("Proxy") + { + return false; } - true - }) - .collect(); - *attr = syn::parse_quote!( - #[derive(#(#items),*)] - ) - } - Meta::Path(path) if path.is_ident("Default") => { - *attr = syn::parse_quote!( - #[derive()] - ) - } - _ => {} + } + true + }) + .collect(); + *attr = syn::parse_quote!( + #[derive(#(#items),*)] + ) } }); + // TODO: Find a way to make this more ergonomic. As `View` struct + // are formed inside a proc macro, we have to remove unrelated attributes from `Configuration` here. remove_attr_struct(&mut ast, "view"); remove_attr_struct(&mut ast, "config"); remove_attr_struct(&mut ast, "builder"); @@ -128,30 +119,6 @@ mod gen { } } - pub fn impl_default( - original: &StructWithFields, - view: &StructWithFields, - ) -> proc_macro2::TokenStream { - let StructWithFields { - ident: original_ident, - .. - } = original; - let StructWithFields { - generics, - ident: view_ident, - .. - } = view; - let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - - quote! { - impl #impl_generics core::default::Default for #view_ident #ty_generics #where_clause { - fn default() -> Self { - core::convert::From::<_>::from(<#original_ident as core::default::Default>::default()) - } - } - } - } - pub fn impl_has_view(original: &StructWithFields) -> proc_macro2::TokenStream { let StructWithFields { generics, diff --git a/config/base/src/lib.rs b/config/base/src/lib.rs index 01e989e03b8..279a7fab7b4 100644 --- a/config/base/src/lib.rs +++ b/config/base/src/lib.rs @@ -2,7 +2,7 @@ #![allow(clippy::std_instead_of_core)] use std::{fmt::Debug, path::Path}; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize}; use serde_json::Value; pub mod derive { @@ -183,7 +183,7 @@ pub mod derive { #[serde(skip)] FieldError(#[from] FieldError), /// Used in [`Combine`] trait for build errors - #[error("Proxy field was [`None`] at build stage: {0}")] + #[error("Proxy failed at build stage due to: {0}")] ProxyBuildError(String), /// Used in the [`LoadFromDisk`](`crate::proxy::LoadFromDisk`) trait for file read errors #[error("Reading file from disk failed: {0}")] @@ -329,4 +329,18 @@ pub mod proxy { /// Construct [`Self::ReturnValue`] from a proxy object. fn build(self) -> Self::ReturnValue; } + + /// Deserialization helper for proxy fields that wrap an `Option` + /// + /// # Errors + /// When deserialization of the field fails, e.g. it doesn't have + /// the `Option>` + #[allow(clippy::option_option)] + pub fn some_option<'de, T, D>(deserializer: D) -> Result>, D::Error> + where + T: Deserialize<'de>, + D: Deserializer<'de>, + { + Option::::deserialize(deserializer).map(Some) + } } diff --git a/config/src/block_sync.rs b/config/src/block_sync.rs index f3a483511e0..e45ecfeced9 100644 --- a/config/src/block_sync.rs +++ b/config/src/block_sync.rs @@ -12,7 +12,6 @@ const DEFAULT_ACTOR_CHANNEL_CAPACITY: u32 = 100; Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv, )] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] #[config(env_prefix = "BLOCK_SYNC_")] pub struct Configuration { /// The period of time to wait between sending requests for the latest block. @@ -24,12 +23,12 @@ pub struct Configuration { pub actor_channel_capacity: u32, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - gossip_period_ms: DEFAULT_GOSSIP_PERIOD_MS, - block_batch_size: DEFAULT_BLOCK_BATCH_SIZE, - actor_channel_capacity: DEFAULT_ACTOR_CHANNEL_CAPACITY, + gossip_period_ms: Some(DEFAULT_GOSSIP_PERIOD_MS), + block_batch_size: Some(DEFAULT_BLOCK_BATCH_SIZE), + actor_channel_capacity: Some(DEFAULT_ACTOR_CHANNEL_CAPACITY), } } } diff --git a/config/src/client.rs b/config/src/client.rs index a00be406dbd..cd7ef3d2d39 100644 --- a/config/src/client.rs +++ b/config/src/client.rs @@ -1,18 +1,15 @@ //! Module for client-related configuration and structs #![allow(clippy::std_instead_of_core, clippy::std_instead_of_alloc)] -use std::{fmt, fs::File, io::BufReader, path::Path, str::FromStr}; +use std::str::FromStr; use derive_more::Display; -use eyre::{eyre, Result, WrapErr}; +use eyre::{eyre, Result}; use iroha_config_base::derive::{Documented, LoadFromEnv, Proxy}; use iroha_crypto::prelude::*; use iroha_data_model::{prelude::*, transaction}; use iroha_primitives::small::SmallStr; use serde::{Deserialize, Serialize}; -use crate::torii::uri; - -const DEFAULT_TORII_TELEMETRY_URL: &str = "127.0.0.1:8180"; const DEFAULT_TRANSACTION_TIME_TO_LIVE_MS: u64 = 100_000; const DEFAULT_TRANSACTION_STATUS_TIMEOUT_MS: u64 = 10_000; const DEFAULT_ADD_TRANSACTION_NONCE: bool = false; @@ -65,7 +62,6 @@ pub struct BasicAuth { /// `Configuration` provides an ability to define client parameters such as `TORII_URL`. #[derive(Debug, Clone, Deserialize, Serialize, Proxy, LoadFromEnv, Documented)] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] #[config(env_prefix = "IROHA_")] pub struct Configuration { /// Public key of the user account. @@ -91,61 +87,22 @@ pub struct Configuration { pub add_transaction_nonce: bool, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { - let (public_key, private_key) = Self::placeholder_keypair().into(); - Self { - public_key, - private_key, - account_id: Self::placeholder_account(), - basic_auth: None, - torii_api_url: SmallStr::from_str(uri::DEFAULT_API_URL), - torii_telemetry_url: SmallStr::from_str(DEFAULT_TORII_TELEMETRY_URL), - transaction_time_to_live_ms: DEFAULT_TRANSACTION_TIME_TO_LIVE_MS, - transaction_status_timeout_ms: DEFAULT_TRANSACTION_STATUS_TIMEOUT_MS, - transaction_limits: TransactionLimits { + public_key: None, + private_key: None, + account_id: None, + basic_auth: Some(None), + torii_api_url: None, + torii_telemetry_url: None, + transaction_time_to_live_ms: Some(DEFAULT_TRANSACTION_TIME_TO_LIVE_MS), + transaction_status_timeout_ms: Some(DEFAULT_TRANSACTION_STATUS_TIMEOUT_MS), + transaction_limits: Some(TransactionLimits { max_instruction_number: transaction::DEFAULT_MAX_INSTRUCTION_NUMBER, max_wasm_size_bytes: transaction::DEFAULT_MAX_WASM_SIZE_BYTES, - }, - add_transaction_nonce: DEFAULT_ADD_TRANSACTION_NONCE, + }), + add_transaction_nonce: Some(DEFAULT_ADD_TRANSACTION_NONCE), } } } - -impl Configuration { - /// Key-pair used by default for demo purposes - #[allow(clippy::expect_used)] - fn placeholder_keypair() -> KeyPair { - let public_key = "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - .parse() - .expect("Public key not in mulithash format"); - let private_key = PrivateKey::from_hex( - Algorithm::Ed25519, - "9ac47abf59b356e0bd7dcbbbb4dec080e302156a48ca907e47cb6aea1d32719e7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" - ).expect("Private key not hex encoded"); - - KeyPair::new(public_key, private_key).expect("Key pair mismatch") - } - - /// Account ID used by default for demo purposes - #[allow(clippy::expect_used)] - fn placeholder_account() -> ::Id { - AccountId::from_str("alice@wonderland").expect("Account ID not valid") - } - - // TODO: Delete this after `LoadFromDisk` is implemented - /// This method will build `Configuration` from a json *pretty* formatted file (without `:` in - /// key names). - /// - /// # Panics - /// If configuration file present, but has incorrect format. - /// - /// # Errors - /// If system fails to find a file or read it's content. - pub fn from_path + fmt::Debug>(path: P) -> Result { - let file = File::open(path).wrap_err("Failed to open the config file")?; - let reader = BufReader::new(file); - serde_json::from_reader(reader).wrap_err("Failed to deserialize json from reader") - } -} diff --git a/config/src/genesis.rs b/config/src/genesis.rs index f23b46b09c2..c1c8182ab6e 100644 --- a/config/src/genesis.rs +++ b/config/src/genesis.rs @@ -2,7 +2,7 @@ #![allow(clippy::std_instead_of_core)] use iroha_config_base::derive::{view, Documented, LoadFromEnv, Proxy}; -use iroha_crypto::{KeyPair, PrivateKey, PublicKey}; +use iroha_crypto::{PrivateKey, PublicKey}; use serde::{Deserialize, Serialize}; const DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT: u64 = 100; @@ -13,7 +13,6 @@ const DEFAULT_GENESIS_SUBMISSION_DELAY_MS: u64 = 1000; view! { /// Configuration of the genesis block and the process of its submission. #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv)] - #[serde(default)] #[serde(rename_all = "UPPERCASE")] #[config(env_prefix = "IROHA_GENESIS_")] pub struct Configuration { @@ -24,56 +23,23 @@ view! { #[view(ignore)] pub account_private_key: Option, /// The number of attempts to connect to peers while waiting for them to submit genesis. - #[serde(default = "default_wait_for_peers_retry_count_limit")] pub wait_for_peers_retry_count_limit: u64, /// The period in milliseconds in which to retry connecting to peers while waiting for them to submit genesis. - #[serde(default = "default_wait_for_peers_retry_period_ms")] pub wait_for_peers_retry_period_ms: u64, /// The delay before genesis block submission after minimum number of peers were discovered to be online. /// The delay between submissions, which is used to ensure that other peers had time to connect to each other. - #[serde(default = "default_genesis_submission_delay_ms")] pub genesis_submission_delay_ms: u64, } } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { - let (public_key, private_key) = Self::placeholder_keypair().into(); - Self { - account_public_key: public_key, - account_private_key: Some(private_key), - wait_for_peers_retry_count_limit: DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT, - wait_for_peers_retry_period_ms: DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS, - genesis_submission_delay_ms: DEFAULT_GENESIS_SUBMISSION_DELAY_MS, + account_public_key: None, + account_private_key: Some(None), + wait_for_peers_retry_count_limit: Some(DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT), + wait_for_peers_retry_period_ms: Some(DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS), + genesis_submission_delay_ms: Some(DEFAULT_GENESIS_SUBMISSION_DELAY_MS), } } } - -impl Configuration { - /// Key-pair used by default for demo purposes - #[allow(clippy::expect_used)] - fn placeholder_keypair() -> KeyPair { - let public_key = "ed01204cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" - .parse() - .expect("Public key not in mulithash format"); - let private_key = PrivateKey::from_hex( - iroha_crypto::Algorithm::Ed25519, - "d748e18ce60cb30dea3e73c9019b7af45a8d465e3d71bcc9a5ef99a008205e534cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" - ).expect("Private key not hex encoded"); - - KeyPair::new(public_key, private_key).expect("Key pair mismatch") - } -} - -const fn default_wait_for_peers_retry_count_limit() -> u64 { - DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT -} - -const fn default_wait_for_peers_retry_period_ms() -> u64 { - DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS -} - -const fn default_genesis_submission_delay_ms() -> u64 { - DEFAULT_GENESIS_SUBMISSION_DELAY_MS -} diff --git a/config/src/iroha.rs b/config/src/iroha.rs index c296b41fd20..48345432120 100644 --- a/config/src/iroha.rs +++ b/config/src/iroha.rs @@ -3,7 +3,10 @@ use std::{fmt::Debug, fs::File, io::BufReader, path::Path}; use eyre::{Result, WrapErr}; -use iroha_config_base::derive::{view, Documented, LoadFromEnv, Proxy}; +use iroha_config_base::{ + derive::{view, Documented, Error as ConfigError, LoadFromEnv, Proxy}, + proxy::Builder, +}; use iroha_crypto::prelude::*; use serde::{Deserialize, Serialize}; @@ -12,8 +15,7 @@ use super::*; // Generate `ConfigurationView` without the private key view! { /// Configuration parameters for a peer - #[derive(Debug, Clone, Deserialize, Serialize, Proxy, LoadFromEnv, Documented)] - #[serde(default)] + #[derive(Debug, Clone, Deserialize, Serialize, Proxy, Documented, LoadFromEnv)] #[serde(rename_all = "UPPERCASE")] #[config(env_prefix = "IROHA_")] pub struct Configuration { @@ -60,26 +62,101 @@ view! { } } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { - let sumeragi_configuration = sumeragi::Configuration::default(); - let (public_key, private_key) = sumeragi_configuration.key_pair.clone().into(); - Self { - public_key, - private_key, - disable_panic_terminal_colors: bool::default(), - kura: kura::Configuration::default(), - sumeragi: sumeragi_configuration, - torii: torii::Configuration::default(), - block_sync: block_sync::Configuration::default(), - queue: queue::Configuration::default(), - logger: logger::Configuration::default(), - genesis: genesis::Configuration::default(), - wsv: wsv::Configuration::default(), - network: network::Configuration::default(), - telemetry: telemetry::Configuration::default(), + public_key: None, + private_key: None, + disable_panic_terminal_colors: Some(bool::default()), + kura: Some(kura::ConfigurationProxy::default()), + sumeragi: Some(sumeragi::ConfigurationProxy::default()), + torii: Some(torii::ConfigurationProxy::default()), + block_sync: Some(block_sync::ConfigurationProxy::default()), + queue: Some(queue::ConfigurationProxy::default()), + logger: Some(logger::ConfigurationProxy::default()), + genesis: Some(genesis::ConfigurationProxy::default()), + wsv: Some(wsv::ConfigurationProxy::default()), + network: Some(network::ConfigurationProxy::default()), + telemetry: Some(telemetry::ConfigurationProxy::default()), + } + } +} + +impl ConfigurationProxy { + /// Finalisation of Iroha config proxy by instantiating mutually equivalent fields + /// via the uppermost Iroha config fields. Configuration fields provided in the + /// Iroha config always overwrite those in sumeragi even in case of discrepancy, + /// so proper care is advised. + /// + /// # Errors + /// - If the relevant uppermost Iroha config fields were not provided. + #[allow(clippy::expect_used, clippy::unwrap_in_result)] + pub fn finalize(&mut self) -> Result<()> { + if let Some(sumeragi_proxy) = &mut self.sumeragi { + // First, iroha public/private key and sumeragi keypair are interchangeable, but + // the user is allowed to provide only the former, and keypair is generated automatically, + // bailing out if key_pair provided in sumeragi no matter its value + if sumeragi_proxy.key_pair.is_some() { + eyre::bail!(ConfigError::ProxyBuildError( + "Sumeragi should not be provided with `key_pair` directly as it is instantiated via Iroha config" + .to_owned())) + } + if let (Some(public_key), Some(private_key)) = (&self.public_key, &self.private_key) { + sumeragi_proxy.key_pair = + Some(KeyPair::new(public_key.clone(), private_key.clone())?); + } else { + eyre::bail!(ConfigError::ProxyBuildError( + "Iroha public and private key not supplied, instantiating sumeragi keypair is impossible" + .to_owned() + )) + } + // Second, torii gateway and sumeragi peer id are interchangeable too; the latter is derived from the + // former and overwritten silently in case of difference + if let Some(torii_proxy) = &mut self.torii { + if sumeragi_proxy.peer_id.is_none() { + sumeragi_proxy.peer_id = Some(iroha_data_model::peer::Id::new( + &torii_proxy.p2p_addr.clone().ok_or_else(|| { + eyre::eyre!("Torii `p2p_addr` field has `None` value") + })?, + &self.public_key.clone().expect( + "Iroha `public_key` should have been initialized above at the latest", + ), + )); + } else { + eyre::bail!(ConfigError::ProxyBuildError( + "Sumeragi should not be provided with `peer_id` directly".to_owned() + )) + } + } else { + eyre::bail!(ConfigError::ProxyBuildError( + "Torii config should have at least `p2p_addr` provided for sumeragi finalisation" + .to_owned() + )) + } + // Finally, if trusted peers were not supplied, we can fall back to inserting itself as + // the only trusted one + if sumeragi_proxy.trusted_peers.is_none() { + sumeragi_proxy.insert_self_as_trusted_peers() + } } + + Ok(()) + } + + /// Wrapper around for the topmost Iroha `ConfigurationProxy` + /// that performs finalisation prior to building. For the uppermost + /// Iroha config, its `::build()` + /// method should never be used directly, as only this wrapper ensures final + /// coherence. + /// + /// # Errors + /// - Finalisation fails + /// - Any of the inner fields had a `None` value when that + /// is not allowed by the defaults. + pub fn build(mut self) -> Result { + self.finalize()?; + ::build(self) + .wrap_err("Failed to build `Configuration` from `ConfigurationProxy`") } } @@ -128,16 +205,19 @@ mod tests { #![allow(clippy::restriction)] use super::*; - use crate::sumeragi::TrustedPeers; + use crate::{base::proxy::LoadFromDisk, sumeragi::TrustedPeers}; const CONFIGURATION_PATH: &str = "../configs/peer/config.json"; #[test] fn parse_example_json() -> Result<()> { - let configuration = Configuration::from_path(CONFIGURATION_PATH) + let cfg_proxy = ConfigurationProxy::from_path(CONFIGURATION_PATH) .wrap_err("Failed to read configuration from example config")?; - assert_eq!("127.0.0.1:1337", configuration.torii.p2p_addr); - assert_eq!(1000, configuration.sumeragi.block_time_ms); + assert_eq!("127.0.0.1:1337", cfg_proxy.torii.unwrap().p2p_addr.unwrap()); + assert_eq!( + 10000, + cfg_proxy.block_sync.unwrap().gossip_period_ms.unwrap() + ); Ok(()) } diff --git a/config/src/kura.rs b/config/src/kura.rs index 74453f2a9dc..cf717ed6b77 100644 --- a/config/src/kura.rs +++ b/config/src/kura.rs @@ -16,26 +16,26 @@ const DEFAULT_ACTOR_CHANNEL_CAPACITY: u32 = 100; #[config(env_prefix = "KURA_")] pub struct Configuration { /// Initialization mode: `strict` or `fast`. - #[serde(default)] pub init_mode: Mode, /// Path to the existing block store folder or path to create new folder. - #[serde(default = "default_block_store_path")] pub block_store_path: String, /// Maximum number of blocks to write into a single storage file. - #[serde(default = "default_blocks_per_storage_file")] pub blocks_per_storage_file: NonZeroU64, /// Default buffer capacity of actor's MPSC channel. - #[serde(default = "default_actor_channel_capacity")] pub actor_channel_capacity: u32, } -impl Default for Configuration { +impl Default for ConfigurationProxy { + #[allow(clippy::expect_used)] fn default() -> Self { Self { - init_mode: Mode::default(), - block_store_path: default_block_store_path(), - blocks_per_storage_file: default_blocks_per_storage_file(), - actor_channel_capacity: default_actor_channel_capacity(), + init_mode: Some(Mode::default()), + block_store_path: Some(DEFAULT_BLOCK_STORE_PATH.to_owned()), + blocks_per_storage_file: Some( + NonZeroU64::new(DEFAULT_BLOCKS_PER_STORAGE_FILE) + .expect("BLOCKS_PER_STORAGE cannot be set to a non-positive value."), + ), + actor_channel_capacity: Some(DEFAULT_ACTOR_CHANNEL_CAPACITY), } } } @@ -54,20 +54,6 @@ impl Configuration { } } -fn default_block_store_path() -> String { - DEFAULT_BLOCK_STORE_PATH.to_owned() -} - -fn default_blocks_per_storage_file() -> NonZeroU64 { - #![allow(clippy::expect_used)] - NonZeroU64::new(DEFAULT_BLOCKS_PER_STORAGE_FILE) - .expect("BLOCKS_PER_STORAGE cannot be set to a non-positive value.") -} - -const fn default_actor_channel_capacity() -> u32 { - DEFAULT_ACTOR_CHANNEL_CAPACITY -} - /// Kura initialization mode. #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] diff --git a/config/src/logger.rs b/config/src/logger.rs index 98114fe2bb5..cbbed124bac 100644 --- a/config/src/logger.rs +++ b/config/src/logger.rs @@ -80,7 +80,6 @@ impl From for SyncLevel { /// 'Logger' configuration. #[derive(Clone, Deserialize, Serialize, Debug, Proxy, LoadFromEnv, Documented)] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] pub struct Configuration { /// Maximum log level #[config(serde_as_str)] @@ -96,14 +95,14 @@ pub struct Configuration { pub terminal_colors: bool, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - max_log_level: SyncLevel::default(), - telemetry_capacity: TELEMETRY_CAPACITY, - compact_mode: DEFAULT_COMPACT_MODE, - log_file_path: None, - terminal_colors: DEFAULT_TERMINAL_COLORS, + max_log_level: Some(SyncLevel::default()), + telemetry_capacity: Some(TELEMETRY_CAPACITY), + compact_mode: Some(DEFAULT_COMPACT_MODE), + log_file_path: Some(None), + terminal_colors: Some(DEFAULT_TERMINAL_COLORS), } } } diff --git a/config/src/network.rs b/config/src/network.rs index b0db1a4f0cb..b76e82cec1b 100644 --- a/config/src/network.rs +++ b/config/src/network.rs @@ -9,7 +9,6 @@ const DEFAULT_ACTOR_CHANNEL_CAPACITY: u32 = 100; #[derive( Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv, )] -#[serde(default)] #[serde(rename_all = "UPPERCASE")] #[config(env_prefix = "IROHA_NETWORK_")] pub struct Configuration { @@ -17,10 +16,10 @@ pub struct Configuration { pub actor_channel_capacity: u32, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - actor_channel_capacity: DEFAULT_ACTOR_CHANNEL_CAPACITY, + actor_channel_capacity: Some(DEFAULT_ACTOR_CHANNEL_CAPACITY), } } } diff --git a/config/src/queue.rs b/config/src/queue.rs index 6e92852f922..78b02befb3c 100644 --- a/config/src/queue.rs +++ b/config/src/queue.rs @@ -14,7 +14,6 @@ const DEFAULT_FUTURE_THRESHOLD_MS: u64 = 1000; Copy, Clone, Deserialize, Serialize, Debug, Documented, Proxy, LoadFromEnv, PartialEq, Eq, )] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] #[config(env_prefix = "QUEUE_")] pub struct Configuration { /// The upper limit of the number of transactions per block. @@ -27,13 +26,13 @@ pub struct Configuration { pub future_threshold_ms: u64, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - maximum_transactions_in_block: DEFAULT_MAXIMUM_TRANSACTIONS_IN_BLOCK, - maximum_transactions_in_queue: DEFAULT_MAXIMUM_TRANSACTIONS_IN_QUEUE, - transaction_time_to_live_ms: DEFAULT_TRANSACTION_TIME_TO_LIVE_MS, - future_threshold_ms: DEFAULT_FUTURE_THRESHOLD_MS, + maximum_transactions_in_block: Some(DEFAULT_MAXIMUM_TRANSACTIONS_IN_BLOCK), + maximum_transactions_in_queue: Some(DEFAULT_MAXIMUM_TRANSACTIONS_IN_QUEUE), + transaction_time_to_live_ms: Some(DEFAULT_TRANSACTION_TIME_TO_LIVE_MS), + future_threshold_ms: Some(DEFAULT_FUTURE_THRESHOLD_MS), } } } diff --git a/config/src/sumeragi.rs b/config/src/sumeragi.rs index 77098267dc4..d534a6fb246 100644 --- a/config/src/sumeragi.rs +++ b/config/src/sumeragi.rs @@ -24,13 +24,12 @@ view! { /// `Sumeragi` configuration. /// [`struct@Configuration`] provides an ability to define parameters such as `BLOCK_TIME_MS` /// and a list of `TRUSTED_PEERS`. - #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv)] - #[serde(default)] + #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Proxy, Documented, LoadFromEnv)] #[serde(rename_all = "UPPERCASE")] #[config(env_prefix = "SUMERAGI_")] pub struct Configuration { /// The key pair consisting of a private and a public key. - #[serde(skip)] + //TODO: consider putting a `#[serde(skip)]` on the proxy struct here #[view(ignore)] pub key_pair: KeyPair, /// Current Peer Identification. @@ -54,63 +53,44 @@ view! { } } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - key_pair: Self::placeholder_keypair(), - peer_id: Self::placeholder_peer_id(), - trusted_peers: Self::placeholder_trusted_peers(), - block_time_ms: DEFAULT_BLOCK_TIME_MS, - commit_time_limit_ms: DEFAULT_COMMIT_TIME_LIMIT_MS, - tx_receipt_time_limit_ms: DEFAULT_TX_RECEIPT_TIME_LIMIT_MS, - transaction_limits: TransactionLimits { + key_pair: None, + peer_id: None, + trusted_peers: None, + block_time_ms: Some(DEFAULT_BLOCK_TIME_MS), + commit_time_limit_ms: Some(DEFAULT_COMMIT_TIME_LIMIT_MS), + tx_receipt_time_limit_ms: Some(DEFAULT_TX_RECEIPT_TIME_LIMIT_MS), + transaction_limits: Some(TransactionLimits { max_instruction_number: transaction::DEFAULT_MAX_INSTRUCTION_NUMBER, max_wasm_size_bytes: transaction::DEFAULT_MAX_WASM_SIZE_BYTES, - }, - actor_channel_capacity: DEFAULT_ACTOR_CHANNEL_CAPACITY, - gossip_batch_size: DEFAULT_GOSSIP_BATCH_SIZE, - gossip_period_ms: DEFAULT_GOSSIP_PERIOD_MS, + }), + actor_channel_capacity: Some(DEFAULT_ACTOR_CHANNEL_CAPACITY), + gossip_batch_size: Some(DEFAULT_GOSSIP_BATCH_SIZE), + gossip_period_ms: Some(DEFAULT_GOSSIP_PERIOD_MS), } } } - -impl Configuration { - /// Key-pair used by default for demo purposes - #[allow(clippy::expect_used)] - fn placeholder_keypair() -> KeyPair { - let public_key = "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - .parse() - .expect("Public key not in mulithash format"); - let private_key = PrivateKey::from_hex( - Algorithm::Ed25519, - "282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - ).expect("Private key not hex encoded"); - - KeyPair::new(public_key, private_key).expect("Key pair mismatch") - } - - fn placeholder_peer_id() -> PeerId { - let (public_key, _) = Self::placeholder_keypair().into(); - - PeerId { - address: "127.0.0.1:1337".to_owned(), - public_key, - } - } - - fn placeholder_trusted_peers() -> TrustedPeers { +impl ConfigurationProxy { + /// To be used for proxy finalisation. Should only be + /// used if no peers present. + /// + /// # Panics + /// The [`peer_id`] field of [`Self`] + /// has not been initialized prior to calling this method. + pub fn insert_self_as_trusted_peers(&mut self) { let mut peers = HashSet::new(); - peers.insert(Self::placeholder_peer_id()); - TrustedPeers { peers } - } - - /// Set `trusted_peers` configuration parameter. Will overwrite - /// existing `trusted_peers` but does not check for duplication. - #[inline] - pub fn set_trusted_peers(&mut self, trusted_peers: Vec) { - self.trusted_peers.peers = trusted_peers.into_iter().collect(); + #[allow(clippy::expect_used)] + let peer_id = self + .peer_id + .clone() + .expect("Insertion of `self` as `trusted_peers` implies that `peer_id` field should be initialized"); + peers.insert(peer_id); + self.trusted_peers = Some(TrustedPeers { peers }); } - +} +impl Configuration { /// Time estimation from receiving a transaction to storing it in /// a block on all peers for the "sunny day" scenario. #[inline] diff --git a/config/src/telemetry.rs b/config/src/telemetry.rs index 012f25fa2ca..b557e840d8c 100644 --- a/config/src/telemetry.rs +++ b/config/src/telemetry.rs @@ -7,7 +7,6 @@ use url::Url; /// Configuration parameters container #[derive(Clone, Deserialize, Serialize, Debug, Proxy, LoadFromEnv, Documented, PartialEq, Eq)] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] #[config(env_prefix = "TELEMETRY_")] pub struct Configuration { /// The node's name to be seen on the telemetry @@ -17,36 +16,26 @@ pub struct Configuration { #[config(serde_as_str)] pub url: Option, /// The minimum period of time in seconds to wait before reconnecting - #[serde(default = "default_min_retry_period")] pub min_retry_period: u64, /// The maximum exponent of 2 that is used for increasing delay between reconnections - #[serde(default = "default_max_retry_delay_exponent")] pub max_retry_delay_exponent: u8, /// The filepath that to write dev-telemetry to #[config(serde_as_str)] pub file: Option, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - name: None, - url: None, - min_retry_period: retry_period::DEFAULT_MIN_RETRY_PERIOD, - max_retry_delay_exponent: retry_period::DEFAULT_MAX_RETRY_DELAY_EXPONENT, - file: None, + name: Some(None), + url: Some(None), + min_retry_period: Some(retry_period::DEFAULT_MIN_RETRY_PERIOD), + max_retry_delay_exponent: Some(retry_period::DEFAULT_MAX_RETRY_DELAY_EXPONENT), + file: Some(None), } } } -const fn default_min_retry_period() -> u64 { - retry_period::DEFAULT_MIN_RETRY_PERIOD -} - -const fn default_max_retry_delay_exponent() -> u8 { - retry_period::DEFAULT_MAX_RETRY_DELAY_EXPONENT -} - /// `RetryPeriod` configuration pub mod retry_period { /// Default minimal retry period diff --git a/config/src/torii.rs b/config/src/torii.rs index bf981a5e620..c13994a625a 100644 --- a/config/src/torii.rs +++ b/config/src/torii.rs @@ -17,7 +17,6 @@ pub const DEFAULT_TORII_MAX_CONTENT_LENGTH: u32 = 2_u32.pow(12) * 4000; /// as well as `max_transaction_size`. #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv)] #[serde(rename_all = "UPPERCASE")] -#[serde(default)] #[config(env_prefix = "TORII_")] pub struct Configuration { /// Torii URL for p2p communication for consensus and block synchronization purposes. @@ -32,14 +31,14 @@ pub struct Configuration { pub max_content_len: u32, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { Self { - p2p_addr: DEFAULT_TORII_P2P_ADDR.to_owned(), - api_url: uri::DEFAULT_API_URL.to_owned(), - telemetry_url: DEFAULT_TORII_TELEMETRY_URL.to_owned(), - max_transaction_size: DEFAULT_TORII_MAX_TRANSACTION_SIZE, - max_content_len: DEFAULT_TORII_MAX_CONTENT_LENGTH, + p2p_addr: None, + api_url: None, + telemetry_url: None, + max_transaction_size: Some(DEFAULT_TORII_MAX_TRANSACTION_SIZE), + max_content_len: Some(DEFAULT_TORII_MAX_CONTENT_LENGTH), } } } diff --git a/config/src/wasm.rs b/config/src/wasm.rs index 4c2cbcbcd96..250216a7432 100644 --- a/config/src/wasm.rs +++ b/config/src/wasm.rs @@ -11,7 +11,7 @@ const DEFAULT_MAX_MEMORY: u32 = 500 * 2_u32.pow(20); // 500 MiB Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Documented, Proxy, LoadFromEnv, )] #[config(env_prefix = "WASM_")] -#[serde(rename_all = "UPPERCASE", default)] +#[serde(rename_all = "UPPERCASE")] pub struct Configuration { /// The fuel limit determines the maximum number of instructions that can be executed during the execution of a smart contract. /// Every WASM instruction costs approximately 1 unit of fuel. See @@ -21,11 +21,11 @@ pub struct Configuration { pub max_memory: u32, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { - Configuration { - fuel_limit: DEFAULT_FUEL_LIMIT, - max_memory: DEFAULT_MAX_MEMORY, + Self { + fuel_limit: Some(DEFAULT_FUEL_LIMIT), + max_memory: Some(DEFAULT_MAX_MEMORY), } } } diff --git a/config/src/wsv.rs b/config/src/wsv.rs index 4f5f2f2258d..473adc6138c 100644 --- a/config/src/wsv.rs +++ b/config/src/wsv.rs @@ -15,7 +15,7 @@ const DEFAULT_IDENT_LENGTH_LIMITS: LengthLimits = LengthLimits::new(1, 2_u32.pow Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Proxy, LoadFromEnv, Documented, )] #[config(env_prefix = "WSV_")] -#[serde(rename_all = "UPPERCASE", default)] +#[serde(rename_all = "UPPERCASE")] pub struct Configuration { /// [`MetadataLimits`] for every asset with store. pub asset_metadata_limits: MetadataLimits, @@ -28,18 +28,19 @@ pub struct Configuration { /// [`LengthLimits`] for the number of chars in identifiers that can be stored in the WSV. pub ident_length_limits: LengthLimits, /// WASM runtime configuration + #[config(inner)] pub wasm_runtime_config: wasm::Configuration, } -impl Default for Configuration { +impl Default for ConfigurationProxy { fn default() -> Self { - Configuration { - asset_metadata_limits: DEFAULT_METADATA_LIMITS, - asset_definition_metadata_limits: DEFAULT_METADATA_LIMITS, - account_metadata_limits: DEFAULT_METADATA_LIMITS, - domain_metadata_limits: DEFAULT_METADATA_LIMITS, - ident_length_limits: DEFAULT_IDENT_LENGTH_LIMITS, - wasm_runtime_config: wasm::Configuration::default(), + Self { + asset_metadata_limits: Some(DEFAULT_METADATA_LIMITS), + asset_definition_metadata_limits: Some(DEFAULT_METADATA_LIMITS), + account_metadata_limits: Some(DEFAULT_METADATA_LIMITS), + domain_metadata_limits: Some(DEFAULT_METADATA_LIMITS), + ident_length_limits: Some(DEFAULT_IDENT_LENGTH_LIMITS), + wasm_runtime_config: Some(wasm::ConfigurationProxy::default()), } } } diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 92785c9f1df..7ff91a60ae8 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -421,9 +421,12 @@ impl RawGenesisDomainBuilder { #[cfg(test)] mod tests { + use iroha_config::{base::proxy::Builder, genesis::ConfigurationProxy}; + use super::*; #[test] + #[allow(clippy::expect_used)] fn load_default_genesis_block() -> Result<()> { let (public_key, private_key) = KeyPair::generate()?.into(); let tx_limits = TransactionLimits { @@ -433,11 +436,15 @@ mod tests { let _genesis_block = GenesisNetwork::from_configuration( true, RawGenesisBlock::default(), - Some(&Configuration { - account_public_key: public_key, - account_private_key: Some(private_key), - ..Configuration::default() - }), + Some( + &ConfigurationProxy { + account_public_key: Some(public_key), + account_private_key: Some(Some(private_key)), + ..ConfigurationProxy::default() + } + .build() + .expect("Default genesis config should build when provided the `public key`"), + ), &tx_limits, )?; Ok(()) diff --git a/core/src/queue.rs b/core/src/queue.rs index caa6e262e15..e86aac79967 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -246,6 +246,7 @@ mod tests { time::{Duration, Instant}, }; + use iroha_config::{base::proxy::Builder, queue::ConfigurationProxy}; use iroha_data_model::prelude::*; use rand::Rng; @@ -299,7 +300,9 @@ mod tests { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -323,7 +326,9 @@ mod tests { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: max_txs_in_queue, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -362,7 +367,9 @@ mod tests { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: max_txs_in_queue, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -388,7 +395,9 @@ mod tests { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -436,7 +445,9 @@ mod tests { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -465,7 +476,9 @@ mod tests { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -486,7 +499,9 @@ mod tests { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, Arc::clone(&wsv), ); @@ -508,7 +523,9 @@ mod tests { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 200, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -545,7 +562,9 @@ mod tests { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); @@ -580,7 +599,9 @@ mod tests { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100_000_000, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, )); @@ -644,7 +665,9 @@ mod tests { let queue = Queue::from_configuration( &Configuration { future_threshold_ms, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default queue config should always build") }, wsv, ); diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index c3c65333283..bf67a5b01ff 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -10,7 +10,10 @@ use anyhow::anyhow; use eyre::Context; -use iroha_config::wasm::Configuration; +use iroha_config::{ + base::proxy::Builder, + wasm::{Configuration, ConfigurationProxy}, +}; use iroha_data_model::{permission, prelude::*, ParseError}; use parity_scale_codec::{Decode, Encode}; use wasmtime::{ @@ -232,9 +235,12 @@ impl<'wrld> Runtime<'wrld> { /// # Errors /// /// If unable to construct runtime + #[allow(clippy::unwrap_in_result)] pub fn new() -> Result { let engine = Self::create_engine()?; - let config = Configuration::default(); + let config = ConfigurationProxy::default() + .build() + .expect("Wasm proxy always builds"); let linker = Self::create_linker(&engine)?; diff --git a/core/src/wsv.rs b/core/src/wsv.rs index a9f0c77bbfb..f4460fd0459 100644 --- a/core/src/wsv.rs +++ b/core/src/wsv.rs @@ -15,7 +15,10 @@ use dashmap::{ }; use eyre::Result; use getset::Getters; -use iroha_config::wsv::Configuration; +use iroha_config::{ + base::proxy::Builder, + wsv::{Configuration, ConfigurationProxy}, +}; use iroha_crypto::HashOf; use iroha_data_model::prelude::*; use iroha_logger::prelude::*; @@ -133,10 +136,14 @@ impl WorldStateView { /// Construct [`WorldStateView`] with given [`World`]. #[must_use] #[inline] + #[allow(clippy::expect_used)] pub fn new(world: World) -> Self { // Added to remain backward compatible with other code primary in tests let (events_sender, _) = broadcast::channel(1); - Self::from_configuration(Configuration::default(), world, events_sender) + let config = ConfigurationProxy::default() + .build() + .expect("Wsv proxy always builds"); + Self::from_configuration(config, world, events_sender) } /// Get `Account`'s `Asset`s diff --git a/docs/source/references/config.md b/docs/source/references/config.md index 050033c7dad..30a14982a0d 100644 --- a/docs/source/references/config.md +++ b/docs/source/references/config.md @@ -4,15 +4,12 @@ In this document we provide a reference and detailed descriptions of Iroha's con ## Default configuration -The following is the default configuration used by Iroha. +The following is the default configuration used by Iroha. Note that fields that have `null` as their value do not have a default and should be provided by the user. ```json { - "PUBLIC_KEY": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b", - "PRIVATE_KEY": { - "digest_function": "ed25519", - "payload": "282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - }, + "PUBLIC_KEY": null, + "PRIVATE_KEY": null, "DISABLE_PANIC_TERMINAL_COLORS": false, "KURA": { "INIT_MODE": "strict", @@ -21,17 +18,10 @@ The following is the default configuration used by Iroha. "ACTOR_CHANNEL_CAPACITY": 100 }, "SUMERAGI": { - "PEER_ID": { - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - }, + "KEY_PAIR": null, + "PEER_ID": null, "BLOCK_TIME_MS": 1000, - "TRUSTED_PEERS": [ - { - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - } - ], + "TRUSTED_PEERS": null, "COMMIT_TIME_LIMIT_MS": 2000, "TX_RECEIPT_TIME_LIMIT_MS": 500, "TRANSACTION_LIMITS": { @@ -43,9 +33,9 @@ The following is the default configuration used by Iroha. "GOSSIP_PERIOD_MS": 1000 }, "TORII": { - "P2P_ADDR": "127.0.0.1:1337", - "API_URL": "127.0.0.1:8080", - "TELEMETRY_URL": "127.0.0.1:8180", + "P2P_ADDR": null, + "API_URL": null, + "TELEMETRY_URL": null, "MAX_TRANSACTION_SIZE": 32768, "MAX_CONTENT_LEN": 16384000 }, @@ -68,11 +58,8 @@ The following is the default configuration used by Iroha. "TERMINAL_COLORS": true }, "GENESIS": { - "ACCOUNT_PUBLIC_KEY": "ed01204cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf", - "ACCOUNT_PRIVATE_KEY": { - "digest_function": "ed25519", - "payload": "d748e18ce60cb30dea3e73c9019b7af45a8d465e3d71bcc9a5ef99a008205e534cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" - }, + "ACCOUNT_PUBLIC_KEY": null, + "ACCOUNT_PRIVATE_KEY": null, "WAIT_FOR_PEERS_RETRY_COUNT_LIMIT": 100, "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500, "GENESIS_SUBMISSION_DELAY_MS": 1000 @@ -120,7 +107,7 @@ The following is the default configuration used by Iroha. `BlockSynchronizer` configuration -Has type `block_sync::Configuration`. Can be configured via environment variable `IROHA_BLOCK_SYNC` +Has type `Option`. Can be configured via environment variable `IROHA_BLOCK_SYNC` ```json { @@ -134,7 +121,7 @@ Has type `block_sync::Configuration`. Can be configured via environment variable Buffer capacity of actor's MPSC channel -Has type `u32`. Can be configured via environment variable `BLOCK_SYNC_ACTOR_CHANNEL_CAPACITY` +Has type `Option`. Can be configured via environment variable `BLOCK_SYNC_ACTOR_CHANNEL_CAPACITY` ```json 100 @@ -144,7 +131,7 @@ Has type `u32`. Can be configured via environment variable `BLOCK_SYNC_ACTOR_CHA The number of blocks that can be sent in one message. -Has type `u32`. Can be configured via environment variable `BLOCK_SYNC_BLOCK_BATCH_SIZE` +Has type `Option`. Can be configured via environment variable `BLOCK_SYNC_BLOCK_BATCH_SIZE` ```json 4 @@ -154,7 +141,7 @@ Has type `u32`. Can be configured via environment variable `BLOCK_SYNC_BLOCK_BAT The period of time to wait between sending requests for the latest block. -Has type `u64`. Can be configured via environment variable `BLOCK_SYNC_GOSSIP_PERIOD_MS` +Has type `Option`. Can be configured via environment variable `BLOCK_SYNC_GOSSIP_PERIOD_MS` ```json 10000 @@ -164,7 +151,7 @@ Has type `u64`. Can be configured via environment variable `BLOCK_SYNC_GOSSIP_PE Disable coloring of the backtrace and error report on panic -Has type `bool`. Can be configured via environment variable `IROHA_DISABLE_PANIC_TERMINAL_COLORS` +Has type `Option`. Can be configured via environment variable `IROHA_DISABLE_PANIC_TERMINAL_COLORS` ```json false @@ -174,15 +161,12 @@ false `GenesisBlock` configuration -Has type `genesis::Configuration`. Can be configured via environment variable `IROHA_GENESIS` +Has type `Option`. Can be configured via environment variable `IROHA_GENESIS` ```json { - "ACCOUNT_PRIVATE_KEY": { - "digest_function": "ed25519", - "payload": "d748e18ce60cb30dea3e73c9019b7af45a8d465e3d71bcc9a5ef99a008205e534cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" - }, - "ACCOUNT_PUBLIC_KEY": "ed01204cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf", + "ACCOUNT_PRIVATE_KEY": null, + "ACCOUNT_PUBLIC_KEY": null, "GENESIS_SUBMISSION_DELAY_MS": 1000, "WAIT_FOR_PEERS_RETRY_COUNT_LIMIT": 100, "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500 @@ -193,30 +177,27 @@ Has type `genesis::Configuration`. Can be configured via environment variable `I The private key of the genesis account, only needed for the peer that submits the genesis block. -Has type `Option`. Can be configured via environment variable `IROHA_GENESIS_ACCOUNT_PRIVATE_KEY` +Has type `Option>`. Can be configured via environment variable `IROHA_GENESIS_ACCOUNT_PRIVATE_KEY` ```json -{ - "digest_function": "ed25519", - "payload": "d748e18ce60cb30dea3e73c9019b7af45a8d465e3d71bcc9a5ef99a008205e534cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" -} +null ``` ### `genesis.account_public_key` The public key of the genesis account, should be supplied to all peers. -Has type `PublicKey`. Can be configured via environment variable `IROHA_GENESIS_ACCOUNT_PUBLIC_KEY` +Has type `Option`. Can be configured via environment variable `IROHA_GENESIS_ACCOUNT_PUBLIC_KEY` ```json -"ed01204cffd0ee429b1bdd36b3910ec570852b8bb63f18750341772fb46bc856c5caaf" +null ``` ### `genesis.genesis_submission_delay_ms` The delay before genesis block submission after minimum number of peers were discovered to be online. -Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_GENESIS_SUBMISSION_DELAY_MS` +Has type `Option`. Can be configured via environment variable `IROHA_GENESIS_GENESIS_SUBMISSION_DELAY_MS` ```json 1000 @@ -226,7 +207,7 @@ Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_GENESI The number of attempts to connect to peers while waiting for them to submit genesis. -Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT` +Has type `Option`. Can be configured via environment variable `IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_COUNT_LIMIT` ```json 100 @@ -236,7 +217,7 @@ Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_WAIT_F The period in milliseconds in which to retry connecting to peers while waiting for them to submit genesis. -Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_PERIOD_MS` +Has type `Option`. Can be configured via environment variable `IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_PERIOD_MS` ```json 500 @@ -246,7 +227,7 @@ Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_WAIT_F `Kura` configuration -Has type `kura::Configuration`. Can be configured via environment variable `IROHA_KURA` +Has type `Option`. Can be configured via environment variable `IROHA_KURA` ```json { @@ -261,7 +242,7 @@ Has type `kura::Configuration`. Can be configured via environment variable `IROH Default buffer capacity of actor's MPSC channel. -Has type `u32`. Can be configured via environment variable `KURA_ACTOR_CHANNEL_CAPACITY` +Has type `Option`. Can be configured via environment variable `KURA_ACTOR_CHANNEL_CAPACITY` ```json 100 @@ -271,7 +252,7 @@ Has type `u32`. Can be configured via environment variable `KURA_ACTOR_CHANNEL_C Path to the existing block store folder or path to create new folder. -Has type `String`. Can be configured via environment variable `KURA_BLOCK_STORE_PATH` +Has type `Option`. Can be configured via environment variable `KURA_BLOCK_STORE_PATH` ```json "./storage" @@ -281,7 +262,7 @@ Has type `String`. Can be configured via environment variable `KURA_BLOCK_STORE_ Maximum number of blocks to write into a single storage file. -Has type `NonZeroU64`. Can be configured via environment variable `KURA_BLOCKS_PER_STORAGE_FILE` +Has type `Option`. Can be configured via environment variable `KURA_BLOCKS_PER_STORAGE_FILE` ```json 1000 @@ -291,7 +272,7 @@ Has type `NonZeroU64`. Can be configured via environment variable `KURA_BLOCKS_P Initialization mode: `strict` or `fast`. -Has type `Mode`. Can be configured via environment variable `KURA_INIT_MODE` +Has type `Option`. Can be configured via environment variable `KURA_INIT_MODE` ```json "strict" @@ -301,7 +282,7 @@ Has type `Mode`. Can be configured via environment variable `KURA_INIT_MODE` `Logger` configuration -Has type `logger::Configuration`. Can be configured via environment variable `IROHA_LOGGER` +Has type `Option`. Can be configured via environment variable `IROHA_LOGGER` ```json { @@ -317,7 +298,7 @@ Has type `logger::Configuration`. Can be configured via environment variable `IR Compact mode (no spans from telemetry) -Has type `bool`. Can be configured via environment variable `COMPACT_MODE` +Has type `Option`. Can be configured via environment variable `COMPACT_MODE` ```json false @@ -327,7 +308,7 @@ false If provided, logs will be copied to said file in the -Has type `Option`. Can be configured via environment variable `LOG_FILE_PATH` +Has type `Option>`. Can be configured via environment variable `LOG_FILE_PATH` ```json null @@ -337,7 +318,7 @@ null Maximum log level -Has type `SyncLevel`. Can be configured via environment variable `MAX_LOG_LEVEL` +Has type `Option`. Can be configured via environment variable `MAX_LOG_LEVEL` ```json "INFO" @@ -347,7 +328,7 @@ Has type `SyncLevel`. Can be configured via environment variable `MAX_LOG_LEVEL` Capacity (or batch size) for telemetry channel -Has type `u32`. Can be configured via environment variable `TELEMETRY_CAPACITY` +Has type `Option`. Can be configured via environment variable `TELEMETRY_CAPACITY` ```json 1000 @@ -357,7 +338,7 @@ Has type `u32`. Can be configured via environment variable `TELEMETRY_CAPACITY` Enable ANSI terminal colors for formatted output. -Has type `bool`. Can be configured via environment variable `TERMINAL_COLORS` +Has type `Option`. Can be configured via environment variable `TERMINAL_COLORS` ```json true @@ -367,7 +348,7 @@ true Network configuration -Has type `network::Configuration`. Can be configured via environment variable `IROHA_NETWORK` +Has type `Option`. Can be configured via environment variable `IROHA_NETWORK` ```json { @@ -379,7 +360,7 @@ Has type `network::Configuration`. Can be configured via environment variable `I Buffer capacity of actor's MPSC channel -Has type `u32`. Can be configured via environment variable `IROHA_NETWORK_ACTOR_CHANNEL_CAPACITY` +Has type `Option`. Can be configured via environment variable `IROHA_NETWORK_ACTOR_CHANNEL_CAPACITY` ```json 100 @@ -389,30 +370,27 @@ Has type `u32`. Can be configured via environment variable `IROHA_NETWORK_ACTOR_ Private key of this peer -Has type `PrivateKey`. Can be configured via environment variable `IROHA_PRIVATE_KEY` +Has type `Option`. Can be configured via environment variable `IROHA_PRIVATE_KEY` ```json -{ - "digest_function": "ed25519", - "payload": "282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" -} +null ``` ## `public_key` Public key of this peer -Has type `PublicKey`. Can be configured via environment variable `IROHA_PUBLIC_KEY` +Has type `Option`. Can be configured via environment variable `IROHA_PUBLIC_KEY` ```json -"ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" +null ``` ## `queue` `Queue` configuration -Has type `queue::Configuration`. Can be configured via environment variable `IROHA_QUEUE` +Has type `Option`. Can be configured via environment variable `IROHA_QUEUE` ```json { @@ -427,7 +405,7 @@ Has type `queue::Configuration`. Can be configured via environment variable `IRO The threshold to determine if a transaction has been tampered to have a future timestamp. -Has type `u64`. Can be configured via environment variable `QUEUE_FUTURE_THRESHOLD_MS` +Has type `Option`. Can be configured via environment variable `QUEUE_FUTURE_THRESHOLD_MS` ```json 1000 @@ -437,7 +415,7 @@ Has type `u64`. Can be configured via environment variable `QUEUE_FUTURE_THRESHO The upper limit of the number of transactions per block. -Has type `u32`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSACTIONS_IN_BLOCK` +Has type `Option`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSACTIONS_IN_BLOCK` ```json 8192 @@ -447,7 +425,7 @@ Has type `u32`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSA The upper limit of the number of transactions waiting in the queue. -Has type `u32`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSACTIONS_IN_QUEUE` +Has type `Option`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSACTIONS_IN_QUEUE` ```json 65536 @@ -457,7 +435,7 @@ Has type `u32`. Can be configured via environment variable `QUEUE_MAXIMUM_TRANSA The transaction will be dropped after this time if it is still in the queue. -Has type `u64`. Can be configured via environment variable `QUEUE_TRANSACTION_TIME_TO_LIVE_MS` +Has type `Option`. Can be configured via environment variable `QUEUE_TRANSACTION_TIME_TO_LIVE_MS` ```json 86400000 @@ -467,7 +445,7 @@ Has type `u64`. Can be configured via environment variable `QUEUE_TRANSACTION_TI `Sumeragi` configuration -Has type `sumeragi::Configuration`. Can be configured via environment variable `IROHA_SUMERAGI` +Has type `Option`. Can be configured via environment variable `IROHA_SUMERAGI` ```json { @@ -476,20 +454,13 @@ Has type `sumeragi::Configuration`. Can be configured via environment variable ` "COMMIT_TIME_LIMIT_MS": 2000, "GOSSIP_BATCH_SIZE": 500, "GOSSIP_PERIOD_MS": 1000, - "PEER_ID": { - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - }, + "KEY_PAIR": null, + "PEER_ID": null, "TRANSACTION_LIMITS": { "max_instruction_number": 4096, "max_wasm_size_bytes": 4194304 }, - "TRUSTED_PEERS": [ - { - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - } - ], + "TRUSTED_PEERS": null, "TX_RECEIPT_TIME_LIMIT_MS": 500 } ``` @@ -498,7 +469,7 @@ Has type `sumeragi::Configuration`. Can be configured via environment variable ` Buffer capacity of actor's MPSC channel -Has type `u32`. Can be configured via environment variable `SUMERAGI_ACTOR_CHANNEL_CAPACITY` +Has type `Option`. Can be configured via environment variable `SUMERAGI_ACTOR_CHANNEL_CAPACITY` ```json 100 @@ -508,7 +479,7 @@ Has type `u32`. Can be configured via environment variable `SUMERAGI_ACTOR_CHANN The period of time a peer waits for the `CreatedBlock` message after getting a `TransactionReceipt` -Has type `u64`. Can be configured via environment variable `SUMERAGI_BLOCK_TIME_MS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_BLOCK_TIME_MS` ```json 1000 @@ -518,7 +489,7 @@ Has type `u64`. Can be configured via environment variable `SUMERAGI_BLOCK_TIME_ The period of time a peer waits for `CommitMessage` from the proxy tail. -Has type `u64`. Can be configured via environment variable `SUMERAGI_COMMIT_TIME_LIMIT_MS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_COMMIT_TIME_LIMIT_MS` ```json 2000 @@ -528,7 +499,7 @@ Has type `u64`. Can be configured via environment variable `SUMERAGI_COMMIT_TIME Maximum number of transactions in tx gossip batch message. While configuring this, pay attention to `p2p` max message size. -Has type `u32`. Can be configured via environment variable `SUMERAGI_GOSSIP_BATCH_SIZE` +Has type `Option`. Can be configured via environment variable `SUMERAGI_GOSSIP_BATCH_SIZE` ```json 500 @@ -538,7 +509,7 @@ Has type `u32`. Can be configured via environment variable `SUMERAGI_GOSSIP_BATC Period in milliseconds for pending transaction gossiping between peers. -Has type `u64`. Can be configured via environment variable `SUMERAGI_GOSSIP_PERIOD_MS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_GOSSIP_PERIOD_MS` ```json 1000 @@ -548,36 +519,27 @@ Has type `u64`. Can be configured via environment variable `SUMERAGI_GOSSIP_PERI The key pair consisting of a private and a public key. -Has type `KeyPair`. Can be configured via environment variable `SUMERAGI_KEY_PAIR` +Has type `Option`. Can be configured via environment variable `SUMERAGI_KEY_PAIR` ```json -{ - "private_key": { - "digest_function": "ed25519", - "payload": "282ed9f3cf92811c3818dbc4ae594ed59dc1a2f78e4241e31924e101d6b1fb831c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - }, - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" -} +null ``` ### `sumeragi.peer_id` Current Peer Identification. -Has type `PeerId`. Can be configured via environment variable `SUMERAGI_PEER_ID` +Has type `Option`. Can be configured via environment variable `SUMERAGI_PEER_ID` ```json -{ - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" -} +null ``` ### `sumeragi.transaction_limits` The limits to which transactions must adhere -Has type `TransactionLimits`. Can be configured via environment variable `SUMERAGI_TRANSACTION_LIMITS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_TRANSACTION_LIMITS` ```json { @@ -590,22 +552,17 @@ Has type `TransactionLimits`. Can be configured via environment variable `SUMERA Optional list of predefined trusted peers. -Has type `TrustedPeers`. Can be configured via environment variable `SUMERAGI_TRUSTED_PEERS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_TRUSTED_PEERS` ```json -[ - { - "address": "127.0.0.1:1337", - "public_key": "ed01201c61faf8fe94e253b93114240394f79a607b7fa55f9e5a41ebec74b88055768b" - } -] +null ``` ### `sumeragi.tx_receipt_time_limit_ms` The period of time a peer waits for `TxReceipt` from the leader. -Has type `u64`. Can be configured via environment variable `SUMERAGI_TX_RECEIPT_TIME_LIMIT_MS` +Has type `Option`. Can be configured via environment variable `SUMERAGI_TX_RECEIPT_TIME_LIMIT_MS` ```json 500 @@ -615,7 +572,7 @@ Has type `u64`. Can be configured via environment variable `SUMERAGI_TX_RECEIPT_ Telemetry configuration -Has type `telemetry::Configuration`. Can be configured via environment variable `IROHA_TELEMETRY` +Has type `Option`. Can be configured via environment variable `IROHA_TELEMETRY` ```json { @@ -631,7 +588,7 @@ Has type `telemetry::Configuration`. Can be configured via environment variable The filepath that to write dev-telemetry to -Has type `Option`. Can be configured via environment variable `TELEMETRY_FILE` +Has type `Option>`. Can be configured via environment variable `TELEMETRY_FILE` ```json null @@ -641,7 +598,7 @@ null The maximum exponent of 2 that is used for increasing delay between reconnections -Has type `u8`. Can be configured via environment variable `TELEMETRY_MAX_RETRY_DELAY_EXPONENT` +Has type `Option`. Can be configured via environment variable `TELEMETRY_MAX_RETRY_DELAY_EXPONENT` ```json 4 @@ -651,7 +608,7 @@ Has type `u8`. Can be configured via environment variable `TELEMETRY_MAX_RETRY_D The minimum period of time in seconds to wait before reconnecting -Has type `u64`. Can be configured via environment variable `TELEMETRY_MIN_RETRY_PERIOD` +Has type `Option`. Can be configured via environment variable `TELEMETRY_MIN_RETRY_PERIOD` ```json 1 @@ -661,7 +618,7 @@ Has type `u64`. Can be configured via environment variable `TELEMETRY_MIN_RETRY_ The node's name to be seen on the telemetry -Has type `Option`. Can be configured via environment variable `TELEMETRY_NAME` +Has type `Option>`. Can be configured via environment variable `TELEMETRY_NAME` ```json null @@ -671,7 +628,7 @@ null The url of the telemetry, e.g., ws://127.0.0.1:8001/submit -Has type `Option`. Can be configured via environment variable `TELEMETRY_URL` +Has type `Option>`. Can be configured via environment variable `TELEMETRY_URL` ```json null @@ -681,15 +638,15 @@ null `Torii` configuration -Has type `torii::Configuration`. Can be configured via environment variable `IROHA_TORII` +Has type `Option`. Can be configured via environment variable `IROHA_TORII` ```json { - "API_URL": "127.0.0.1:8080", + "API_URL": null, "MAX_CONTENT_LEN": 16384000, "MAX_TRANSACTION_SIZE": 32768, - "P2P_ADDR": "127.0.0.1:1337", - "TELEMETRY_URL": "127.0.0.1:8180" + "P2P_ADDR": null, + "TELEMETRY_URL": null } ``` @@ -697,17 +654,17 @@ Has type `torii::Configuration`. Can be configured via environment variable `IRO Torii URL for client API. -Has type `String`. Can be configured via environment variable `TORII_API_URL` +Has type `Option`. Can be configured via environment variable `TORII_API_URL` ```json -"127.0.0.1:8080" +null ``` ### `torii.max_content_len` Maximum number of bytes in raw message. Used to prevent from DOS attacks. -Has type `u32`. Can be configured via environment variable `TORII_MAX_CONTENT_LEN` +Has type `Option`. Can be configured via environment variable `TORII_MAX_CONTENT_LEN` ```json 16384000 @@ -717,7 +674,7 @@ Has type `u32`. Can be configured via environment variable `TORII_MAX_CONTENT_LE Maximum number of bytes in raw transaction. Used to prevent from DOS attacks. -Has type `u32`. Can be configured via environment variable `TORII_MAX_TRANSACTION_SIZE` +Has type `Option`. Can be configured via environment variable `TORII_MAX_TRANSACTION_SIZE` ```json 32768 @@ -727,27 +684,27 @@ Has type `u32`. Can be configured via environment variable `TORII_MAX_TRANSACTIO Torii URL for p2p communication for consensus and block synchronization purposes. -Has type `String`. Can be configured via environment variable `TORII_P2P_ADDR` +Has type `Option`. Can be configured via environment variable `TORII_P2P_ADDR` ```json -"127.0.0.1:1337" +null ``` ### `torii.telemetry_url` Torii URL for reporting internal status and metrics for administration. -Has type `String`. Can be configured via environment variable `TORII_TELEMETRY_URL` +Has type `Option`. Can be configured via environment variable `TORII_TELEMETRY_URL` ```json -"127.0.0.1:8180" +null ``` ## `wsv` `WorldStateView` configuration -Has type `wsv::Configuration`. Can be configured via environment variable `IROHA_WSV` +Has type `Option`. Can be configured via environment variable `IROHA_WSV` ```json { @@ -782,7 +739,7 @@ Has type `wsv::Configuration`. Can be configured via environment variable `IROHA [`MetadataLimits`] of any account metadata. -Has type `MetadataLimits`. Can be configured via environment variable `WSV_ACCOUNT_METADATA_LIMITS` +Has type `Option`. Can be configured via environment variable `WSV_ACCOUNT_METADATA_LIMITS` ```json { @@ -795,7 +752,7 @@ Has type `MetadataLimits`. Can be configured via environment variable `WSV_ACCOU [`MetadataLimits`] of any asset definition metadata. -Has type `MetadataLimits`. Can be configured via environment variable `WSV_ASSET_DEFINITION_METADATA_LIMITS` +Has type `Option`. Can be configured via environment variable `WSV_ASSET_DEFINITION_METADATA_LIMITS` ```json { @@ -808,7 +765,7 @@ Has type `MetadataLimits`. Can be configured via environment variable `WSV_ASSET [`MetadataLimits`] for every asset with store. -Has type `MetadataLimits`. Can be configured via environment variable `WSV_ASSET_METADATA_LIMITS` +Has type `Option`. Can be configured via environment variable `WSV_ASSET_METADATA_LIMITS` ```json { @@ -821,7 +778,7 @@ Has type `MetadataLimits`. Can be configured via environment variable `WSV_ASSET [`MetadataLimits`] of any domain metadata. -Has type `MetadataLimits`. Can be configured via environment variable `WSV_DOMAIN_METADATA_LIMITS` +Has type `Option`. Can be configured via environment variable `WSV_DOMAIN_METADATA_LIMITS` ```json { @@ -834,7 +791,7 @@ Has type `MetadataLimits`. Can be configured via environment variable `WSV_DOMAI [`LengthLimits`] for the number of chars in identifiers that can be stored in the WSV. -Has type `LengthLimits`. Can be configured via environment variable `WSV_IDENT_LENGTH_LIMITS` +Has type `Option`. Can be configured via environment variable `WSV_IDENT_LENGTH_LIMITS` ```json { @@ -847,7 +804,7 @@ Has type `LengthLimits`. Can be configured via environment variable `WSV_IDENT_L WASM runtime configuration -Has type `wasm::Configuration`. Can be configured via environment variable `WSV_WASM_RUNTIME_CONFIG` +Has type `Option`. Can be configured via environment variable `WSV_WASM_RUNTIME_CONFIG` ```json { @@ -856,3 +813,23 @@ Has type `wasm::Configuration`. Can be configured via environment variable `WSV_ } ``` +#### `wsv.wasm_runtime_config.fuel_limit` + +The fuel limit determines the maximum number of instructions that can be executed during the execution of a smart contract. + +Has type `Option`. Can be configured via environment variable `WASM_FUEL_LIMIT` + +```json +1000000 +``` + +#### `wsv.wasm_runtime_config.max_memory` + +Maximum amount of linear memory a given smartcontract can allocate + +Has type `Option`. Can be configured via environment variable `WASM_MAX_MEMORY` + +```json +524288000 +``` + diff --git a/futures/Cargo.toml b/futures/Cargo.toml index 1bd164dd1f2..37d07eb4167 100644 --- a/futures/Cargo.toml +++ b/futures/Cargo.toml @@ -12,6 +12,7 @@ default = [] telemetry = ["iroha_futures_derive/telemetry"] [dependencies] +iroha_config = { version = "=2.0.0-pre-rc.8", path = "../config" } iroha_futures_derive = { version = "=2.0.0-pre-rc.8", path = "derive" } iroha_logger = { version = "=2.0.0-pre-rc.8", path = "../logger" } diff --git a/futures/tests/basic.rs b/futures/tests/basic.rs index f600e776af9..c3a17c6ba7a 100644 --- a/futures/tests/basic.rs +++ b/futures/tests/basic.rs @@ -2,8 +2,9 @@ use std::{thread, time::Duration}; +use iroha_config::base::proxy::Builder; use iroha_futures::FuturePollTelemetry; -use iroha_logger::Configuration; +use iroha_logger::ConfigurationProxy; use tokio::task; use tokio_stream::{wrappers::ReceiverStream, StreamExt}; @@ -33,9 +34,13 @@ async fn test_sleep() { Duration::from_nanos(80_000_000), ]; - let (_, telemetry_future) = iroha_logger::init(&Configuration::default()) - .unwrap() - .unwrap(); + let (_, telemetry_future) = iroha_logger::init( + &ConfigurationProxy::default() + .build() + .expect("Default logger config always builds"), + ) + .unwrap() + .unwrap(); assert_eq!(sleep(sleep_times.clone()).await, 10_i32); let telemetry = ReceiverStream::new(telemetry_future) .map(FuturePollTelemetry::try_from) diff --git a/logger/src/lib.rs b/logger/src/lib.rs index 3aa6fa0c7a2..82a1a0d3edd 100644 --- a/logger/src/lib.rs +++ b/logger/src/lib.rs @@ -19,7 +19,7 @@ use std::{ }; use color_eyre::{eyre::WrapErr, Report, Result}; -pub use iroha_config::logger::{Configuration, Level}; +pub use iroha_config::logger::{Configuration, ConfigurationProxy, Level}; pub use telemetry::{Telemetry, TelemetryFields, TelemetryLayer}; use tokio::sync::mpsc::Receiver; pub use tracing::{ diff --git a/logger/tests/setting_logger.rs b/logger/tests/setting_logger.rs index ac75325921f..da82ff950e3 100644 --- a/logger/tests/setting_logger.rs +++ b/logger/tests/setting_logger.rs @@ -1,11 +1,21 @@ #![allow(clippy::restriction, clippy::expect_used)] -use iroha_logger::{init, Configuration}; +use iroha_config::base::proxy::Builder; +use iroha_logger::{init, ConfigurationProxy}; #[tokio::test] async fn setting_logger_twice_fails() { - assert!(init(&Configuration::default()).is_ok()); - let second_init = init(&Configuration::default()); + assert!(init( + &ConfigurationProxy::default() + .build() + .expect("Default logger config always builds") + ) + .is_ok()); + let second_init = init( + &ConfigurationProxy::default() + .build() + .expect("Default logger config always builds"), + ); assert!(second_init.is_ok()); assert!(second_init.unwrap().is_none()); } diff --git a/logger/tests/telemetry.rs b/logger/tests/telemetry.rs index d896d154d62..50507412673 100644 --- a/logger/tests/telemetry.rs +++ b/logger/tests/telemetry.rs @@ -2,12 +2,15 @@ use std::time::Duration; -use iroha_logger::{info, init, Configuration, Telemetry, TelemetryFields}; +use iroha_config::base::proxy::Builder; +use iroha_logger::{info, init, ConfigurationProxy, Telemetry, TelemetryFields}; use tokio::time; #[tokio::test] async fn telemetry_separation_default() { - let (mut receiver, _) = init(&Configuration::default()).unwrap().unwrap(); + let (mut receiver, _) = init(&ConfigurationProxy::default().build().unwrap()) + .unwrap() + .unwrap(); info!(target: "telemetry::test", a = 2, c = true, d = "this won't be logged"); info!("This will be logged"); let telemetry = Telemetry { diff --git a/p2p/tests/integration/p2p.rs b/p2p/tests/integration/p2p.rs index 0028247cd22..5dd9642a1d7 100644 --- a/p2p/tests/integration/p2p.rs +++ b/p2p/tests/integration/p2p.rs @@ -11,8 +11,9 @@ use std::{ use futures::{prelude::*, stream::FuturesUnordered}; use iroha_actor::{broker::*, prelude::*}; +use iroha_config::base::proxy::Builder; use iroha_crypto::{KeyPair, PublicKey}; -use iroha_logger::{prelude::*, Configuration, Level}; +use iroha_logger::{prelude::*, Configuration, ConfigurationProxy, Level}; use iroha_p2p::{ network::{ConnectedPeers, GetConnectedPeers}, peer::PeerId, @@ -36,7 +37,9 @@ fn setup_logger() { let log_config = Configuration { max_log_level: Level::TRACE.into(), compact_mode: false, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default logger config failed to build. This is a programmer error") }; iroha_logger::init(&log_config).expect("Failed to start logger"); }) @@ -203,7 +206,9 @@ async fn multiple_networks() { let log_config = Configuration { max_log_level: Level::TRACE.into(), compact_mode: false, - ..Configuration::default() + ..ConfigurationProxy::default() + .build() + .expect("Default logger config should always build") }; // Can't use logger because it's failed to initialize. #[allow(clippy::print_stderr)] diff --git a/telemetry/src/ws.rs b/telemetry/src/ws.rs index f2b93d3fb31..9b82a07d508 100644 --- a/telemetry/src/ws.rs +++ b/telemetry/src/ws.rs @@ -275,6 +275,7 @@ mod tests { use eyre::{eyre, Result}; use futures::{Sink, StreamExt}; + use iroha_config::base::proxy::Builder; use iroha_logger::telemetry::{Telemetry, TelemetryFields}; use serde_json::{Map, Value}; use tokio::task::JoinHandle; @@ -575,7 +576,12 @@ mod tests { ($ident:ident, $future:ident) => { #[tokio::test] async fn $ident() { - iroha_logger::init(&iroha_logger::Configuration::default()).unwrap(); + iroha_logger::init( + &iroha_logger::ConfigurationProxy::default() + .build() + .expect("Default logger config should always build"), + ) + .unwrap(); let (suite, run_handle) = Suite::new(); $future(suite).await; run_handle.await.unwrap(); diff --git a/tools/kagami/src/main.rs b/tools/kagami/src/main.rs index 65925dd91b3..df770fafa87 100644 --- a/tools/kagami/src/main.rs +++ b/tools/kagami/src/main.rs @@ -10,7 +10,6 @@ use std::io::{stdout, BufWriter, Write}; use clap::{ArgGroup, StructOpt}; use color_eyre::eyre::WrapErr as _; -use iroha_config::iroha::Configuration; pub type Outcome = color_eyre::Result<()>; @@ -223,7 +222,7 @@ mod docs { use std::{fmt::Debug, io::Write}; use color_eyre::eyre::WrapErr as _; - use iroha_config::base::proxy::Documented; + use iroha_config::{base::proxy::Documented, iroha::ConfigurationProxy}; use serde_json::Value; use super::*; @@ -235,7 +234,7 @@ mod docs { impl RunArgs for Args { fn run(self, writer: &mut BufWriter) -> crate::Outcome { - Configuration::get_markdown(writer).wrap_err("Failed to generate documentation") + ConfigurationProxy::get_markdown(writer).wrap_err("Failed to generate documentation") } } @@ -256,7 +255,7 @@ mod docs { writeln!(writer, "## Default configuration\n")?; writeln!( writer, - "The following is the default configuration used by Iroha.\n" + "The following is the default configuration used by Iroha. Note that fields that have `null` as their value do not have a default and should be provided by the user.\n" )?; writeln!(writer, "```json\n{}\n```\n", defaults)?; Self::get_markdown_with_depth(writer, &docs, &mut vec, 2)?;