diff --git a/client/benches/torii.rs b/client/benches/torii.rs index d54ef78ce54..b4db657f6af 100644 --- a/client/benches/torii.rs +++ b/client/benches/torii.rs @@ -3,33 +3,28 @@ use std::thread; use criterion::{criterion_group, criterion_main, Criterion, Throughput}; -use iroha_client::{ - client::{asset, Client}, - config::Configuration as ClientConfiguration, -}; +use iroha_client::client::{asset, Client}; use iroha_core::{ - config::Configuration, genesis::{GenesisNetwork, GenesisNetworkTrait}, prelude::*, + samples::get_config, }; use iroha_data_model::prelude::*; -use test_network::{Peer as TestPeer, TestRuntime}; +use test_network::{get_key_pair, Peer as TestPeer, TestRuntime}; use tokio::runtime::Runtime; -const CONFIGURATION_PATH: &str = "../configs/test_config.json"; -const CLIENT_CONFIGURATION_PATH: &str = "../configs/test_client_config.json"; -const GENESIS_PATH: &str = "../configs/genesis.json"; const MINIMUM_SUCCESS_REQUEST_RATIO: f32 = 0.9; fn query_requests(criterion: &mut Criterion) { - let mut configuration = - Configuration::from_path(CONFIGURATION_PATH).expect("Failed to load configuration."); let mut peer = ::new().expect("Failed to create peer"); + let configuration = get_config( + std::iter::once(peer.id.clone()).collect(), + Some(get_key_pair()), + ); let rt = Runtime::test(); - configuration.sumeragi.trusted_peers.peers = std::iter::once(peer.id.clone()).collect(); let genesis = GenesisNetwork::from_configuration( true, - GENESIS_PATH, + ("alice", "wonderland", &get_key_pair().public_key).into(), &configuration.genesis, configuration.sumeragi.max_instruction_number, ) @@ -61,8 +56,7 @@ fn query_requests(criterion: &mut Criterion) { Value::U32(quantity), IdBox::AssetId(AssetId::new(asset_definition_id, account_id.clone())), ); - let mut client_config = ClientConfiguration::from_path(CLIENT_CONFIGURATION_PATH) - .expect("Failed to load configuration."); + let mut client_config = iroha_client::samples::get_client_config(&get_key_pair()); client_config.torii_api_url = peer.api_address.clone(); let mut iroha_client = Client::new(&client_config); let _ = iroha_client @@ -104,15 +98,15 @@ fn query_requests(criterion: &mut Criterion) { } fn instruction_submits(criterion: &mut Criterion) { - let mut configuration = - Configuration::from_path(CONFIGURATION_PATH).expect("Failed to load configuration."); let rt = Runtime::test(); let mut peer = ::new().expect("Failed to create peer"); - configuration.sumeragi.trusted_peers.peers = std::iter::once(peer.id.clone()).collect(); - + let configuration = get_config( + std::iter::once(peer.id.clone()).collect(), + Some(get_key_pair()), + ); let genesis = GenesisNetwork::from_configuration( true, - GENESIS_PATH, + ("alice", "wonderland", &configuration.public_key).into(), &configuration.genesis, configuration.sumeragi.max_instruction_number, ) @@ -135,8 +129,7 @@ fn instruction_submits(criterion: &mut Criterion) { .into(), )); let asset_definition_id = AssetDefinitionId::new("xor", domain_name); - let mut client_config = ClientConfiguration::from_path(CLIENT_CONFIGURATION_PATH) - .expect("Failed to load configuration."); + let mut client_config = iroha_client::samples::get_client_config(&get_key_pair()); client_config.torii_api_url = peer.api_address.clone(); let mut iroha_client = Client::new(&client_config); let _ = iroha_client diff --git a/client/src/lib.rs b/client/src/lib.rs index 474046a30e6..0d2992c4e53 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -6,21 +6,24 @@ pub mod client; pub mod config; pub use config::Configuration; mod http_client; + +/// Module containing sample configurations for tests and benchmarks. pub mod samples { - use super::Configuration; - use iroha_core::prelude::KeyPair; - /// Get sample client configuration. - 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: iroha_data_model::prelude::AccountId{ - name: "alice".to_string(), - domain_name: "wonderland".to_string(), - }, - torii_api_url: iroha_core::torii::config::DEFAULT_TORII_API_URL.to_string(), - ..Configuration::default() - } - } + use iroha_core::prelude::KeyPair; + + use super::Configuration; + /// Get sample client configuration. + 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: iroha_data_model::prelude::AccountId { + name: "alice".to_owned(), + domain_name: "wonderland".to_owned(), + }, + torii_api_url: iroha_core::torii::config::DEFAULT_TORII_API_URL.to_owned(), + ..Configuration::default() + } + } } diff --git a/client/src/samples.rs b/client/src/samples.rs deleted file mode 100644 index 301e59ac7f1..00000000000 --- a/client/src/samples.rs +++ /dev/null @@ -1,14 +0,0 @@ -/// Get sample client configuration. -pub fn get_client_config(key_pair: &KeyPair) -> ClientConfiguration { - let (public_key, private_key) = key_pair.clone().into(); - ClientConfiguration { - public_key, - private_key, - account_id: iroha_data_model::prelude::AccountId{ - name: "alice".to_string(), - domain_name: "wonderland".to_string(), - }, - torii_api_url: iroha_core::torii::config::DEFAULT_TORII_API_URL.to_string(), - ..ClientConfiguration::default() - } -} diff --git a/configs/peer/config.json b/configs/peer/config.json index a474659423a..db725f03cea 100644 --- a/configs/peer/config.json +++ b/configs/peer/config.json @@ -28,4 +28,4 @@ "payload": "9ac47abf59b356e0bd7dcbbbb4dec080e302156a48ca907e47cb6aea1d32719e7233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0" } } -} \ No newline at end of file +} diff --git a/configs/peer/genesis.json b/configs/peer/genesis.json index e87d9378186..ec91a3184bf 100644 --- a/configs/peer/genesis.json +++ b/configs/peer/genesis.json @@ -85,4 +85,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/configs/peer/trusted_peers.json b/configs/peer/trusted_peers.json index f68485b2121..6f57eff0fb5 100644 --- a/configs/peer/trusted_peers.json +++ b/configs/peer/trusted_peers.json @@ -15,4 +15,4 @@ "address": "127.0.0.1:1340", "public_key": "ed01208e351a70b6a603ed285d666b8d689b680865913ba03ce29fb7d13a166c4e7f1f" } -] \ No newline at end of file +] diff --git a/core/Cargo.toml b/core/Cargo.toml index de9e454e1f2..336f69d9848 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -60,6 +60,8 @@ pin-project = "1" [dev-dependencies] +test_network = { version = "=0.1.0", path = "./test_network" } + hex-literal = "0.2.1" tempfile = "3" criterion = "0.3" @@ -67,7 +69,6 @@ hex = "0.4.0" unique_port = "0.1.0" byte-unit = "4.0.12" once_cell = "1" -test_network = { version = "=0.1.0", path = "./test_network" } [[bench]] name = "sumeragi" diff --git a/core/src/config.rs b/core/src/config.rs index 4e7633a2d4b..32a2ca44eea 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -12,7 +12,7 @@ use crate::{ block_sync::config::BlockSyncConfiguration, genesis::config::GenesisConfiguration, kura::config::KuraConfiguration, - queue::config::QueueConfiguration, + queue::Configuration as QueueConfiguration, sumeragi::config::{SumeragiConfiguration, TrustedPeers}, torii::config::ToriiConfiguration, wsv::config::Configuration as WorldStateViewConfiguration, @@ -139,10 +139,11 @@ mod tests { use super::*; - const CONFIGURATION_PATH: &str = "../configs/test_config.json"; - const TRUSTED_PEERS_PATH: &str = "../configs/test_trusted_peers.json"; + const CONFIGURATION_PATH: &str = "../configs/peer/config.json"; + const TRUSTED_PEERS_PATH: &str = "../configs/peer/trusted_peers.json"; #[test] + #[ignore = "We shouldn't be testing `serde`"] fn parse_example_json() -> Result<()> { let configuration = Configuration::from_path(CONFIGURATION_PATH) .wrap_err("Failed to read configuration from example config")?; @@ -152,6 +153,7 @@ mod tests { } #[test] + #[ignore = "We shouldn't be testing `serde`"] fn parse_example_trusted_peers_json() -> Result<(), String> { let mut configuration = Configuration::from_path(CONFIGURATION_PATH) .map_err(|e| format!("Failed to read configuration from example config: {}", e))?; diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 57a1e98c491..87f2c8fef31 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -214,13 +214,17 @@ pub struct RawGenesisBlock { } impl RawGenesisBlock { + /// Construct a genesis block from a `.json` file at the specified path. + /// + /// # Errors + /// If file not found or deserialization from file fails. pub fn from_path + Debug>(path: P) -> Result { let file = File::open(&path).wrap_err(format!("Failed to open {:?}", &path))?; let reader = BufReader::new(file); - Ok(serde_json::from_reader(reader).wrap_err(format!( + serde_json::from_reader(reader).wrap_err(format!( "Failed to deserialise raw genesis block from {:?}", &path - ))?) + )) } } @@ -233,7 +237,7 @@ pub struct GenesisTransaction { impl GenesisTransaction { /// Convert `GenesisTransaction` into `AcceptedTransaction` with signature - /// + /// /// # Errors /// Fails if signing fails pub fn sign_and_accept( @@ -253,91 +257,95 @@ impl GenesisTransaction { impl From<(&str, &str, &PublicKey)> for GenesisTransaction { fn from((name, domain, pubkey): (&str, &str, &PublicKey)) -> Self { - Self { - isi: vec![ - RegisterBox::new(IdentifiableBox::Domain(Domain::new(domain).into())).into(), - RegisterBox::new(IdentifiableBox::NewAccount( - NewAccount::with_signatory( - iroha_data_model::account::Id::new(name, domain), pubkey.clone()).into())).into() - ] - } + Self { + isi: vec![ + RegisterBox::new(IdentifiableBox::Domain(Domain::new(domain).into())).into(), + RegisterBox::new(IdentifiableBox::NewAccount( + NewAccount::with_signatory( + iroha_data_model::account::Id::new(name, domain), + pubkey.clone(), + ) + .into(), + )) + .into(), + ], + } } } impl From<(&str, &str, &PublicKey)> for RawGenesisBlock { - fn from(tuple: (&str, &str, &PublicKey)) -> Self { - RawGenesisBlock { - transactions: vec![tuple.into()] - } - } + fn from(tuple: (&str, &str, &PublicKey)) -> Self { + RawGenesisBlock { + transactions: vec![tuple.into()], + } + } } - /// This module contains all genesis configuration related logic. pub mod config { - use iroha_config::derive::Configurable; - use iroha_crypto::{PrivateKey, PublicKey}; - use serde::{Deserialize, Serialize}; - - const DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT: u64 = 100; - const DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS: u64 = 500; - - #[derive(Clone, Deserialize, Serialize, Debug, Configurable, PartialEq, Eq)] - #[serde(rename_all = "UPPERCASE")] - #[config(env_prefix = "IROHA_GENESIS_")] - /// Configuration of the genesis block and its submission process. - pub struct GenesisConfiguration { - /// Genesis account public key, should be supplied to all the peers. - /// The type is `Option` just because it might be loaded from environment variables and not from `config.json`. - #[config(serde_as_str)] - pub account_public_key: Option, - /// Genesis account private key, only needed on the peer that submits the genesis block. - pub account_private_key: Option, - /// Number of attempts to connect to peers, while waiting for them to submit genesis. - #[serde(default = "default_wait_for_peers_retry_count")] - pub wait_for_peers_retry_count: u64, - /// 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, - } + use iroha_config::derive::Configurable; + use iroha_crypto::{PrivateKey, PublicKey}; + use serde::{Deserialize, Serialize}; + + const DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT: u64 = 100; + const DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS: u64 = 500; + + #[derive(Clone, Deserialize, Serialize, Debug, Configurable, PartialEq, Eq)] + #[serde(rename_all = "UPPERCASE")] + #[config(env_prefix = "IROHA_GENESIS_")] + /// Configuration of the genesis block and its submission process. + pub struct GenesisConfiguration { + /// Genesis account public key, should be supplied to all the peers. + /// The type is `Option` just because it might be loaded from environment variables and not from `config.json`. + #[config(serde_as_str)] + pub account_public_key: Option, + /// Genesis account private key, only needed on the peer that submits the genesis block. + pub account_private_key: Option, + /// Number of attempts to connect to peers, while waiting for them to submit genesis. + #[serde(default = "default_wait_for_peers_retry_count")] + pub wait_for_peers_retry_count: u64, + /// 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, + } - impl Default for GenesisConfiguration { - fn default() -> Self { - Self { - account_public_key: None, - account_private_key: None, - wait_for_peers_retry_count: DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT, - wait_for_peers_retry_period_ms: DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS - } - } - } + impl Default for GenesisConfiguration { + fn default() -> Self { + Self { + account_public_key: None, + account_private_key: None, + wait_for_peers_retry_count: DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT, + wait_for_peers_retry_period_ms: DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS, + } + } + } - const fn default_wait_for_peers_retry_count() -> u64 { - DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT - } + const fn default_wait_for_peers_retry_count() -> u64 { + DEFAULT_WAIT_FOR_PEERS_RETRY_COUNT + } - const fn default_wait_for_peers_retry_period_ms() -> u64 { - DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS - } + const fn default_wait_for_peers_retry_period_ms() -> u64 { + DEFAULT_WAIT_FOR_PEERS_RETRY_PERIOD_MS + } } #[cfg(test)] mod tests { - use super::*; - - #[test] - fn load_default_genesis_block() -> Result<()> { - let genesis_key_pair = KeyPair::generate()?; - let _genesis_block = GenesisNetwork::from_configuration( - true, - RawGenesisBlock::default(), - &GenesisConfiguration { - account_public_key: Some(genesis_key_pair.public_key), - account_private_key: Some(genesis_key_pair.private_key), - ..GenesisConfiguration::default() - }, - 4096, - )?; - Ok(()) - } + use super::*; + + #[test] + fn load_default_genesis_block() -> Result<()> { + let genesis_key_pair = KeyPair::generate()?; + let _genesis_block = GenesisNetwork::from_configuration( + true, + RawGenesisBlock::default(), + &GenesisConfiguration { + account_public_key: Some(genesis_key_pair.public_key), + account_private_key: Some(genesis_key_pair.private_key), + ..GenesisConfiguration::default() + }, + 4096, + )?; + Ok(()) + } } diff --git a/core/src/lib.rs b/core/src/lib.rs index a669233e9b9..89c46222e3f 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -10,12 +10,12 @@ pub mod kura; mod merkle; pub mod modules; pub mod queue; +pub mod samples; pub mod smartcontracts; pub mod sumeragi; pub mod torii; pub mod tx; pub mod wsv; -pub mod samples; use std::{path::PathBuf, sync::Arc, time::Duration}; diff --git a/core/src/queue.rs b/core/src/queue.rs index ba052f445df..399310ec3ec 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -1,4 +1,3 @@ - //! Module with queue actor use std::time::Duration; @@ -10,7 +9,7 @@ use iroha_crypto::HashOf; use iroha_data_model::transaction::VersionedTransaction; use thiserror::Error; -pub use self::config::QueueConfiguration; +pub use self::config::Configuration; use crate::{prelude::*, wsv::WorldTrait}; /// Lockfree queue for transactions @@ -56,7 +55,7 @@ pub enum Error { impl Queue { /// Makes queue from configuration - pub fn from_configuration(cfg: &QueueConfiguration) -> Self { + pub fn from_configuration(cfg: &Configuration) -> Self { Self { queue: ArrayQueue::new(cfg.maximum_transactions_in_queue as usize), txs: DashMap::new(), @@ -232,7 +231,7 @@ pub mod config { #[serde(rename_all = "UPPERCASE")] #[serde(default)] #[config(env_prefix = "QUEUE_")] - pub struct QueueConfiguration { + pub struct Configuration { /// The upper limit of the number of transactions per block. pub maximum_transactions_in_block: u32, /// The upper limit of the number of transactions waiting in this queue. @@ -243,7 +242,7 @@ pub mod config { pub future_threshold_ms: u64, } - impl Default for QueueConfiguration { + impl Default for Configuration { fn default() -> Self { Self { maximum_transactions_in_block: DEFAULT_MAXIMUM_TRANSACTIONS_IN_BLOCK, @@ -309,11 +308,11 @@ mod tests { #[test] fn push_tx() { - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); let wsv = WorldStateView::new(world_with_test_domains( KeyPair::generate().unwrap().public_key, @@ -327,11 +326,11 @@ mod tests { #[test] fn push_tx_overflow() { let max_txs_in_queue = 10; - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: max_txs_in_queue, - ..QueueConfiguration::default() + ..Configuration::default() }); let wsv = WorldStateView::new(world_with_test_domains( KeyPair::generate().unwrap().public_key, @@ -353,11 +352,11 @@ mod tests { #[test] fn push_tx_signature_condition_failure() { let max_txs_in_queue = 10; - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: max_txs_in_queue, - ..QueueConfiguration::default() + ..Configuration::default() }); let wsv = WorldStateView::new(world_with_test_domains( KeyPair::generate().unwrap().public_key, @@ -378,11 +377,11 @@ mod tests { #[test] fn push_multisignature_tx() { - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); let tx = Transaction::new( Vec::new(), @@ -421,11 +420,11 @@ mod tests { let max_block_tx = 2; let alice_key = KeyPair::generate().expect("Failed to generate keypair."); let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); for _ in 0..5 { queue @@ -448,11 +447,11 @@ mod tests { let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); let tx = accepted_tx("alice", "wonderland", 100_000, Some(&alice_key)); wsv.transactions.insert(tx.hash()); - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); assert!(matches!( queue.push(tx, &wsv), @@ -467,11 +466,11 @@ mod tests { let alice_key = KeyPair::generate().expect("Failed to generate keypair."); let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); let tx = accepted_tx("alice", "wonderland", 100_000, Some(&alice_key)); - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); queue.push(tx.clone(), &wsv).unwrap(); wsv.transactions.insert(tx.hash()); @@ -484,11 +483,11 @@ mod tests { let max_block_tx = 6; let alice_key = KeyPair::generate().expect("Failed to generate keypair."); let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 200, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); for _ in 0..(max_block_tx - 1) { queue @@ -527,11 +526,11 @@ mod tests { fn transactions_available_after_pop() { let alice_key = KeyPair::generate().expect("Failed to generate keypair."); let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { maximum_transactions_in_block: 2, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100, - ..QueueConfiguration::default() + ..Configuration::default() }); queue .push( @@ -561,11 +560,11 @@ mod tests { let wsv = Arc::new(WorldStateView::new(world_with_test_domains( alice_key.public_key.clone(), ))); - let queue = Arc::new(Queue::from_configuration(&QueueConfiguration { + let queue = Arc::new(Queue::from_configuration(&Configuration { maximum_transactions_in_block: max_block_tx, transaction_time_to_live_ms: 100_000, maximum_transactions_in_queue: 100_000_000, - ..QueueConfiguration::default() + ..Configuration::default() })); let start_time = Instant::now(); @@ -620,9 +619,9 @@ mod tests { #[test] fn push_tx_in_future() { let future_threshold_ms = 1000; - let queue = Queue::from_configuration(&QueueConfiguration { + let queue = Queue::from_configuration(&Configuration { future_threshold_ms, - ..QueueConfiguration::default() + ..Configuration::default() }); let alice_key = KeyPair::generate().expect("Failed to generate keypair."); let wsv = WorldStateView::new(world_with_test_domains(alice_key.public_key.clone())); diff --git a/core/src/samples.rs b/core/src/samples.rs index 30777dc21b2..f0ea4840d9a 100644 --- a/core/src/samples.rs +++ b/core/src/samples.rs @@ -1,23 +1,27 @@ -//! This module contains the sample configurations used for testing throghout Iroha. +#![allow(clippy::restriction)] +//! This module contains the sample configurations used for testing and benchmarking throghout Iroha. +use std::{collections::HashSet, str::FromStr}; + use iroha_crypto::{KeyPair, PublicKey}; -use std::collections::HashSet; -use iroha_data_model::peer::{Id as PeerId}; -use crate::{ - config::Configuration, - torii::config::DEFAULT_TORII_P2P_ADDR, +use iroha_data_model::peer::Id as PeerId; + +use crate::{ block_sync::config::BlockSyncConfiguration, + config::Configuration, genesis::config::GenesisConfiguration, kura::config::KuraConfiguration, - queue::config::QueueConfiguration, + queue::Configuration as QueueConfiguration, sumeragi::config::{SumeragiConfiguration, TrustedPeers}, - torii::config::ToriiConfiguration, + torii::config::{ToriiConfiguration, DEFAULT_TORII_P2P_ADDR}, }; -use std::str::FromStr; /// Get sample trusted peers. The public key must be the same as `configuration.public_key` +/// +/// # Panics +/// Never pub fn get_trusted_peers(public_key: Option<&PublicKey>) -> HashSet { let mut trusted_peers: HashSet = [ - ( + ( "localhost:1338", "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c1", ), @@ -30,31 +34,29 @@ pub fn get_trusted_peers(public_key: Option<&PublicKey>) -> HashSet { "ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c3", ), ] - .iter() - .map(|(a, k)| PeerId { - address: a.to_string(), - public_key: PublicKey::from_str(k).unwrap().clone(), - }) - .collect(); - if let Some(pubkey) = public_key { - trusted_peers.insert(PeerId { - address: DEFAULT_TORII_P2P_ADDR.to_string(), - public_key: pubkey.clone(), - }); - } - trusted_peers + .iter() + .map(|(a, k)| PeerId { + address: (*a).to_string(), + public_key: PublicKey::from_str(k).unwrap(), + }) + .collect(); + if let Some(pubkey) = public_key { + trusted_peers.insert(PeerId { + address: DEFAULT_TORII_P2P_ADDR.to_owned(), + public_key: pubkey.clone(), + }); + } + trusted_peers } +#[allow(clippy::implicit_hasher)] /// Get a sample Iroha configuration. Trusted peers must either be /// specified in this function, including the current peer. Use [`samples::get_trusted_peers`] /// to populate `trusted_peers` if in doubt. /// /// # Panics -/// when [`KeyPair`] generation fails (rare). -pub fn get_config( - trusted_peers: HashSet, - key_pair: Option, -) -> Configuration { +/// when [`KeyPair`] generation fails (rare). +pub fn get_config(trusted_peers: HashSet, key_pair: Option) -> Configuration { let (public_key, private_key) = match key_pair { Some(key_pair) => key_pair.into(), None => KeyPair::generate() @@ -75,7 +77,7 @@ pub fn get_config( public_key: public_key.clone(), private_key: private_key.clone(), }, - peer_id: PeerId::new(DEFAULT_TORII_P2P_ADDR, &public_key.clone()), + peer_id: PeerId::new(DEFAULT_TORII_P2P_ADDR, &public_key), block_time_ms: 1000, trusted_peers: TrustedPeers { peers: trusted_peers, @@ -85,7 +87,7 @@ pub fn get_config( ..SumeragiConfiguration::default() }, torii: ToriiConfiguration { - max_transaction_size: 32768, + max_transaction_size: 0x8000, ..ToriiConfiguration::default() }, block_sync: BlockSyncConfiguration { @@ -98,13 +100,10 @@ pub fn get_config( ..QueueConfiguration::default() }, genesis: GenesisConfiguration { - account_public_key: Some(public_key.clone()), - account_private_key: Some(private_key.clone()), + account_public_key: Some(public_key), + account_private_key: Some(private_key), ..GenesisConfiguration::default() }, ..Configuration::default() } } - - - diff --git a/core/src/torii/mod.rs b/core/src/torii/mod.rs index b34d8f095b4..05937bd926a 100644 --- a/core/src/torii/mod.rs +++ b/core/src/torii/mod.rs @@ -389,10 +389,15 @@ pub mod config { use iroha_config::derive::Configurable; use serde::{Deserialize, Serialize}; + /// Default socket for p2p communication pub const DEFAULT_TORII_P2P_ADDR: &str = "127.0.0.1:1337"; + /// Default socket for listening on external requests. pub const DEFAULT_TORII_API_URL: &str = "127.0.0.1:8080"; + /// Default maximum size of single transaction. pub const DEFAULT_TORII_MAX_TRANSACTION_SIZE: usize = 2_usize.pow(15); + /// Default maximum instruction number pub const DEFAULT_TORII_MAX_INSTRUCTION_NUMBER: u64 = 2_u64.pow(12); + /// Default maxiumum size of [`Sumeragi`] message size. pub const DEFAULT_TORII_MAX_SUMERAGI_MESSAGE_SIZE: usize = 2_usize.pow(12) * 4000; /// `ToriiConfiguration` provides an ability to define parameters such as `TORII_URL`. @@ -427,16 +432,21 @@ pub mod config { } #[cfg(test)] -pub mod tests { +mod tests { #![allow(clippy::pedantic, clippy::restriction)] use std::{convert::TryInto, time::Duration}; use futures::future::FutureExt; use tokio::time; - use crate::samples::{get_config, get_trusted_peers}; + use super::*; - use crate::{queue::Queue, smartcontracts::permissions::DenyAll, wsv::World}; + use crate::{ + queue::Queue, + samples::{get_config, get_trusted_peers}, + smartcontracts::permissions::DenyAll, + wsv::World, + }; fn create_torii() -> (Torii, KeyPair) { let config = get_config(get_trusted_peers(None), None); diff --git a/core/src/tx.rs b/core/src/tx.rs index 8b0c254269c..875a5c26aea 100644 --- a/core/src/tx.rs +++ b/core/src/tx.rs @@ -502,13 +502,20 @@ mod tests { }; use super::*; - use crate::{init, smartcontracts::permissions::AllowAll, wsv::World}; - use crate::samples::{get_config, get_trusted_peers}; - + use crate::{ + init, + samples::{get_config, get_trusted_peers}, + smartcontracts::permissions::AllowAll, + wsv::World, + }; + #[test] fn hash_should_be_the_same() { let key_pair = &KeyPair::generate().expect("Failed to generate key pair."); - let mut config = get_config(get_trusted_peers(Some(&key_pair.public_key)), Some(key_pair.clone())); + let mut config = get_config( + get_trusted_peers(Some(&key_pair.public_key)), + Some(key_pair.clone()), + ); config.genesis.account_private_key = Some(key_pair.private_key.clone()); config.genesis.account_public_key = Some(key_pair.public_key.clone()); diff --git a/core/test_network/Cargo.toml b/core/test_network/Cargo.toml index 2e1cd510602..f300d80fc42 100644 --- a/core/test_network/Cargo.toml +++ b/core/test_network/Cargo.toml @@ -28,6 +28,7 @@ futures = { version = "0.3.17", default-features = false, features = ["std", "as [dev-dependencies] iroha_crypto = { path = "../../crypto" } + async-trait = "0.1" color-eyre = "0.5.11" once_cell = "1" diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index f51aa10c59e..7387636e2ab 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -25,7 +25,6 @@ use iroha_core::{ wsv::{World, WorldTrait}, Iroha, }; -use iroha_crypto::ursa::signatures::EcdsaPublicKeyHandler; use iroha_data_model::{peer::Peer as DataModelPeer, prelude::*}; use iroha_logger::{ config::{LevelEnv, LoggerConfiguration}, @@ -108,12 +107,7 @@ impl std::cmp::PartialEq for Peer { impl std::cmp::Eq for Peer {} -// pub const CONFIGURATION_PATH: &str = "../configs/test_network/test_config.json"; -// pub const CLIENT_CONFIGURATION_PATH: &str = "../configs/test_network/test_client_config.json"; -// pub const GENESIS_PATH: &str = "../configs/test_network/genesis.json"; -// pub const TRUSTED_PEERS_PATH: &str = "../configs/test_network/test_trusted_peers.json"; - -fn get_key_pair() -> KeyPair { +pub fn get_key_pair() -> KeyPair { KeyPair { public_key: PublicKey::from_str( r#"ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"#, @@ -145,25 +139,28 @@ impl TestGenesis for G { let cfg = Configuration::test(); let mut genesis = RawGenesisBlock::from(("alice", "wonderland", &get_key_pair().public_key)); - genesis.transactions[0].isi.push(RegisterBox::new( - IdentifiableBox::AssetDefinition( + genesis.transactions[0].isi.push( + RegisterBox::new(IdentifiableBox::AssetDefinition( AssetDefinition::new_quantity(AssetDefinitionId::new("rose", "wonderland")).into(), )) - .into() + .into(), ); - genesis.transactions[0].isi.push(RegisterBox::new( - IdentifiableBox::AssetDefinition( + genesis.transactions[0].isi.push( + RegisterBox::new(IdentifiableBox::AssetDefinition( AssetDefinition::new_quantity(AssetDefinitionId::new("tulip", "wonderland")).into(), )) - .into() + .into(), + ); + genesis.transactions[0].isi.push( + MintBox::new( + Value::U32(13), + IdBox::AssetId(AssetId::new( + AssetDefinitionId::new("rose", "wonderland"), + AccountId::new("alice", "wonderland"), + )), + ) + .into(), ); - genesis.transactions[0].isi.push(MintBox::new( - Value::U32(13), - IdBox::AssetId(AssetId::new( - AssetDefinitionId::new("rose", "wonderland"), - AccountId::new("alice", "wonderland"))) - ) - .into()); G::from_configuration( submit_genesis, genesis, @@ -375,7 +372,7 @@ where } } - /// Returns per peer config with all addresses, keys, and id setted up + /// Returns per peer config with all addresses, keys, and id set up fn get_config(&self, configuration: Configuration) -> Configuration { Configuration { sumeragi: SumeragiConfiguration { @@ -666,8 +663,6 @@ use std::collections::HashSet; impl TestConfiguration for Configuration { fn test() -> Self { - // let mut configuration = - // Self::from_path(CONFIGURATION_PATH).expect("Failed to load configuration."); let mut configuration = iroha_core::samples::get_config(HashSet::new(), Some(get_key_pair())); configuration @@ -692,8 +687,6 @@ use std::str::FromStr; impl TestClientConfiguration for ClientConfiguration { fn test(api_url: &str) -> Self { - // let mut configuration = ClientConfiguration::from_path(CLIENT_CONFIGURATION_PATH) - // .expect("Failed to load configuration."); let mut configuration = iroha_client::samples::get_client_config(&get_key_pair()); if !api_url.starts_with("http") { configuration.torii_api_url = "http://".to_owned() + api_url; diff --git a/data_model/tests/data_model.rs b/data_model/tests/data_model.rs index b0938e894c5..3ca33725c14 100644 --- a/data_model/tests/data_model.rs +++ b/data_model/tests/data_model.rs @@ -8,11 +8,6 @@ use iroha_data_model::prelude::*; use test_network::{Peer as TestPeer, TestRuntime}; use tokio::runtime::Runtime; -// const CONFIGURATION_PATH: &str = "../configs/test_config.json"; -// const TRUSTED_PEERS_PATH: &str = "../configs/test_trusted_peers.json"; -// const CLIENT_CONFIGURATION_PATH: &str = "../configs/test_client_config.json"; -// const GENESIS_PATH: &str = "../configs/test_genesis.json"; - #[test] fn find_rate_and_make_exchange_isi_should_be_valid() { let _instruction = Pair::new( @@ -97,41 +92,47 @@ fn find_rate_and_check_it_greater_than_value_predefined_isi_should_be_valid() { let _instruction = FindRateAndCheckItGreaterThanValue::new("btc", "eth", 10).into_isi(); } -use iroha_core::prelude::*; use std::str::FromStr; -use iroha_core::samples::get_config; + use iroha_client::samples::get_client_config; +use iroha_core::{prelude::*, samples::get_config}; #[test] fn find_rate_and_make_exchange_isi_should_succeed() { - let kp = KeyPair{ - public_key: PublicKey::from_str(r#"ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"#).unwrap(), - private_key: PrivateKey{ - digest_function: "ed25519".to_string(), - payload: hex_literal::hex!("9AC47ABF 59B356E0 + let kp = KeyPair { + public_key: PublicKey::from_str( + r#"ed01207233bfc89dcbd68c19fde6ce6158225298ec1131b6a130d1aeb454c1ab5183c0"#, + ) + .unwrap(), + private_key: PrivateKey { + digest_function: "ed25519".to_string(), + payload: hex_literal::hex!( + "9AC47ABF 59B356E0 BD7DCBBB B4DEC080 E302156A 48CA907E 47CB6AEA 1D32719E 7233BFC8 9DCBD68C 19FDE6CE 61582252 98EC1131 B6A130D1 - AEB454C1 AB5183C0").into() - } - }; - let mut peer = ::new().expect("Failed to create peer"); - let configuration = get_config(std::iter::once(peer.id.clone()).collect(), Some(kp.clone())); + AEB454C1 AB5183C0" + ) + .into(), + }, + }; + let mut peer = ::new().expect("Failed to create peer"); + let configuration = get_config(std::iter::once(peer.id.clone()).collect(), Some(kp.clone())); let pipeline_time = Duration::from_millis(configuration.sumeragi.pipeline_time_ms()); // Given let genesis = GenesisNetwork::from_configuration( true, - ("alice", "wonderland", &kp.public_key).into(), + ("alice", "wonderland", &kp.public_key).into(), &configuration.genesis, configuration.sumeragi.max_instruction_number, ) .unwrap(); let rt = Runtime::test(); - let mut client_configuration = get_client_config(&configuration.sumeragi.key_pair); + let mut client_configuration = get_client_config(&configuration.sumeragi.key_pair); rt.block_on(peer.start_with_config(genesis, configuration)); thread::sleep(pipeline_time); diff --git a/docs/source/references/config.md b/docs/source/references/config.md index d05ff4adc76..1f88f2c8656 100644 --- a/docs/source/references/config.md +++ b/docs/source/references/config.md @@ -59,8 +59,8 @@ The following is the default configuration used by Iroha. "GENESIS": { "ACCOUNT_PUBLIC_KEY": null, "ACCOUNT_PRIVATE_KEY": null, - "WAIT_FOR_PEERS_RETRY_COUNT": 0, - "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 0 + "WAIT_FOR_PEERS_RETRY_COUNT": 100, + "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500 }, "WSV": { "ASSET_METADATA_LIMITS": { @@ -151,8 +151,8 @@ Has type `GenesisConfiguration`. Can be configured via environment variable `IRO { "ACCOUNT_PRIVATE_KEY": null, "ACCOUNT_PUBLIC_KEY": null, - "WAIT_FOR_PEERS_RETRY_COUNT": 0, - "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 0 + "WAIT_FOR_PEERS_RETRY_COUNT": 100, + "WAIT_FOR_PEERS_RETRY_PERIOD_MS": 500 } ``` @@ -183,7 +183,7 @@ 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` ```json -0 +100 ``` ### `genesis.wait_for_peers_retry_period_ms` @@ -193,7 +193,7 @@ Period in milliseconds in which to retry connecting to peers, while waiting for Has type `u64`. Can be configured via environment variable `IROHA_GENESIS_WAIT_FOR_PEERS_RETRY_PERIOD_MS` ```json -0 +500 ``` ## `kura` diff --git a/docs/source/references/glossary.md b/docs/source/references/glossary.md index 81c3c344eea..ebec8525db4 100644 --- a/docs/source/references/glossary.md +++ b/docs/source/references/glossary.md @@ -1,133 +1,82 @@ # Glossary -//TODO: add links to docs.rs - Definitions of all Iroha-related entities can be found here. -# Asset +## Asset A representation of a valuable object on the blockchain. - -## Byzantine Fault-tolerance (BFT) - -The property of being able to properly function with a network -containing a certain percentage of malicious actors. Iroha is capable -of functioning with up to 33% malicious actors in its peer-to-peer -network. +## Byzantine fault-tolerance (BFT) {#bft} +The property of being able to properly function with a network containing a certain percentage of malicious actors. Iroha is capable of functioning with up to 33% malicious actors in its peer-to-peer network. ## Leader +In an iroha network a peer is selected randomly and granted the special privilege of forming the next block. This privilege can be revoked in networks that achieve [Byzantine fault-torelance](#bft) via [view change](#view-change). -In an iroha network a peer is selected randomly and granted the -special privilege of forming the next block. - -## World State View (WSV) - -In-memory representation of the current blockchain state. This -includes all currently loaded blocks, with all of their contents, as -well as peers elected for the current epoch. +## World state view (WSV) {#wsv} +In-memory representation of the current blockchain state. This includes all currently loaded blocks, with all of their contents, as well as peers elected for the current epoch. ## View change - -A process that takes place in case of a failed attempt at consensus. -Usually this entails the election of a new [Leader](#leader). +A process that takes place in case of a failed attempt at consensus. Usually this entails the election of a new [Leader](#leader). ## Iroha Query +A request to read the World State View without modifying said view. -A request to read the [World State View](#world-state-view) without -modifying said view. - -## Iroha Special Instruction (ISI) - -A library of smart contracts provided with Iroha. These can be -invoked via either transactions or registered event listeners. - -### Trigger - -Triggers are Iroha Special Instructions registered on -[peer](#peer). Their execution depends on some conditions, for example -on the blockchain height, time or [query](#iroha-query) result. - -#### Utility Iroha Special Instruction +## Iroha Special Instruction (ISI) {#isi} +A library of smart contracts provided with Iroha. These can be invoked via either transactions or registered event listeners. -This set contains logical instructions like `If`, I/O related like -`Notify` and compositions like `Sequence`. They are mostly used by -[custom Instructions](#custom-iroha-special-instruction). +#### Utility Iroha special instruction {#utility} +This set of [isi](#isi) contains logical instructions like `If`, I/O related like `Notify` and compositions like `Sequence`. They are mostly used by [custom Instructions](#custom-iroha-special-instruction). -### Core Iroha Special Instruction +### Core Iroha Special Instruction {#core} +[Special instructions](#isi) provided with every Iroha deployment. These include some [domain-specific](#dsisi) as well as [utility instructions](#utility). -Special instructions provided with every Iroha deployment. These -include some domain-specific as well as utility instructions. - - -### Domain-specific Iroha Special Instruction - -Instructions related to domain-specific activities: -(asset/account/domain/peer management). These provide the tools -necessary to make changes to the [World State View](#world-state-view) -in a secure and safe manner. +### Domain-specific Iroha Special Instruction {#dsisi} +Instructions related to domain-specific activities: (asset/account/domain/peer management). These provide the tools necessary to make changes to the [World State View](#wsv) in a secure and safe manner. ### Custom Iroha Special Instruction +Instructions provided in [Iroha Modules](#mod), by clients or 3rd parties. These can only be built using [the Core Instructions](#core). Forking and modifying the Iroha source code is not recommended, as special instructions not agreed-upon by peers in an Iroha deployment will be treated as faults, thus peers running a modified instance will have their access revoked. -Instructions provided in [Iroha Modules](#todo), by clients or 3rd -parties. These can only be built using [the Core -Instructions](#core-iroha-special-instruction). Forking and modifying -the Iroha source code is not recommended, as special instructions not -agreed upon by peers in an Iroha deployment will be treated as faults -and your peers running a modified instance will have their access -revoked. - -# Iroha Components - -Rust modules containing Iroha's functionality. - -## Sumeragi +## Iroha Components +Rust modules containing Iroha's functionality. +### Sumeragi (Emperor) The Iroha module responsible for consensus. -## Torii (Gate) +### Torii (Gate) +Module with the incoming request handling logic for the peer. It is used to receive, accept and route incoming instructions, and HTTP queries, as well as run-time configuration updates. -Module with the incoming request handling logic for the peer. It is -used to receive accept and route incoming instructions, and HTTP -queries, as well as run-time configuration updates. +### Kura (Warehouse) +Persistence-related logic. It handles storing the blocks, log rotation, block storage folder rotation etc. -## Kura (Warehouse) +### Merkle tree (hash tree) +A data structure used to validate and verify the state at each block height. Iroha's current implementation is a binary tree. See [Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree) for more details. -Persistence-related logic. It handles storing the blocks, log -rotation, block storage folder rotation etc. - -## Merkle tree (hash tree) - -A data structure used to validate and verify the state at each block -height. Iroha's current implementation is a binary tree. See -[Wikipedia](https://en.wikipedia.org/wiki/Merkle_tree) for more -details. - -## Smart contracts - -Smart contracts are blockchain-based programs that run when a specific -set of conditions is met. In Iroha smart contracts are implemented -using core Iroha special instructions. +### Smart contracts +Smart contracts are blockchain-based programs that run when a specific set of conditions is met. In Iroha smart contracts are implemented using core Iroha special instructions. ### Triggers +An event type that allows invoking an Iroha special instruction at specific block commit, time (with some caveats) etc. More details can be found on our dedicated [wiki page](https://wiki.hyperledger.org/display/iroha/Triggers). -An event type that allows invoking an Iroha special instruction at -specific block commit, time (with some caveats) etc. More details can -be found on our dedicated [wiki -page](https://wiki.hyperledger.org/display/iroha/Triggers). - -## Versioning +### Versioning +Each request is labelled with the API version to which it belongs. It allows a combination of different binary versions of Iroha client/peer software to interoperate, which in turn allows software upgrades in the Iroha network. -Each request is labelled with the API version to which it belongs. It -allows a combination of different binary versions of Iroha client/peer -software to interoperate, which in turn allows software upgrades in -the Iroha network. +### Hijiri (peer reputation system) +Iroha's reputation system. It allows prioritising communication with peers that have a good track-record, and reducing the harm that can be caused by malicious peers. -## Hijiri (peer reputation system) +## Iroha modules {#mod} +Third party extensions to Iroha that provide custom functionality. -Iroha's reputation system. It allows prioritising communication with -peers that have a good track-record, and reducing the harm that can be -caused by malicious peers. +# Table of contents +- [Glossary](#glossary) + - [Asset](#asset) + - [Byzantine fault-tolerance (BFT) {#bft}](#byzantine-fault-tolerance-bft-bft) + - [Leader](#leader) + - [World state view (WSV) {#wsv}](#world-state-view-wsv-wsv) + - [View change](#view-change) + - [Iroha Query](#iroha-query) + - [Iroha Special Instruction (ISI) {#isi}](#iroha-special-instruction-isi-isi) + - [Iroha Components](#iroha-components) + - [Iroha modules {#mod}](#iroha-modules-mod)