diff --git a/cli/src/lib.rs b/cli/src/lib.rs index b84c0ebbea8..2551560fa75 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -294,8 +294,7 @@ impl Iroha { None } }.unwrap_or_else(|| { - State::from_config( - config.chain_wide, + State::new( world, Arc::clone(&kura), live_query_store_handle.clone(), diff --git a/cli/src/samples.rs b/cli/src/samples.rs index 5aaa54701a5..b03d96279bd 100644 --- a/cli/src/samples.rs +++ b/cli/src/samples.rs @@ -67,9 +67,8 @@ pub fn get_config_toml( .write(["sumeragi", "trusted_peers"], peers) .write(["network", "address"], DEFAULT_P2P_ADDR) .write(["network", "block_gossip_period_ms"], 500) - .write(["network", "block_gossip_max_size"], 1) + .write(["network", "block_gossip_size"], 1) .write(["torii", "address"], DEFAULT_TORII_ADDR) - .write(["chain_wide", "max_transactions_in_block"], 2) .write(["genesis", "public_key"], genesis_public_key) .write( ["genesis", "signed_file"], diff --git a/client/benches/tps/utils.rs b/client/benches/tps/utils.rs index c2d3c2e4875..0c376b9347f 100644 --- a/client/benches/tps/utils.rs +++ b/client/benches/tps/utils.rs @@ -6,10 +6,10 @@ use iroha::{ crypto::KeyPair, data_model::{ events::pipeline::{BlockEventFilter, BlockStatus}, - parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, prelude::*, }, }; +use iroha_data_model::param::BlockLimits; use nonzero_ext::nonzero; use serde::Deserialize; use test_network::*; @@ -22,7 +22,7 @@ pub struct Config { pub peers: u32, /// Interval in microseconds between transactions to reduce load pub interval_us_per_tx: u64, - pub max_txs_per_block: u32, + pub block_limits: BlockLimits, pub blocks: u32, pub sample_size: u32, pub genesis_max_retries: u32, @@ -33,11 +33,7 @@ impl fmt::Display for Config { write!( f, "{}peers-{}interval_µs-{}max_txs-{}blocks-{}samples", - self.peers, - self.interval_us_per_tx, - self.max_txs_per_block, - self.blocks, - self.sample_size, + self.peers, self.interval_us_per_tx, self.block_limits, self.blocks, self.sample_size, ) } } @@ -55,11 +51,7 @@ impl Config { let clients = network.clients(); wait_for_genesis_committed_with_max_retries(&clients, 0, self.genesis_max_retries); - client.submit_all_blocking( - ParametersBuilder::new() - .add_parameter(MAX_TRANSACTIONS_IN_BLOCK, self.max_txs_per_block)? - .into_set_parameters(), - )?; + client.submit_blocking(SetParameter::new(Parameter::BlockLimits(self.block_limits)))?; let unit_names = (UnitName::MIN..).take(self.peers as usize); let units = clients diff --git a/client/examples/register_1000_triggers.rs b/client/examples/register_1000_triggers.rs index 567dd9d3317..714c15cc454 100644 --- a/client/examples/register_1000_triggers.rs +++ b/client/examples/register_1000_triggers.rs @@ -64,17 +64,13 @@ fn main() -> Result<(), Box> { let chain_id = get_chain_id(); let genesis_key_pair = get_key_pair(test_network::Signatory::Genesis); let topology = vec![peer.id.clone()]; - let mut configuration = get_config( + let configuration = get_config( unique_vec![peer.id.clone()], chain_id.clone(), get_key_pair(test_network::Signatory::Peer), genesis_key_pair.public_key(), ); - // Increase executor limits for large genesis - configuration.chain_wide.executor_runtime.fuel_limit = u64::MAX; - configuration.chain_wide.executor_runtime.max_memory = u32::MAX.into(); - let genesis = generate_genesis(1_000_u32, chain_id, &genesis_key_pair, topology)?; let builder = PeerBuilder::new() diff --git a/client/examples/tutorial.rs b/client/examples/tutorial.rs index 1589b8d78ad..4718137ab0c 100644 --- a/client/examples/tutorial.rs +++ b/client/examples/tutorial.rs @@ -34,7 +34,7 @@ fn domain_registration_test(config: Config) -> Result<(), Error> { use iroha::{ client::Client, data_model::{ - metadata::UnlimitedMetadata, + metadata::Metadata, prelude::{Domain, DomainId, InstructionBox, Register}, }, }; @@ -57,7 +57,7 @@ fn domain_registration_test(config: Config) -> Result<(), Error> { // #region domain_register_example_prepare_tx // Prepare a transaction - let metadata = UnlimitedMetadata::default(); + let metadata = Metadata::default(); let instructions: Vec = vec![create_looking_glass.into()]; let tx = iroha.build_transaction(instructions, metadata); // #endregion domain_register_example_prepare_tx @@ -101,7 +101,7 @@ fn account_registration_test(config: Config) -> Result<(), Error> { client::Client, crypto::KeyPair, data_model::{ - metadata::UnlimitedMetadata, + metadata::Metadata, prelude::{Account, AccountId, InstructionBox, Register}, }, }; @@ -127,7 +127,7 @@ fn account_registration_test(config: Config) -> Result<(), Error> { // #region register_account_prepare_tx // Prepare a transaction using the // Account's RegisterBox - let metadata = UnlimitedMetadata::new(); + let metadata = Metadata::default(); let instructions: Vec = vec![create_account.into()]; let tx = iroha.build_transaction(instructions, metadata); // #endregion register_account_prepare_tx diff --git a/client/src/client.rs b/client/src/client.rs index c97eda480e9..d211953a3b4 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -331,6 +331,7 @@ impl_query_output! { crate::data_model::executor::ExecutorDataModel, crate::data_model::trigger::Trigger, crate::data_model::prelude::Numeric, + crate::data_model::param::Parameters, } /// Iroha client @@ -452,7 +453,7 @@ impl Client { pub fn build_transaction( &self, instructions: impl Into, - metadata: UnlimitedMetadata, + metadata: Metadata, ) -> SignedTransaction { let tx_builder = TransactionBuilder::new(self.chain.clone(), self.account.clone()); @@ -509,7 +510,7 @@ impl Client { &self, instructions: impl IntoIterator, ) -> Result> { - self.submit_all_with_metadata(instructions, UnlimitedMetadata::new()) + self.submit_all_with_metadata(instructions, Metadata::default()) } /// Instructions API entry point. Submits one Iroha Special Instruction to `Iroha` peers. @@ -521,7 +522,7 @@ impl Client { pub fn submit_with_metadata( &self, instruction: impl Instruction, - metadata: UnlimitedMetadata, + metadata: Metadata, ) -> Result> { self.submit_all_with_metadata([instruction], metadata) } @@ -535,7 +536,7 @@ impl Client { pub fn submit_all_with_metadata( &self, instructions: impl IntoIterator, - metadata: UnlimitedMetadata, + metadata: Metadata, ) -> Result> { self.submit_transaction(&self.build_transaction(instructions, metadata)) } @@ -718,7 +719,7 @@ impl Client { &self, instructions: impl IntoIterator, ) -> Result> { - self.submit_all_blocking_with_metadata(instructions, UnlimitedMetadata::new()) + self.submit_all_blocking_with_metadata(instructions, Metadata::default()) } /// Submits and waits until the transaction is either rejected or committed. @@ -730,7 +731,7 @@ impl Client { pub fn submit_blocking_with_metadata( &self, instruction: impl Instruction, - metadata: UnlimitedMetadata, + metadata: Metadata, ) -> Result> { self.submit_all_blocking_with_metadata(vec![instruction.into()], metadata) } @@ -744,7 +745,7 @@ impl Client { pub fn submit_all_blocking_with_metadata( &self, instructions: impl IntoIterator, - metadata: UnlimitedMetadata, + metadata: Metadata, ) -> Result> { let transaction = self.build_transaction(instructions, metadata); self.submit_transaction_blocking(&transaction) @@ -1620,7 +1621,7 @@ mod tests { }); let build_transaction = - || client.build_transaction(Vec::::new(), UnlimitedMetadata::new()); + || client.build_transaction(Vec::::new(), Metadata::default()); let tx1 = build_transaction(); let tx2 = build_transaction(); assert_ne!(tx1.hash(), tx2.hash()); diff --git a/client/tests/integration/add_domain.rs b/client/tests/integration/add_domain.rs index 514e18b85d6..edb3f4810c1 100644 --- a/client/tests/integration/add_domain.rs +++ b/client/tests/integration/add_domain.rs @@ -6,8 +6,7 @@ use iroha_config::parameters::actual::Root as Config; use test_network::*; #[test] -// This test suite is also covered at the UI level in the iroha_cli tests -// in test_register_domains.py +#[ignore = "should be implemented with custom parameters"] fn client_add_domain_with_name_length_more_than_limit_should_not_commit_transaction() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(10_500).start_with_runtime(); diff --git a/client/tests/integration/asset.rs b/client/tests/integration/asset.rs index f0fe33e8fd9..390b472b659 100644 --- a/client/tests/integration/asset.rs +++ b/client/tests/integration/asset.rs @@ -106,7 +106,7 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount() -> let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let create_asset = Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let metadata = iroha::data_model::metadata::UnlimitedMetadata::default(); + let metadata = iroha::data_model::metadata::Metadata::default(); //When let quantity = numeric!(200); let mint = Mint::asset_numeric( @@ -137,7 +137,7 @@ fn client_add_big_asset_quantity_to_existing_asset_should_increase_asset_amount( let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let create_asset = Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let metadata = iroha::data_model::metadata::UnlimitedMetadata::default(); + let metadata = iroha::data_model::metadata::Metadata::default(); //When let quantity = Numeric::new(2_u128.pow(65), 0); let mint = Mint::asset_numeric( @@ -168,7 +168,7 @@ fn client_add_asset_with_decimal_should_increase_asset_amount() -> Result<()> { let asset_definition_id = AssetDefinitionId::from_str("xor#wonderland").expect("Valid"); let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()); let create_asset = Register::asset_definition(asset_definition); - let metadata = iroha::data_model::metadata::UnlimitedMetadata::default(); + let metadata = iroha::data_model::metadata::Metadata::default(); //When let quantity = numeric!(123.456); diff --git a/client/tests/integration/asset_propagation.rs b/client/tests/integration/asset_propagation.rs index bcf99a5ca9c..54f4df0034f 100644 --- a/client/tests/integration/asset_propagation.rs +++ b/client/tests/integration/asset_propagation.rs @@ -1,14 +1,12 @@ -use std::{str::FromStr as _, thread}; +use std::{num::NonZeroU64, str::FromStr as _, thread}; use eyre::Result; use iroha::{ client::{self, QueryResult}, - data_model::{ - parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, - prelude::*, - }, + data_model::prelude::*, }; use iroha_config::parameters::actual::Root as Config; +use iroha_data_model::param::BlockLimits; use test_network::*; use test_samples::gen_account_in; @@ -22,11 +20,9 @@ fn client_add_asset_quantity_to_existing_asset_should_increase_asset_amount_on_a wait_for_genesis_committed(&network.clients(), 0); let pipeline_time = Config::pipeline_time(); - client.submit_all_blocking( - ParametersBuilder::new() - .add_parameter(MAX_TRANSACTIONS_IN_BLOCK, 1u32)? - .into_set_parameters(), - )?; + client.submit_blocking(SetParameter::new(Parameter::BlockLimits(BlockLimits { + max_transactions: NonZeroU64::new(1).unwrap(), + })))?; let create_domain: InstructionBox = Register::domain(Domain::new(DomainId::from_str("domain")?)).into(); diff --git a/client/tests/integration/events/data.rs b/client/tests/integration/events/data.rs index 1e35a9819ed..5c3db17605f 100644 --- a/client/tests/integration/events/data.rs +++ b/client/tests/integration/events/data.rs @@ -151,7 +151,7 @@ fn transaction_execution_should_produce_events( // submit transaction to produce events init_receiver.recv()?; - let transaction = client.build_transaction(executable, UnlimitedMetadata::new()); + let transaction = client.build_transaction(executable, Metadata::default()); client.submit_transaction_blocking(&transaction)?; // assertion @@ -161,9 +161,9 @@ fn transaction_execution_should_produce_events( iroha_logger::info!("Event: {:?}", event); assert!(matches!(event, DataEvent::Domain(_))); if let DataEvent::Domain(domain_event) = event { - assert!(matches!(domain_event, DomainEvent::Created(_))); + assert!(matches!(domain_event, DomainEvent::Create(_))); - if let DomainEvent::Created(created_domain) = domain_event { + if let DomainEvent::Create(created_domain) = domain_event { let domain_id = DomainId::new(i.to_string().parse().expect("Valid")); assert_eq!(domain_id, *created_domain.id()); } @@ -226,9 +226,9 @@ fn produce_multiple_events() -> Result<()> { let event: DataEvent = event_receiver.recv()??.try_into()?; assert!(matches!(event, DataEvent::Role(_))); if let DataEvent::Role(role_event) = event { - assert!(matches!(role_event, RoleEvent::Created(_))); + assert!(matches!(role_event, RoleEvent::Create(_))); - if let RoleEvent::Created(created_role) = role_event { + if let RoleEvent::Create(created_role) = role_event { assert_eq!(created_role.id(), role.id()); assert!(created_role .permissions() @@ -237,43 +237,43 @@ fn produce_multiple_events() -> Result<()> { } let expected_domain_events: Vec = [ - DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded( + DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdd( AccountPermissionChanged { account: bob_id.clone(), permission: token_1.id.clone(), }, ))), - DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdded( + DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionAdd( AccountPermissionChanged { account: bob_id.clone(), permission: token_2.id.clone(), }, ))), - DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleGranted( + DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleGrant( AccountRoleChanged { account: bob_id.clone(), role: role_id.clone(), }, ))), - DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved( + DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemove( AccountPermissionChanged { account: bob_id.clone(), permission: token_1.id, }, ))), - DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemoved( + DataEvent::Domain(DomainEvent::Account(AccountEvent::PermissionRemove( AccountPermissionChanged { account: bob_id.clone(), permission: token_2.id, }, ))), - DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleRevoked( + DataEvent::Domain(DomainEvent::Account(AccountEvent::RoleRevoke( AccountRoleChanged { account: bob_id, role: role_id.clone(), }, ))), - DataEvent::Role(RoleEvent::Deleted(role_id)), + DataEvent::Role(RoleEvent::Delete(role_id)), ] .into_iter() .map(Into::into) diff --git a/client/tests/integration/events/pipeline.rs b/client/tests/integration/events/pipeline.rs index 6d78d8685ad..d3c87533f0b 100644 --- a/client/tests/integration/events/pipeline.rs +++ b/client/tests/integration/events/pipeline.rs @@ -1,5 +1,5 @@ use std::{ - num::NonZeroUsize, + num::NonZeroU64, thread::{self, JoinHandle}, }; @@ -11,13 +11,13 @@ use iroha::{ BlockEvent, BlockEventFilter, BlockStatus, TransactionEventFilter, TransactionStatus, }, isi::error::InstructionExecutionError, - parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, prelude::*, transaction::error::TransactionRejectionReason, ValidationFail, }, }; use iroha_config::parameters::actual::Root as Config; +use iroha_data_model::param::BlockLimits; use test_network::*; // Needed to re-enable ignored tests. @@ -56,15 +56,13 @@ fn test_with_instruction_and_status_and_port( wait_for_genesis_committed(&clients, 0); let pipeline_time = Config::pipeline_time(); - client.submit_all_blocking( - ParametersBuilder::new() - .add_parameter(MAX_TRANSACTIONS_IN_BLOCK, 1u32)? - .into_set_parameters(), - )?; + client.submit_blocking(SetParameter::new(Parameter::BlockLimits(BlockLimits { + max_transactions: NonZeroU64::new(1).unwrap(), + })))?; // Given let submitter = client; - let transaction = submitter.build_transaction(instruction, UnlimitedMetadata::new()); + let transaction = submitter.build_transaction(instruction, Metadata::default()); let hash = transaction.hash(); let mut handles = Vec::new(); for listener in clients { @@ -130,8 +128,6 @@ fn applied_block_must_be_available_in_kura() { .as_ref() .expect("Must be some") .kura() - .get_block_by_height( - NonZeroUsize::new(event.header().height().try_into().unwrap()).unwrap(), - ) + .get_block_by_height(event.header().height().try_into().unwrap()) .expect("Block applied event was received earlier"); } diff --git a/client/tests/integration/extra_functional/multiple_blocks_created.rs b/client/tests/integration/extra_functional/multiple_blocks_created.rs index 458af606d10..7646e457f54 100644 --- a/client/tests/integration/extra_functional/multiple_blocks_created.rs +++ b/client/tests/integration/extra_functional/multiple_blocks_created.rs @@ -1,14 +1,12 @@ -use std::thread; +use std::{num::NonZeroU64, thread}; use eyre::Result; use iroha::{ client::{self, Client, QueryResult}, - data_model::{ - parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, - prelude::*, - }, + data_model::prelude::*, }; use iroha_config::parameters::actual::Root as Config; +use iroha_data_model::param::BlockLimits; use test_network::*; use test_samples::gen_account_in; @@ -22,11 +20,9 @@ fn long_multiple_blocks_created() -> Result<()> { wait_for_genesis_committed(&network.clients(), 0); let pipeline_time = Config::pipeline_time(); - client.submit_all_blocking( - ParametersBuilder::new() - .add_parameter(MAX_TRANSACTIONS_IN_BLOCK, 1u32)? - .into_set_parameters(), - )?; + client.submit_blocking(SetParameter::new(Parameter::BlockLimits(BlockLimits { + max_transactions: NonZeroU64::new(1).unwrap(), + })))?; let create_domain: InstructionBox = Register::domain(Domain::new("domain".parse()?)).into(); let (account_id, _account_keypair) = gen_account_in("domain"); diff --git a/client/tests/integration/extra_functional/normal.rs b/client/tests/integration/extra_functional/normal.rs index c278deafa96..6c94ea2a02f 100644 --- a/client/tests/integration/extra_functional/normal.rs +++ b/client/tests/integration/extra_functional/normal.rs @@ -1,8 +1,8 @@ -use std::num::NonZeroU32; +use std::num::NonZeroU64; use iroha::client::{self, Client}; use iroha_config::parameters::actual::Root as Config; -use iroha_data_model::{asset::AssetDefinitionId, prelude::*}; +use iroha_data_model::{asset::AssetDefinitionId, param::BlockLimits, prelude::*}; use test_network::*; use tokio::runtime::Runtime; @@ -10,8 +10,7 @@ use tokio::runtime::Runtime; fn tranasctions_should_be_applied() { let rt = Runtime::test(); let (network, iroha) = rt.block_on(async { - let mut configuration = Config::test(); - configuration.chain_wide.max_transactions_in_block = NonZeroU32::new(1).unwrap(); + let configuration = Config::test(); let network = Network::new_with_offline_peers(Some(configuration), 4, 0, Some(11_300)) .await .unwrap(); @@ -20,6 +19,11 @@ fn tranasctions_should_be_applied() { (network, iroha) }); wait_for_genesis_committed(&network.clients(), 0); + iroha + .submit_blocking(SetParameter::new(Parameter::BlockLimits(BlockLimits { + max_transactions: NonZeroU64::new(1).unwrap(), + }))) + .unwrap(); let domain_id = "and".parse::().unwrap(); let account_id = "ed01201F803CB23B1AAFB958368DF2F67CB78A2D1DFB47FFFC3133718F165F54DFF677@and" diff --git a/client/tests/integration/extra_functional/unregister_peer.rs b/client/tests/integration/extra_functional/unregister_peer.rs index ade2324d525..0b3719a849d 100644 --- a/client/tests/integration/extra_functional/unregister_peer.rs +++ b/client/tests/integration/extra_functional/unregister_peer.rs @@ -1,14 +1,12 @@ -use std::thread; +use std::{num::NonZeroU64, thread}; use eyre::Result; use iroha::{ client::{self, QueryResult}, - data_model::{ - parameter::{default::MAX_TRANSACTIONS_IN_BLOCK, ParametersBuilder}, - prelude::*, - }, + data_model::prelude::*, }; use iroha_config::parameters::actual::Root as Config; +use iroha_data_model::param::BlockLimits; use test_network::*; use test_samples::gen_account_in; @@ -117,20 +115,23 @@ fn init() -> Result<( let (rt, network, client) = Network::start_test_with_runtime(4, Some(10_925)); let pipeline_time = Config::pipeline_time(); iroha_logger::info!("Started"); - let parameters = ParametersBuilder::new() - .add_parameter(MAX_TRANSACTIONS_IN_BLOCK, 1u32)? - .into_set_parameters(); + + let set_max_txns_in_block = SetParameter::new(Parameter::BlockLimits(BlockLimits { + max_transactions: NonZeroU64::new(1).unwrap(), + })); + let create_domain = Register::domain(Domain::new("domain".parse()?)); let (account_id, _account_keypair) = gen_account_in("domain"); let create_account = Register::account(Account::new(account_id.clone())); let asset_definition_id: AssetDefinitionId = "xor#domain".parse()?; let create_asset = Register::asset_definition(AssetDefinition::numeric(asset_definition_id.clone())); - let instructions = parameters.into_iter().chain([ + let instructions: [InstructionBox; 4] = [ + set_max_txns_in_block.into(), create_domain.into(), create_account.into(), create_asset.into(), - ]); + ]; client.submit_all_blocking(instructions)?; iroha_logger::info!("Init"); Ok(( diff --git a/client/tests/integration/extra_functional/unstable_network.rs b/client/tests/integration/extra_functional/unstable_network.rs index 558991f9c64..dc70dd318df 100644 --- a/client/tests/integration/extra_functional/unstable_network.rs +++ b/client/tests/integration/extra_functional/unstable_network.rs @@ -10,8 +10,6 @@ use test_network::*; use test_samples::ALICE_ID; use tokio::runtime::Runtime; -const MAX_TRANSACTIONS_IN_BLOCK: u32 = 5; - #[test] fn unstable_network_5_peers_1_fault() { let n_peers = 4; @@ -53,8 +51,6 @@ fn unstable_network( // Given let (network, iroha) = rt.block_on(async { let mut configuration = Config::test(); - configuration.chain_wide.max_transactions_in_block = - MAX_TRANSACTIONS_IN_BLOCK.try_into().unwrap(); #[cfg(debug_assertions)] { configuration.sumeragi.debug_force_soft_fork = force_soft_fork; diff --git a/client/tests/integration/non_mintable.rs b/client/tests/integration/non_mintable.rs index 4f65579a9be..d976fce1eb9 100644 --- a/client/tests/integration/non_mintable.rs +++ b/client/tests/integration/non_mintable.rs @@ -3,7 +3,7 @@ use std::str::FromStr as _; use eyre::Result; use iroha::{ client::{self, QueryResult}, - data_model::{isi::InstructionBox, metadata::UnlimitedMetadata, prelude::*}, + data_model::{isi::InstructionBox, prelude::*}, }; use test_network::*; use test_samples::ALICE_ID; @@ -20,7 +20,7 @@ fn non_mintable_asset_can_be_minted_once_but_not_twice() -> Result<()> { AssetDefinition::numeric(asset_definition_id.clone()).mintable_once(), ); - let metadata = UnlimitedMetadata::default(); + let metadata = Metadata::default(); let mint = Mint::asset_numeric( 200_u32, diff --git a/client/tests/integration/queries/smart_contract.rs b/client/tests/integration/queries/smart_contract.rs index 649f4550146..cc95bf86074 100644 --- a/client/tests/integration/queries/smart_contract.rs +++ b/client/tests/integration/queries/smart_contract.rs @@ -23,10 +23,8 @@ fn live_query_is_dropped_after_smart_contract_end() -> Result<()> { .optimize()? .into_bytes()?; - let transaction = client.build_transaction( - WasmSmartContract::from_compiled(wasm), - UnlimitedMetadata::default(), - ); + let transaction = + client.build_transaction(WasmSmartContract::from_compiled(wasm), Metadata::default()); client.submit_transaction_blocking(&transaction)?; let metadata_value = client.request(FindAccountKeyValueByIdAndKey::new( @@ -63,10 +61,8 @@ fn smart_contract_can_filter_queries() -> Result<()> { .optimize()? .into_bytes()?; - let transaction = client.build_transaction( - WasmSmartContract::from_compiled(wasm), - UnlimitedMetadata::default(), - ); + let transaction = + client.build_transaction(WasmSmartContract::from_compiled(wasm), Metadata::default()); client.submit_transaction_blocking(&transaction)?; Ok(()) diff --git a/client/tests/integration/set_parameter.rs b/client/tests/integration/set_parameter.rs index cf2fa11accb..20615c4d3c6 100644 --- a/client/tests/integration/set_parameter.rs +++ b/client/tests/integration/set_parameter.rs @@ -1,10 +1,11 @@ -use std::str::FromStr; +use std::time::Duration; use eyre::Result; use iroha::{ - client::{self, QueryResult}, - data_model::prelude::*, + client, + data_model::{param::Parameter, prelude::*}, }; +use iroha_data_model::param::Parameters; use test_network::*; #[test] @@ -12,51 +13,37 @@ fn can_change_parameter_value() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(11_135).start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); - let parameter = Parameter::from_str("?BlockTime=4000")?; - let parameter_id = ParameterId::from_str("BlockTime")?; - let param_box = SetParameter::new(parameter); + let old_params: Parameters = test_client.request(client::parameter::all())?; + assert_eq!(old_params.block_time, Parameters::default().block_time); - let old_params = test_client - .request(client::parameter::all())? - .collect::>>()?; - let param_val_old = old_params - .iter() - .find(|param| param.id() == ¶meter_id) - .expect("Parameter should exist") - .val(); + let block_time = Duration::from_millis(40_000); + let parameter = Parameter::BlockTime(block_time); + let set_param_isi = SetParameter::new(parameter); + test_client.submit_blocking(set_param_isi)?; - test_client.submit_blocking(param_box)?; + let new_params = test_client.request(client::parameter::all())?; + assert_eq!(new_params.block_time, block_time); - let new_params = test_client - .request(client::parameter::all())? - .collect::>>()?; - let param_val_new = new_params - .iter() - .find(|param| param.id() == ¶meter_id) - .expect("Parameter should exist") - .val(); - - assert_ne!(param_val_old, param_val_new); Ok(()) } -#[test] -fn parameter_propagated() -> Result<()> { - let (_rt, _peer, test_client) = ::new().with_port(10_985).start_with_runtime(); - wait_for_genesis_committed(&vec![test_client.clone()], 0); - - let too_long_domain_name: DomainId = "0".repeat(2_usize.pow(8)).parse()?; - let create_domain = Register::domain(Domain::new(too_long_domain_name)); - let _ = test_client - .submit_blocking(create_domain.clone()) - .expect_err("Should fail before ident length limits update"); - - let parameter = Parameter::from_str("?WSVIdentLengthLimits=1,256_LL")?; - let param_box = SetParameter::new(parameter); - test_client.submit_blocking(param_box)?; - - test_client - .submit_blocking(create_domain) - .expect("Should work after ident length limits update"); - Ok(()) -} +//#[test] +//fn parameter_propagated() -> Result<()> { +// let (_rt, _peer, test_client) = ::new().with_port(10_985).start_with_runtime(); +// wait_for_genesis_committed(&vec![test_client.clone()], 0); +// +// let too_long_domain_name: DomainId = "0".repeat(2_usize.pow(8)).parse()?; +// let create_domain = Register::domain(Domain::new(too_long_domain_name)); +// let _ = test_client +// .submit_blocking(create_domain.clone()) +// .expect_err("Should fail before ident length limits update"); +// +// let parameter = Parameter::CommitTime("?WSVIdentLengthLimits=1,256_LL"); +// let set_param_isi = SetParameter::new(parameter); +// test_client.submit_blocking(set_param_isi)?; +// +// test_client +// .submit_blocking(create_domain) +// .expect("Should work after ident length limits update"); +// Ok(()) +//} diff --git a/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs b/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs index 811e64fbbb8..e7e260ead0f 100644 --- a/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs +++ b/client/tests/integration/smartcontracts/create_nft_for_every_user_trigger/src/lib.rs @@ -21,8 +21,6 @@ fn main(_id: TriggerId, _owner: AccountId, _event: EventBox) { let accounts_cursor = FindAllAccounts.execute().dbg_unwrap(); - let limits = MetadataLimits::new(256, 256); - let bad_domain_ids: [DomainId; 2] = [ "genesis".parse().dbg_unwrap(), "garden_of_live_flowers".parse().dbg_unwrap(), @@ -35,7 +33,7 @@ fn main(_id: TriggerId, _owner: AccountId, _event: EventBox) { continue; } - let mut metadata = Metadata::new(); + let mut metadata = Metadata::default(); let name = format!( "nft_for_{}_in_{}", account.id().signatory(), @@ -43,14 +41,14 @@ fn main(_id: TriggerId, _owner: AccountId, _event: EventBox) { ) .parse() .dbg_unwrap(); - metadata.insert_with_limits(name, true, limits).dbg_unwrap(); + metadata.insert(name, true).dbg_unwrap(); let nft_id = generate_new_nft_id(account.id()); let nft_definition = AssetDefinition::store(nft_id.clone()) .mintable_once() .with_metadata(metadata); let account_nft_id = AssetId::new(nft_id, account.id().clone()); - let account_nft = Asset::new(account_nft_id, Metadata::new()); + let account_nft = Asset::new(account_nft_id, Metadata::default()); Register::asset_definition(nft_definition) .execute() diff --git a/client/tests/integration/sorting.rs b/client/tests/integration/sorting.rs index dd95bba5579..7f5fec19ec8 100644 --- a/client/tests/integration/sorting.rs +++ b/client/tests/integration/sorting.rs @@ -51,13 +51,9 @@ fn correct_pagination_assets_after_creating_new_one() { let asset_definition_id = AssetDefinitionId::from_str(&format!("xor{i}#wonderland")).expect("Valid"); let asset_definition = AssetDefinition::store(asset_definition_id.clone()); - let mut asset_metadata = Metadata::new(); + let mut asset_metadata = Metadata::default(); asset_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - i as u32, - MetadataLimits::new(10, 23), - ) + .insert(sort_by_metadata_key.clone(), i as u32) .expect("Valid"); let asset = Asset::new( AssetId::new(asset_definition_id, account_id.clone()), @@ -146,13 +142,9 @@ fn correct_sorting_of_entities() { for i in 0..n { let asset_definition_id = AssetDefinitionId::from_str(&format!("xor_{i}#wonderland")).expect("Valid"); - let mut asset_metadata = Metadata::new(); + let mut asset_metadata = Metadata::default(); asset_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - n - i - 1, - MetadataLimits::new(10, 28), - ) + .insert(sort_by_metadata_key.clone(), n - i - 1) .expect("Valid"); let asset_definition = AssetDefinition::numeric(asset_definition_id.clone()) .with_metadata(asset_metadata.clone()); @@ -207,13 +199,9 @@ fn correct_sorting_of_entities() { public_keys.sort_unstable(); for i in 0..n { let account_id = AccountId::new(domain_id.clone(), public_keys[i as usize].clone()); - let mut account_metadata = Metadata::new(); + let mut account_metadata = Metadata::default(); account_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - n - i - 1, - MetadataLimits::new(10, 28), - ) + .insert(sort_by_metadata_key.clone(), n - i - 1) .expect("Valid"); let account = Account::new(account_id.clone()).with_metadata(account_metadata.clone()); @@ -255,13 +243,9 @@ fn correct_sorting_of_entities() { let n = 10u32; for i in 0..n { let domain_id = DomainId::from_str(&format!("neverland{i}")).expect("Valid"); - let mut domain_metadata = Metadata::new(); + let mut domain_metadata = Metadata::default(); domain_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - n - i - 1, - MetadataLimits::new(10, 28), - ) + .insert(sort_by_metadata_key.clone(), n - i - 1) .expect("Valid"); let domain = Domain::new(domain_id.clone()).with_metadata(domain_metadata.clone()); @@ -302,13 +286,9 @@ fn correct_sorting_of_entities() { let mut instructions = vec![]; for (idx, val) in input { let domain_id = DomainId::from_str(&format!("neverland_{idx}")).expect("Valid"); - let mut domain_metadata = Metadata::new(); + let mut domain_metadata = Metadata::default(); domain_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - val, - MetadataLimits::new(10, 28), - ) + .insert(sort_by_metadata_key.clone(), val) .expect("Valid"); let domain = Domain::new(domain_id.clone()).with_metadata(domain_metadata.clone()); @@ -376,13 +356,9 @@ fn sort_only_elements_which_have_sorting_key() -> Result<()> { accounts_b.push(account_id); account } else { - let mut account_metadata = Metadata::new(); + let mut account_metadata = Metadata::default(); account_metadata - .insert_with_limits( - sort_by_metadata_key.clone(), - n - i - 1, - MetadataLimits::new(10, 28), - ) + .insert(sort_by_metadata_key.clone(), n - i - 1) .expect("Valid"); let account = Account::new(account_id.clone()).with_metadata(account_metadata); accounts_a.push(account_id); diff --git a/client/tests/integration/triggers/data_trigger.rs b/client/tests/integration/triggers/data_trigger.rs index 06ce5a2400e..bfbc48fd188 100644 --- a/client/tests/integration/triggers/data_trigger.rs +++ b/client/tests/integration/triggers/data_trigger.rs @@ -32,7 +32,7 @@ fn must_execute_both_triggers() -> Result<()> { [instruction.clone()], Repeats::Indefinitely, account_id.clone(), - AccountEventFilter::new().for_events(AccountEventSet::Created), + AccountEventFilter::new().for_events(AccountEventSet::Create), ), )); test_client.submit_blocking(register_trigger)?; @@ -43,7 +43,7 @@ fn must_execute_both_triggers() -> Result<()> { [instruction], Repeats::Indefinitely, account_id, - DomainEventFilter::new().for_events(DomainEventSet::Created), + DomainEventFilter::new().for_events(DomainEventSet::Create), ), )); test_client.submit_blocking(register_trigger)?; diff --git a/client/tests/integration/triggers/event_trigger.rs b/client/tests/integration/triggers/event_trigger.rs index 0221d770139..190d507ff5d 100644 --- a/client/tests/integration/triggers/event_trigger.rs +++ b/client/tests/integration/triggers/event_trigger.rs @@ -23,7 +23,7 @@ fn test_mint_asset_when_new_asset_definition_created() -> Result<()> { vec![instruction], Repeats::Indefinitely, account_id, - AssetDefinitionEventFilter::new().for_events(AssetDefinitionEventSet::Created), + AssetDefinitionEventFilter::new().for_events(AssetDefinitionEventSet::Create), ), )); test_client.submit(register_trigger)?; diff --git a/client/tests/integration/triggers/time_trigger.rs b/client/tests/integration/triggers/time_trigger.rs index b44acc1611a..075a0f1bd7b 100644 --- a/client/tests/integration/triggers/time_trigger.rs +++ b/client/tests/integration/triggers/time_trigger.rs @@ -11,11 +11,25 @@ use iroha::{ Level, }, }; -use iroha_config::parameters::defaults::chain_wide::CONSENSUS_ESTIMATION as DEFAULT_CONSENSUS_ESTIMATION; use iroha_logger::info; use test_network::*; use test_samples::{gen_account_in, ALICE_ID}; +/// Default estimation of consensus duration. +pub fn default_consensus_estimation() -> Duration { + let default_parameters = iroha_data_model::param::Parameters::default(); + + default_parameters + .block_time + .checked_add( + default_parameters + .commit_time + .checked_div(2) + .map_or_else(|| unreachable!(), |x| x), + ) + .map_or_else(|| unreachable!(), |x| x) +} + fn curr_time() -> core::time::Duration { use std::time::SystemTime; @@ -41,7 +55,7 @@ macro_rules! const_assert { fn time_trigger_execution_count_error_should_be_less_than_15_percent() -> Result<()> { const PERIOD: Duration = Duration::from_millis(100); const ACCEPTABLE_ERROR_PERCENT: u8 = 15; - const_assert!(PERIOD.as_millis() < DEFAULT_CONSENSUS_ESTIMATION.as_millis()); + assert!(PERIOD.as_millis() < default_consensus_estimation().as_millis()); const_assert!(ACCEPTABLE_ERROR_PERCENT <= 100); let (_rt, _peer, mut test_client) = ::new().with_port(10_775).start_with_runtime(); @@ -77,7 +91,7 @@ fn time_trigger_execution_count_error_should_be_less_than_15_percent() -> Result Duration::from_secs(1), 3, )?; - std::thread::sleep(DEFAULT_CONSENSUS_ESTIMATION); + std::thread::sleep(default_consensus_estimation()); let finish_time = curr_time(); let average_count = finish_time.saturating_sub(start_time).as_millis() / PERIOD.as_millis(); @@ -104,7 +118,7 @@ fn mint_asset_after_3_sec() -> Result<()> { let (_rt, _peer, test_client) = ::new().with_port(10_660).start_with_runtime(); wait_for_genesis_committed(&vec![test_client.clone()], 0); // Sleep to certainly bypass time interval analyzed by genesis - std::thread::sleep(DEFAULT_CONSENSUS_ESTIMATION); + std::thread::sleep(default_consensus_estimation()); let asset_definition_id = AssetDefinitionId::from_str("rose#wonderland").expect("Valid"); let account_id = ALICE_ID.clone(); @@ -137,7 +151,7 @@ fn mint_asset_after_3_sec() -> Result<()> { assert_eq!(init_quantity, after_registration_quantity); // Sleep long enough that trigger start is in the past - std::thread::sleep(DEFAULT_CONSENSUS_ESTIMATION); + std::thread::sleep(default_consensus_estimation()); test_client.submit_blocking(Log::new(Level::DEBUG, "Just to create block".to_string()))?; let after_wait_quantity = test_client.request(FindAssetQuantityById { diff --git a/client/tests/integration/tx_history.rs b/client/tests/integration/tx_history.rs index 77ee2fcfa2e..be415f90eae 100644 --- a/client/tests/integration/tx_history.rs +++ b/client/tests/integration/tx_history.rs @@ -46,7 +46,7 @@ fn client_has_rejected_and_acepted_txs_should_return_tx_history() -> Result<()> &mint_not_existed_asset }; let instructions: Vec = vec![mint_asset.clone().into()]; - let transaction = client.build_transaction(instructions, UnlimitedMetadata::new()); + let transaction = client.build_transaction(instructions, Metadata::default()); client.submit_transaction(&transaction)?; } thread::sleep(pipeline_time * 5); diff --git a/client/tests/integration/upgrade.rs b/client/tests/integration/upgrade.rs index 2d06f4a8a75..9dac5fb46ef 100644 --- a/client/tests/integration/upgrade.rs +++ b/client/tests/integration/upgrade.rs @@ -6,7 +6,6 @@ use iroha::{ client::{self, Client, QueryResult}, data_model::prelude::*, }; -use iroha_data_model::parameter::{default::EXECUTOR_FUEL_LIMIT, ParametersBuilder}; use iroha_logger::info; use serde_json::json; use test_network::*; @@ -241,25 +240,10 @@ fn executor_custom_instructions_complex() -> Result<()> { use executor_custom_data_model::complex::{ ConditionalExpr, CoreExpr, CustomInstructionExpr, EvaluatesTo, Expression, Greater, }; - use iroha_config::parameters::actual::Root as Config; - let mut config = Config::test(); - // Note that this value will be overwritten by genesis block with NewParameter ISI - // But it will be needed after NewParameter removal in #4597 - config.chain_wide.executor_runtime.fuel_limit = 1_000_000_000; - - let (_rt, _peer, client) = PeerBuilder::new() - .with_port(11_275) - .with_config(config) - .start_with_runtime(); + let (_rt, _peer, client) = PeerBuilder::new().with_port(11_275).start_with_runtime(); wait_for_genesis_committed(&vec![client.clone()], 0); - // Remove this after #4597 - config value will be used (see above) - let parameters = ParametersBuilder::new() - .add_parameter(EXECUTOR_FUEL_LIMIT, Numeric::from(1_000_000_000_u32))? - .into_set_parameters(); - client.submit_all_blocking(parameters)?; - upgrade_executor( &client, "tests/integration/smartcontracts/executor_custom_instructions_complex", @@ -354,7 +338,7 @@ fn migration_should_cause_upgrade_event() { .await .unwrap(); while let Some(event) = stream.try_next().await.unwrap() { - if let EventBox::Data(DataEvent::Executor(ExecutorEvent::Upgraded(ExecutorUpgrade { + if let EventBox::Data(DataEvent::Executor(ExecutorEvent::Upgrade(ExecutorUpgrade { new_data_model, }))) = event { diff --git a/client_cli/src/main.rs b/client_cli/src/main.rs index 3a2ea0caa3e..fd06dc580e2 100644 --- a/client_cli/src/main.rs +++ b/client_cli/src/main.rs @@ -30,20 +30,19 @@ pub struct MetadataArgs { } impl MetadataArgs { - fn load(self) -> Result { - let value: Option = self + fn load(self) -> Result { + let value: Option = self .metadata .map(|path| { let content = fs::read_to_string(&path).wrap_err_with(|| { eyre!("Failed to read the metadata file `{}`", path.display()) })?; - let metadata: UnlimitedMetadata = - json5::from_str(&content).wrap_err_with(|| { - eyre!( - "Failed to deserialize metadata from file `{}`", - path.display() - ) - })?; + let metadata: Metadata = json5::from_str(&content).wrap_err_with(|| { + eyre!( + "Failed to deserialize metadata from file `{}`", + path.display() + ) + })?; Ok::<_, eyre::Report>(metadata) }) .transpose()?; @@ -237,7 +236,7 @@ fn color_mode() -> ColorMode { #[allow(clippy::shadow_unrelated)] fn submit( instructions: impl Into, - metadata: UnlimitedMetadata, + metadata: Metadata, context: &mut dyn RunContext, ) -> Result<()> { let iroha = context.client_from_config(); @@ -490,7 +489,7 @@ mod domain { value: MetadataValueArg { value }, } = self; let set_key_value = SetKeyValue::domain(id, key, value); - submit([set_key_value], UnlimitedMetadata::new(), context) + submit([set_key_value], Metadata::default(), context) .wrap_err("Failed to submit Set instruction") } } @@ -510,7 +509,7 @@ mod domain { fn run(self, context: &mut dyn RunContext) -> Result<()> { let Self { id, key } = self; let remove_key_value = RemoveKeyValue::domain(id, key); - submit([remove_key_value], UnlimitedMetadata::new(), context) + submit([remove_key_value], Metadata::default(), context) .wrap_err("Failed to submit Remove instruction") } } @@ -887,7 +886,7 @@ mod asset { } = self; let set = iroha::data_model::isi::SetKeyValue::asset(asset_id, key, value); - submit([set], UnlimitedMetadata::default(), context)?; + submit([set], Metadata::default(), context)?; Ok(()) } } @@ -905,7 +904,7 @@ mod asset { fn run(self, context: &mut dyn RunContext) -> Result<()> { let Self { asset_id, key } = self; let remove = iroha::data_model::isi::RemoveKeyValue::asset(asset_id, key); - submit([remove], UnlimitedMetadata::default(), context)?; + submit([remove], Metadata::default(), context)?; Ok(()) } } @@ -1036,7 +1035,7 @@ mod wasm { submit( WasmSmartContract::from_compiled(raw_data), - UnlimitedMetadata::new(), + Metadata::default(), context, ) .wrap_err("Failed to submit a Wasm smart contract") @@ -1076,7 +1075,7 @@ mod json { match self.variant { Variant::Transaction => { let instructions: Vec = json5::from_str(&string_content)?; - submit(instructions, UnlimitedMetadata::new(), context) + submit(instructions, Metadata::default(), context) .wrap_err("Failed to submit parsed instructions") } Variant::Query => { diff --git a/config/src/parameters/actual.rs b/config/src/parameters/actual.rs index 0bea7dd1b13..8e51f814c44 100644 --- a/config/src/parameters/actual.rs +++ b/config/src/parameters/actual.rs @@ -10,12 +10,8 @@ use std::{ use error_stack::{Result, ResultExt}; use iroha_config_base::{read::ConfigReader, toml::TomlSource, util::Bytes, WithOrigin}; use iroha_crypto::{KeyPair, PublicKey}; -use iroha_data_model::{ - metadata::Limits as MetadataLimits, peer::PeerId, transaction::TransactionLimits, ChainId, - LengthLimits, -}; +use iroha_data_model::{peer::PeerId, ChainId}; use iroha_primitives::{addr::SocketAddr, unique_vec::UniqueVec}; -use serde::{Deserialize, Serialize}; use url::Url; pub use user::{DevTelemetry, Logger, Snapshot}; @@ -42,7 +38,6 @@ pub struct Root { pub snapshot: Snapshot, pub telemetry: Option, pub dev_telemetry: DevTelemetry, - pub chain_wide: ChainWide, } /// See [`Root::from_toml_source`] @@ -168,78 +163,14 @@ impl Default for LiveQueryStore { #[derive(Debug, Clone, Copy)] pub struct BlockSync { pub gossip_period: Duration, - pub gossip_max_size: NonZeroU32, + pub gossip_size: NonZeroU32, } #[derive(Debug, Clone, Copy)] #[allow(missing_docs)] pub struct TransactionGossiper { pub gossip_period: Duration, - pub gossip_max_size: NonZeroU32, -} - -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -#[allow(missing_docs)] -pub struct ChainWide { - pub max_transactions_in_block: NonZeroU32, - pub block_time: Duration, - pub commit_time: Duration, - pub transaction_limits: TransactionLimits, - pub domain_metadata_limits: MetadataLimits, - pub asset_definition_metadata_limits: MetadataLimits, - pub account_metadata_limits: MetadataLimits, - pub asset_metadata_limits: MetadataLimits, - pub trigger_metadata_limits: MetadataLimits, - pub ident_length_limits: LengthLimits, - pub executor_runtime: WasmRuntime, - pub wasm_runtime: WasmRuntime, -} - -impl ChainWide { - /// Calculate pipeline time based on the block time and commit time - pub fn pipeline_time(&self) -> Duration { - self.block_time + self.commit_time - } - - /// Estimates as `block_time + commit_time / 2` - pub fn consensus_estimation(&self) -> Duration { - self.block_time + (self.commit_time / 2) - } -} - -impl Default for ChainWide { - fn default() -> Self { - Self { - max_transactions_in_block: defaults::chain_wide::MAX_TXS, - block_time: defaults::chain_wide::BLOCK_TIME, - commit_time: defaults::chain_wide::COMMIT_TIME, - transaction_limits: defaults::chain_wide::TRANSACTION_LIMITS, - domain_metadata_limits: defaults::chain_wide::METADATA_LIMITS, - account_metadata_limits: defaults::chain_wide::METADATA_LIMITS, - asset_definition_metadata_limits: defaults::chain_wide::METADATA_LIMITS, - asset_metadata_limits: defaults::chain_wide::METADATA_LIMITS, - trigger_metadata_limits: defaults::chain_wide::METADATA_LIMITS, - ident_length_limits: defaults::chain_wide::IDENT_LENGTH_LIMITS, - executor_runtime: WasmRuntime::default(), - wasm_runtime: WasmRuntime::default(), - } - } -} - -#[allow(missing_docs)] -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] -pub struct WasmRuntime { - pub fuel_limit: u64, - pub max_memory: Bytes, -} - -impl Default for WasmRuntime { - fn default() -> Self { - Self { - fuel_limit: defaults::chain_wide::WASM_FUEL_LIMIT, - max_memory: defaults::chain_wide::WASM_MAX_MEMORY, - } - } + pub gossip_size: NonZeroU32, } #[derive(Debug, Clone)] diff --git a/config/src/parameters/defaults.rs b/config/src/parameters/defaults.rs index e68bfbf1c73..aa5e96ce6a9 100644 --- a/config/src/parameters/defaults.rs +++ b/config/src/parameters/defaults.rs @@ -8,7 +8,6 @@ use std::{ time::Duration, }; -use iroha_data_model::{prelude::MetadataLimits, transaction::TransactionLimits, LengthLimits}; use nonzero_ext::nonzero; pub mod queue { @@ -29,10 +28,10 @@ pub mod network { use super::*; pub const TRANSACTION_GOSSIP_PERIOD: Duration = Duration::from_secs(1); - pub const TRANSACTION_GOSSIP_MAX_SIZE: NonZeroU32 = nonzero!(500u32); + pub const TRANSACTION_GOSSIP_SIZE: NonZeroU32 = nonzero!(500u32); pub const BLOCK_GOSSIP_PERIOD: Duration = Duration::from_secs(10); - pub const BLOCK_GOSSIP_MAX_SIZE: NonZeroU32 = nonzero!(4u32); + pub const BLOCK_GOSSIP_SIZE: NonZeroU32 = nonzero!(4u32); pub const IDLE_TIMEOUT: Duration = Duration::from_secs(60); } @@ -45,41 +44,6 @@ pub mod snapshot { pub const CREATE_EVERY: Duration = Duration::from_secs(60); } -pub mod chain_wide { - use iroha_config_base::util::Bytes; - - use super::*; - - pub const MAX_TXS: NonZeroU32 = nonzero!(2_u32.pow(9)); - pub const BLOCK_TIME: Duration = Duration::from_secs(2); - pub const COMMIT_TIME: Duration = Duration::from_secs(4); - pub const WASM_FUEL_LIMIT: u64 = 55_000_000; - pub const WASM_MAX_MEMORY: Bytes = Bytes(500 * 2_u32.pow(20)); - - /// Default estimation of consensus duration. - pub const CONSENSUS_ESTIMATION: Duration = - match BLOCK_TIME.checked_add(match COMMIT_TIME.checked_div(2) { - Some(x) => x, - None => unreachable!(), - }) { - Some(x) => x, - None => unreachable!(), - }; - - /// Default limits for metadata - pub const METADATA_LIMITS: MetadataLimits = MetadataLimits::new(2_u32.pow(20), 2_u32.pow(12)); - /// Default limits for ident length - pub const IDENT_LENGTH_LIMITS: LengthLimits = LengthLimits::new(1, 2_u32.pow(7)); - /// Default maximum number of instructions and expressions per transaction - pub const MAX_INSTRUCTION_NUMBER: u64 = 2_u64.pow(12); - /// Default maximum number of instructions and expressions per transaction - pub const MAX_WASM_SIZE_BYTES: u64 = 4 * 2_u64.pow(20); - - /// Default transaction limits - pub const TRANSACTION_LIMITS: TransactionLimits = - TransactionLimits::new(MAX_INSTRUCTION_NUMBER, MAX_WASM_SIZE_BYTES); -} - pub mod torii { use std::time::Duration; diff --git a/config/src/parameters/user.rs b/config/src/parameters/user.rs index a619626e896..c3fd636ec8f 100644 --- a/config/src/parameters/user.rs +++ b/config/src/parameters/user.rs @@ -25,10 +25,7 @@ use iroha_config_base::{ ReadConfig, WithOrigin, }; use iroha_crypto::{PrivateKey, PublicKey}; -use iroha_data_model::{ - metadata::Limits as MetadataLimits, peer::PeerId, transaction::TransactionLimits, ChainId, - LengthLimits, Level, -}; +use iroha_data_model::{peer::PeerId, ChainId, Level}; use iroha_primitives::{addr::SocketAddr, unique_vec::UniqueVec}; use serde::Deserialize; use url::Url; @@ -81,8 +78,6 @@ pub struct Root { dev_telemetry: DevTelemetry, #[config(nested)] torii: Torii, - #[config(nested)] - chain_wide: ChainWide, } #[derive(thiserror::Error, Debug, Copy, Clone)] @@ -119,7 +114,6 @@ impl Root { let dev_telemetry = self.dev_telemetry; let (torii, live_query_store) = self.torii.parse(); let telemetry = self.telemetry.map(actual::Telemetry::from); - let chain_wide = self.chain_wide.parse(); let peer_id = key_pair.as_ref().map(|key_pair| { PeerId::new( @@ -156,7 +150,6 @@ impl Root { snapshot, telemetry, dev_telemetry, - chain_wide, }) } } @@ -272,12 +265,12 @@ pub struct Network { /// Peer-to-peer address #[config(env = "P2P_ADDRESS")] pub address: WithOrigin, - #[config(default = "defaults::network::BLOCK_GOSSIP_MAX_SIZE")] - pub block_gossip_max_size: NonZeroU32, + #[config(default = "defaults::network::BLOCK_GOSSIP_SIZE")] + pub block_gossip_size: NonZeroU32, #[config(default = "defaults::network::BLOCK_GOSSIP_PERIOD.into()")] pub block_gossip_period_ms: DurationMs, - #[config(default = "defaults::network::TRANSACTION_GOSSIP_MAX_SIZE")] - pub transaction_gossip_max_size: NonZeroU32, + #[config(default = "defaults::network::TRANSACTION_GOSSIP_SIZE")] + pub transaction_gossip_size: NonZeroU32, #[config(default = "defaults::network::TRANSACTION_GOSSIP_PERIOD.into()")] pub transaction_gossip_period_ms: DurationMs, /// Duration of time after which connection with peer is terminated if peer is idle @@ -295,9 +288,9 @@ impl Network { ) { let Self { address, - block_gossip_max_size, + block_gossip_size, block_gossip_period_ms: block_gossip_period, - transaction_gossip_max_size, + transaction_gossip_size, transaction_gossip_period_ms: transaction_gossip_period, idle_timeout_ms: idle_timeout, } = self; @@ -309,11 +302,11 @@ impl Network { }, actual::BlockSync { gossip_period: block_gossip_period.get(), - gossip_max_size: block_gossip_max_size, + gossip_size: block_gossip_size, }, actual::TransactionGossiper { gossip_period: transaction_gossip_period.get(), - gossip_max_size: transaction_gossip_max_size, + gossip_size: transaction_gossip_size, }, ) } @@ -433,81 +426,6 @@ pub struct Snapshot { pub store_dir: WithOrigin, } -// TODO: make serde -#[derive(Debug, Copy, Clone, ReadConfig)] -pub struct ChainWide { - #[config(default = "defaults::chain_wide::MAX_TXS")] - pub max_transactions_in_block: NonZeroU32, - #[config(default = "defaults::chain_wide::BLOCK_TIME.into()")] - pub block_time_ms: DurationMs, - #[config(default = "defaults::chain_wide::COMMIT_TIME.into()")] - pub commit_time_ms: DurationMs, - #[config(default = "defaults::chain_wide::TRANSACTION_LIMITS")] - pub transaction_limits: TransactionLimits, - #[config(default = "defaults::chain_wide::METADATA_LIMITS")] - pub domain_metadata_limits: MetadataLimits, - #[config(default = "defaults::chain_wide::METADATA_LIMITS")] - pub asset_definition_metadata_limits: MetadataLimits, - #[config(default = "defaults::chain_wide::METADATA_LIMITS")] - pub account_metadata_limits: MetadataLimits, - #[config(default = "defaults::chain_wide::METADATA_LIMITS")] - pub asset_metadata_limits: MetadataLimits, - #[config(default = "defaults::chain_wide::METADATA_LIMITS")] - pub trigger_metadata_limits: MetadataLimits, - #[config(default = "defaults::chain_wide::IDENT_LENGTH_LIMITS")] - pub ident_length_limits: LengthLimits, - #[config(default = "defaults::chain_wide::WASM_FUEL_LIMIT")] - pub executor_fuel_limit: u64, - #[config(default = "defaults::chain_wide::WASM_MAX_MEMORY")] - pub executor_max_memory: Bytes, - #[config(default = "defaults::chain_wide::WASM_FUEL_LIMIT")] - pub wasm_fuel_limit: u64, - #[config(default = "defaults::chain_wide::WASM_MAX_MEMORY")] - pub wasm_max_memory: Bytes, -} - -impl ChainWide { - fn parse(self) -> actual::ChainWide { - let Self { - max_transactions_in_block, - block_time_ms: DurationMs(block_time), - commit_time_ms: DurationMs(commit_time), - transaction_limits, - asset_metadata_limits, - trigger_metadata_limits, - asset_definition_metadata_limits, - account_metadata_limits, - domain_metadata_limits, - ident_length_limits, - executor_fuel_limit, - executor_max_memory, - wasm_fuel_limit, - wasm_max_memory, - } = self; - - actual::ChainWide { - max_transactions_in_block, - block_time, - commit_time, - transaction_limits, - asset_metadata_limits, - trigger_metadata_limits, - asset_definition_metadata_limits, - account_metadata_limits, - domain_metadata_limits, - ident_length_limits, - executor_runtime: actual::WasmRuntime { - fuel_limit: executor_fuel_limit, - max_memory: executor_max_memory, - }, - wasm_runtime: actual::WasmRuntime { - fuel_limit: wasm_fuel_limit, - max_memory: wasm_max_memory, - }, - } - } -} - #[derive(Debug, ReadConfig)] pub struct Torii { #[config(env = "API_ADDRESS")] diff --git a/config/tests/fixtures.rs b/config/tests/fixtures.rs index ae29cb5ba15..411b1460fd8 100644 --- a/config/tests/fixtures.rs +++ b/config/tests/fixtures.rs @@ -162,11 +162,11 @@ fn minimal_config_snapshot() { }, block_sync: BlockSync { gossip_period: 10s, - gossip_max_size: 4, + gossip_size: 4, }, transaction_gossiper: TransactionGossiper { gossip_period: 1s, - gossip_max_size: 500, + gossip_size: 500, }, live_query_store: LiveQueryStore { idle_time: 30s, @@ -197,51 +197,6 @@ fn minimal_config_snapshot() { dev_telemetry: DevTelemetry { out_file: None, }, - chain_wide: ChainWide { - max_transactions_in_block: 512, - block_time: 2s, - commit_time: 4s, - transaction_limits: TransactionLimits { - max_instruction_number: 4096, - max_wasm_size_bytes: 4194304, - }, - domain_metadata_limits: Limits { - capacity: 1048576, - max_entry_len: 4096, - }, - asset_definition_metadata_limits: Limits { - capacity: 1048576, - max_entry_len: 4096, - }, - account_metadata_limits: Limits { - capacity: 1048576, - max_entry_len: 4096, - }, - asset_metadata_limits: Limits { - capacity: 1048576, - max_entry_len: 4096, - }, - trigger_metadata_limits: Limits { - capacity: 1048576, - max_entry_len: 4096, - }, - ident_length_limits: LengthLimits { - min: 1, - max: 128, - }, - executor_runtime: WasmRuntime { - fuel_limit: 55000000, - max_memory: Bytes( - 524288000, - ), - }, - wasm_runtime: WasmRuntime { - fuel_limit: 55000000, - max_memory: Bytes( - 524288000, - ), - }, - }, }"#]].assert_eq(&format!("{config:#?}")); } diff --git a/config/tests/fixtures/full.toml b/config/tests/fixtures/full.toml index 02404b6cf3d..22aa92459af 100644 --- a/config/tests/fixtures/full.toml +++ b/config/tests/fixtures/full.toml @@ -11,9 +11,9 @@ signed_file = "genesis.signed.scale" [network] address = "localhost:3840" block_gossip_period_ms = 10_000 -block_gossip_max_size = 4 +block_gossip_size = 4 transaction_gossip_period_ms = 1_000 -transaction_gossip_max_size = 500 +transaction_gossip_size = 500 idle_timeout_ms = 10_000 [torii] @@ -40,8 +40,8 @@ level = "TRACE" format = "compact" [queue] -capacity = 65536 -capacity_per_user = 65536 +capacity = 65_536 +capacity_per_user = 65_536 transaction_time_to_live_ms = 100 future_threshold_ms = 50 @@ -58,16 +58,3 @@ max_retry_delay_exponent = 4 [dev_telemetry] out_file = "./dev_telemetry.json" - -[chain_wide] -max_transactions_in_block = 512 -block_time_ms = 2_000 -commit_time_ms = 4_000 -transaction_limits = { max_instruction_number = 4096, max_wasm_size_bytes = 4194304 } -asset_metadata_limits = { capacity = 1048576, max_entry_len = 4096 } -asset_definition_metadata_limits = { capacity = 1048576, max_entry_len = 4096 } -account_metadata_limits = { capacity = 1048576, max_entry_len = 4096 } -domain_metadata_limits = { capacity = 1048576, max_entry_len = 4096 } -ident_length_limits = { min = 1, max = 128 } -wasm_fuel_limit = 55000000 -wasm_max_memory = 524288000 diff --git a/configs/peer.template.toml b/configs/peer.template.toml index 2c32102420d..0dcfb679abb 100644 --- a/configs/peer.template.toml +++ b/configs/peer.template.toml @@ -20,9 +20,9 @@ [network] # address = # block_gossip_period_ms = 10_000 -# block_gossip_max_size = 4 +# block_gossip_size = 4 # transaction_gossip_period_ms = 1_000 -# transaction_gossip_max_size = 500 +# transaction_gossip_size = 500 # idle_timeout_ms = 60_000 [torii] diff --git a/configs/swarm/genesis.json b/configs/swarm/genesis.json index 7d547116ff5..764cdf98e76 100644 --- a/configs/swarm/genesis.json +++ b/configs/swarm/genesis.json @@ -123,48 +123,6 @@ } } }, - { - "NewParameter": "?MaxTransactionsInBlock=512" - }, - { - "NewParameter": "?BlockTime=2000" - }, - { - "NewParameter": "?CommitTimeLimit=4000" - }, - { - "NewParameter": "?TransactionLimits=4096,4194304_TL" - }, - { - "NewParameter": "?WSVDomainMetadataLimits=1048576,4096_ML" - }, - { - "NewParameter": "?WSVAssetDefinitionMetadataLimits=1048576,4096_ML" - }, - { - "NewParameter": "?WSVAccountMetadataLimits=1048576,4096_ML" - }, - { - "NewParameter": "?WSVAssetMetadataLimits=1048576,4096_ML" - }, - { - "NewParameter": "?WSVTriggerMetadataLimits=1048576,4096_ML" - }, - { - "NewParameter": "?WSVIdentLengthLimits=1,128_LL" - }, - { - "NewParameter": "?ExecutorFuelLimit=55000000" - }, - { - "NewParameter": "?ExecutorMaxMemory=524288000" - }, - { - "NewParameter": "?WASMFuelLimit=55000000" - }, - { - "NewParameter": "?WASMMaxMemory=524288000" - }, { "Register": { "Role": { diff --git a/core/benches/blocks/common.rs b/core/benches/blocks/common.rs index 30ac642aee4..12400463122 100644 --- a/core/benches/blocks/common.rs +++ b/core/benches/blocks/common.rs @@ -1,4 +1,4 @@ -use std::str::FromStr as _; +use std::{num::NonZeroU64, str::FromStr as _}; use iroha_core::{ block::{BlockBuilder, CommittedBlock}, @@ -13,8 +13,8 @@ use iroha_data_model::{ asset::{AssetDefinition, AssetDefinitionId}, domain::Domain, isi::InstructionBox, + param::TransactionLimits, prelude::*, - transaction::TransactionLimits, ChainId, JsonString, }; use iroha_primitives::unique_vec::UniqueVec; @@ -186,9 +186,12 @@ pub fn build_state(rt: &tokio::runtime::Handle, account_id: &AccountId) -> State { let mut state_block = state.block(); - state_block.config.transaction_limits = TransactionLimits::new(u64::MAX, u64::MAX); - state_block.config.executor_runtime.fuel_limit = u64::MAX; - state_block.config.executor_runtime.max_memory = u32::MAX.into(); + state_block.world.parameters.transaction_limits = TransactionLimits::new( + NonZeroU64::new(u64::MAX).unwrap(), + NonZeroU64::new(u64::MAX).unwrap(), + ); + state_block.world.parameters.executor_limits.fuel = NonZeroU64::new(u64::MAX).unwrap(); + state_block.world.parameters.executor_limits.memory = NonZeroU64::new(u64::MAX).unwrap(); let mut state_transaction = state_block.transaction(); let path_to_executor = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) diff --git a/core/benches/kura.rs b/core/benches/kura.rs index bc3b55a49e6..32904aec6d7 100644 --- a/core/benches/kura.rs +++ b/core/benches/kura.rs @@ -14,7 +14,8 @@ use iroha_core::{ sumeragi::network_topology::Topology, }; use iroha_crypto::KeyPair; -use iroha_data_model::{prelude::*, transaction::TransactionLimits}; +use iroha_data_model::{param::TransactionLimits, prelude::*}; +use nonzero_ext::nonzero; use test_samples::gen_account_in; use tokio::{fs, runtime::Runtime}; @@ -29,11 +30,11 @@ async fn measure_block_size_for_n_executors(n_executors: u32) { let tx = TransactionBuilder::new(chain_id.clone(), alice_id.clone()) .with_instructions([transfer]) .sign(alice_keypair.private_key()); - let transaction_limits = TransactionLimits { - max_instruction_number: 4096, - max_wasm_size_bytes: 0, + let txn_limits = TransactionLimits { + max_instructions: nonzero!(4096_u64), + smart_contract_size: nonzero!(1_u64), }; - let tx = AcceptedTransaction::accept(tx, &chain_id, transaction_limits) + let tx = AcceptedTransaction::accept(tx, &chain_id, txn_limits) .expect("Failed to accept Transaction."); let dir = tempfile::tempdir().expect("Could not create tempfile."); let cfg = Config { diff --git a/core/benches/validation.rs b/core/benches/validation.rs index bb2820d1379..c2420d1329d 100644 --- a/core/benches/validation.rs +++ b/core/benches/validation.rs @@ -11,12 +11,11 @@ use iroha_core::{ tx::TransactionExecutor, }; use iroha_data_model::{ - account::AccountId, - isi::InstructionBox, - prelude::*, - transaction::{TransactionBuilder, TransactionLimits}, + account::AccountId, isi::InstructionBox, param::TransactionLimits, prelude::*, + transaction::TransactionBuilder, }; use iroha_primitives::unique_vec::UniqueVec; +use nonzero_ext::nonzero; use once_cell::sync::Lazy; use test_samples::gen_account_in; @@ -25,10 +24,8 @@ static STARTER_KEYPAIR: Lazy = Lazy::new(KeyPair::random); static STARTER_ID: Lazy = Lazy::new(|| AccountId::new(STARTER_DOMAIN.clone(), STARTER_KEYPAIR.public_key().clone())); -const TRANSACTION_LIMITS: TransactionLimits = TransactionLimits { - max_instruction_number: 4096, - max_wasm_size_bytes: 0, -}; +const TRANSACTION_LIMITS: TransactionLimits = + TransactionLimits::new(nonzero!(5096_u64), nonzero!(1_u64)); fn build_test_transaction(chain_id: ChainId) -> TransactionBuilder { let domain_id: DomainId = "domain".parse().unwrap(); diff --git a/core/src/block.rs b/core/src/block.rs index 9e5f89c3945..a8023289a6a 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -116,7 +116,10 @@ pub enum InvalidGenesisError { pub struct BlockBuilder(B); mod pending { - use std::time::{Duration, SystemTime}; + use std::{ + num::NonZeroUsize, + time::{Duration, SystemTime}, + }; use iroha_data_model::transaction::CommittedTransaction; @@ -165,11 +168,14 @@ mod pending { consensus_estimation: Duration, ) -> BlockHeader { BlockHeader { - height: prev_height - .checked_add(1) - .expect("INTERNAL BUG: Blockchain height exceeds usize::MAX") - .try_into() - .expect("INTERNAL BUG: Number of blocks exceeds u64::MAX"), + height: NonZeroUsize::new( + prev_height + .checked_add(1) + .expect("INTERNAL BUG: Blockchain height exceeds usize::MAX"), + ) + .expect("INTERNAL BUG: block height must not be 0") + .try_into() + .expect("INTERNAL BUG: Number of blocks exceeds u64::MAX"), prev_block_hash, transactions_hash: transactions .iter() @@ -237,7 +243,7 @@ mod pending { state.latest_block_hash(), view_change_index, &transactions, - state.config.consensus_estimation(), + state.consensus_estimation(), ), transactions, commit_topology: self.0.commit_topology.into_iter().collect(), @@ -423,10 +429,14 @@ mod valid { genesis_account: &AccountId, state_block: &mut StateBlock<'_>, ) -> WithEvents> { - let expected_block_height = state_block.height() + 1; + let expected_block_height = state_block + .height() + .checked_add(1) + .expect("INTERNAL BUG: Block height exceeds usize::MAX"); let actual_height = block .header() .height + .get() .try_into() .expect("INTERNAL BUG: Block height exceeds usize::MAX"); @@ -647,9 +657,11 @@ mod valid { leader_private_key: &PrivateKey, f: impl FnOnce(&mut BlockPayload), ) -> Self { + use nonzero_ext::nonzero; + let mut payload = BlockPayload { header: BlockHeader { - height: 2, + height: nonzero!(2_u64), prev_block_hash: None, transactions_hash: HashOf::from_untyped_unchecked(Hash::prehashed( [1; Hash::LENGTH], diff --git a/core/src/block_sync.rs b/core/src/block_sync.rs index 85dd12ff289..99553729f92 100644 --- a/core/src/block_sync.rs +++ b/core/src/block_sync.rs @@ -41,7 +41,7 @@ pub struct BlockSynchronizer { kura: Arc, peer_id: PeerId, gossip_period: Duration, - gossip_max_size: NonZeroU32, + gossip_size: NonZeroU32, network: IrohaNetwork, state: Arc, } @@ -118,7 +118,7 @@ impl BlockSynchronizer { sumeragi, kura, gossip_period: config.gossip_period, - gossip_max_size: config.gossip_max_size, + gossip_size: config.gossip_size, network, state, } @@ -219,7 +219,7 @@ pub mod message { }; let blocks = (start_height.get()..) - .take(block_sync.gossip_max_size.get() as usize + 1) + .take(block_sync.gossip_size.get() as usize + 1) .map_while(|height| { NonZeroUsize::new(height) .and_then(|height| block_sync.kura.get_block_by_height(height)) diff --git a/core/src/executor.rs b/core/src/executor.rs index 50a632e54ec..178a3935731 100644 --- a/core/src/executor.rs +++ b/core/src/executor.rs @@ -18,6 +18,7 @@ use serde::{ use crate::{ smartcontracts::{wasm, Execute as _}, state::{deserialize::WasmSeed, StateReadOnly, StateTransaction}, + WorldReadOnly as _, }; impl From for ValidationFail { @@ -157,7 +158,7 @@ impl Executor { let runtime = wasm::RuntimeBuilder::::new() .with_engine(state_transaction.engine.clone()) // Cloning engine is cheap, see [`wasmtime::Engine`] docs - .with_config(state_transaction.config.executor_runtime) + .with_config(state_transaction.world.parameters().executor_limits) .build()?; runtime.execute_executor_validate_transaction( @@ -193,7 +194,7 @@ impl Executor { let runtime = wasm::RuntimeBuilder::::new() .with_engine(state_transaction.engine.clone()) // Cloning engine is cheap, see [`wasmtime::Engine`] docs - .with_config(state_transaction.config.executor_runtime) + .with_config(state_transaction.world.parameters().executor_limits) .build()?; runtime.execute_executor_validate_instruction( @@ -227,7 +228,7 @@ impl Executor { let runtime = wasm::RuntimeBuilder::>::new() .with_engine(state_ro.engine().clone()) // Cloning engine is cheap, see [`wasmtime::Engine`] docs - .with_config(state_ro.config().executor_runtime) + .with_config(state_ro.world().parameters().executor_limits) .build()?; runtime.execute_executor_validate_query( @@ -262,7 +263,7 @@ impl Executor { let runtime = wasm::RuntimeBuilder::::new() .with_engine(state_transaction.engine.clone()) // Cloning engine is cheap, see [`wasmtime::Engine`] docs - .with_config(state_transaction.config.executor_runtime) + .with_config(state_transaction.world().parameters().executor_limits) .build()?; runtime diff --git a/core/src/gossiper.rs b/core/src/gossiper.rs index 4f5018aa9f6..9b6ca31881e 100644 --- a/core/src/gossiper.rs +++ b/core/src/gossiper.rs @@ -8,7 +8,10 @@ use iroha_p2p::Broadcast; use parity_scale_codec::{Decode, Encode}; use tokio::sync::mpsc; -use crate::{queue::Queue, state::State, tx::AcceptedTransaction, IrohaNetwork, NetworkMessage}; +use crate::{ + queue::Queue, state::State, tx::AcceptedTransaction, IrohaNetwork, NetworkMessage, + StateReadOnly, WorldReadOnly, +}; /// [`Gossiper`] actor handle. #[derive(Clone)] @@ -26,21 +29,18 @@ impl TransactionGossiperHandle { } } -/// Actor to gossip transactions and receive transaction gossips +/// Actor which gossips transactions and receives transaction gossips pub struct TransactionGossiper { /// Unique id of the blockchain. Used for simple replay attack protection. chain_id: ChainId, - /// The size of batch that is being gossiped. Smaller size leads - /// to longer time to synchronise, useful if you have high packet loss. - gossip_max_size: NonZeroU32, - /// The time between gossiping. More frequent gossiping shortens + /// The time between gossip messages. More frequent gossiping shortens /// the time to sync, but can overload the network. gossip_period: Duration, - /// Address of queue - queue: Arc, - /// [`iroha_p2p::Network`] actor handle + /// Maximum size of a batch that is being gossiped. Smaller size leads + /// to longer time to synchronise, useful if you have high packet loss. + gossip_size: NonZeroU32, network: IrohaNetwork, - /// [`WorldState`] + queue: Arc, state: Arc, } @@ -57,7 +57,7 @@ impl TransactionGossiper { chain_id: ChainId, Config { gossip_period, - gossip_max_size, + gossip_size, }: Config, network: IrohaNetwork, queue: Arc, @@ -65,10 +65,10 @@ impl TransactionGossiper { ) -> Self { Self { chain_id, - gossip_max_size, gossip_period, - queue, + gossip_size, network, + queue, state, } } @@ -93,7 +93,7 @@ impl TransactionGossiper { fn gossip_transactions(&self) { let txs = self .queue - .n_random_transactions(self.gossip_max_size.get(), &self.state.view()); + .n_random_transactions(self.gossip_size.get(), &self.state.view()); if txs.is_empty() { return; @@ -110,7 +110,7 @@ impl TransactionGossiper { let state_view = self.state.view(); for tx in txs { - let transaction_limits = state_view.config.transaction_limits; + let transaction_limits = state_view.world().parameters().transaction_limits; match AcceptedTransaction::accept(tx, &self.chain_id, transaction_limits) { Ok(tx) => match self.queue.push(tx, &state_view) { diff --git a/core/src/lib.rs b/core/src/lib.rs index f1104d47163..0d25bf98ca7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -18,7 +18,6 @@ pub mod tx; use core::time::Duration; use gossiper::TransactionGossip; -use indexmap::IndexSet; use iroha_data_model::{events::EventBox, prelude::*}; use iroha_primitives::unique_vec::UniqueVec; use parity_scale_codec::{Decode, Encode}; @@ -39,9 +38,6 @@ pub type IrohaNetwork = iroha_p2p::NetworkHandle; /// Ids of peers. pub type PeersIds = UniqueVec; -/// Parameters set. -pub type Parameters = IndexSet; - /// Type of `Sender` which should be used for channels of `Event` messages. pub type EventsSender = broadcast::Sender; diff --git a/core/src/queue.rs b/core/src/queue.rs index 658ffafe405..30218035305 100644 --- a/core/src/queue.rs +++ b/core/src/queue.rs @@ -284,9 +284,9 @@ impl Queue { fn collect_transactions_for_block( &self, state_view: &StateView, - max_txs_in_block: usize, + max_txs_in_block: NonZeroUsize, ) -> Vec { - let mut transactions = Vec::with_capacity(max_txs_in_block); + let mut transactions = Vec::with_capacity(max_txs_in_block.get()); self.get_transactions_for_block(state_view, max_txs_in_block, &mut transactions); transactions } @@ -297,10 +297,10 @@ impl Queue { pub fn get_transactions_for_block( &self, state_view: &StateView, - max_txs_in_block: usize, + max_txs_in_block: NonZeroUsize, transactions: &mut Vec, ) { - if transactions.len() >= max_txs_in_block { + if transactions.len() >= max_txs_in_block.get() { return; } @@ -315,7 +315,7 @@ impl Queue { transactions.iter().map(|tx| tx.as_ref().hash()).collect(); let txs = txs_from_queue .filter(|tx| !transactions_hashes.contains(&tx.as_ref().hash())) - .take(max_txs_in_block - transactions.len()); + .take(max_txs_in_block.get() - transactions.len()); transactions.extend(txs); seen_queue @@ -377,7 +377,7 @@ impl Queue { pub mod tests { use std::{str::FromStr, sync::Arc, thread, time::Duration}; - use iroha_data_model::{prelude::*, transaction::TransactionLimits}; + use iroha_data_model::{param::TransactionLimits, prelude::*}; use nonzero_ext::nonzero; use rand::Rng as _; use test_samples::gen_account_in; @@ -428,8 +428,8 @@ pub mod tests { .with_instructions(instructions) .sign(key_pair.private_key()); let limits = TransactionLimits { - max_instruction_number: 4096, - max_wasm_size_bytes: 0, + max_instructions: nonzero!(4096_u64), + smart_contract_size: nonzero!(1024_u64), }; AcceptedTransaction::accept(tx, &chain_id, limits).expect("Failed to accept Transaction.") } @@ -504,7 +504,7 @@ pub mod tests { #[test] async fn get_available_txs() { - let max_txs_in_block = 2; + let max_txs_in_block = nonzero!(2_usize); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = Arc::new(State::new(world_with_test_domains(), kura, query_handle)); @@ -527,7 +527,7 @@ pub mod tests { } let available = queue.collect_transactions_for_block(&state_view, max_txs_in_block); - assert_eq!(available.len(), max_txs_in_block); + assert_eq!(available.len(), max_txs_in_block.get()); } #[test] @@ -538,7 +538,9 @@ pub mod tests { let (_time_handle, time_source) = TimeSource::new_mock(Duration::default()); let tx = accepted_tx_by_someone(&time_source); let mut state_block = state.block(); - state_block.transactions.insert(tx.as_ref().hash(), 1); + state_block + .transactions + .insert(tx.as_ref().hash(), nonzero!(1_usize)); state_block.commit(); let state_view = state.view(); let queue = Queue::test(config_factory(), &time_source); @@ -554,7 +556,7 @@ pub mod tests { #[test] async fn get_tx_drop_if_in_blockchain() { - let max_txs_in_block = 2; + let max_txs_in_block = nonzero!(2_usize); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = State::new(world_with_test_domains(), kura, query_handle); @@ -563,7 +565,9 @@ pub mod tests { let queue = Queue::test(config_factory(), &time_source); queue.push(tx.clone(), &state.view()).unwrap(); let mut state_block = state.block(); - state_block.transactions.insert(tx.as_ref().hash(), 1); + state_block + .transactions + .insert(tx.as_ref().hash(), nonzero!(1_usize)); state_block.commit(); assert_eq!( queue @@ -576,7 +580,7 @@ pub mod tests { #[test] async fn get_available_txs_with_timeout() { - let max_txs_in_block = 6; + let max_txs_in_block = nonzero!(6_usize); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = Arc::new(State::new(world_with_test_domains(), kura, query_handle)); @@ -591,7 +595,7 @@ pub mod tests { }, &time_source, ); - for _ in 0..(max_txs_in_block - 1) { + for _ in 0..(max_txs_in_block.get() - 1) { queue .push(accepted_tx_by_someone(&time_source), &state_view) .expect("Failed to push tx into queue"); @@ -625,7 +629,7 @@ pub mod tests { // Others should stay in the queue until that moment. #[test] async fn transactions_available_after_pop() { - let max_txs_in_block = 2; + let max_txs_in_block = nonzero!(2_usize); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = Arc::new(State::new(world_with_test_domains(), kura, query_handle)); @@ -658,7 +662,7 @@ pub mod tests { let chain_id = ChainId::from("00000000-0000-0000-0000-000000000000"); - let max_txs_in_block = 2; + let max_txs_in_block = nonzero!(2_usize); let (alice_id, alice_keypair) = gen_account_in("wonderland"); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); @@ -678,8 +682,8 @@ pub mod tests { tx.set_ttl(Duration::from_millis(TTL_MS)); let tx = tx.sign(alice_keypair.private_key()); let limits = TransactionLimits { - max_instruction_number: 4096, - max_wasm_size_bytes: 0, + max_instructions: nonzero!(4096_u64), + smart_contract_size: nonzero!(1024_u64), }; let tx_hash = tx.hash(); let tx = AcceptedTransaction::accept(tx, &chain_id, limits) @@ -718,7 +722,7 @@ pub mod tests { #[test] async fn concurrent_stress_test() { - let max_txs_in_block = 10; + let max_txs_in_block = nonzero!(10_usize); let kura = Kura::blank_kura_for_testing(); let query_handle = LiveQueryStore::test().start(); let state = Arc::new(State::new(world_with_test_domains(), kura, query_handle)); @@ -766,7 +770,9 @@ pub mod tests { for tx in queue.collect_transactions_for_block(&state.view(), max_txs_in_block) { let mut state_block = state.block(); - state_block.transactions.insert(tx.as_ref().hash(), 1); + state_block + .transactions + .insert(tx.as_ref().hash(), nonzero!(1_usize)); state_block.commit(); } // Simulate random small delays @@ -884,18 +890,18 @@ pub mod tests { ) .expect("Failed to push tx into queue"); - let transactions = queue.collect_transactions_for_block(&state.view(), 10); + let transactions = queue.collect_transactions_for_block(&state.view(), nonzero!(10_usize)); assert_eq!(transactions.len(), 2); let mut state_block = state.block(); for transaction in transactions { // Put transaction hashes into state as if they were in the blockchain state_block .transactions - .insert(transaction.as_ref().hash(), 1); + .insert(transaction.as_ref().hash(), nonzero!(1_usize)); } state_block.commit(); // Cleanup transactions - let transactions = queue.collect_transactions_for_block(&state.view(), 10); + let transactions = queue.collect_transactions_for_block(&state.view(), nonzero!(10_usize)); assert!(transactions.is_empty()); // After cleanup Alice and Bob pushes should work fine diff --git a/core/src/smartcontracts/isi/account.rs b/core/src/smartcontracts/isi/account.rs index bea9b9c375f..2a91d62a6f7 100644 --- a/core/src/smartcontracts/isi/account.rs +++ b/core/src/smartcontracts/isi/account.rs @@ -28,7 +28,7 @@ pub mod isi { asset::{AssetValue, AssetValueType}, isi::{ error::{MintabilityError, RepetitionError}, - InstructionType, + InstructionId, }, query::error::QueryExecutionFail, }; @@ -78,7 +78,7 @@ pub mod isi { _ => Err(err.into()), }, Ok(_) => Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::AssetId(asset_id.clone()), } .into()), @@ -119,7 +119,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AccountEvent::Asset(AssetEvent::Removed( + .emit_events(Some(AccountEvent::Asset(AssetEvent::Remove( AssetChanged { asset: asset.id, amount: asset.value, @@ -154,7 +154,7 @@ pub mod isi { asset_definition.owned_by = destination.clone(); state_transaction .world - .emit_events(Some(AssetDefinitionEvent::OwnerChanged( + .emit_events(Some(AssetDefinitionEvent::OwnerChange( AssetDefinitionOwnerChanged { asset_definition: object, new_owner: destination, @@ -174,26 +174,19 @@ pub mod isi { ) -> Result<(), Error> { let account_id = self.object; - let account_metadata_limits = state_transaction.config.account_metadata_limits; - state_transaction .world .account_mut(&account_id) .map_err(Error::from) - .and_then(|account| { + .map(|account| { account .metadata - .insert_with_limits( - self.key.clone(), - self.value.clone(), - account_metadata_limits, - ) - .map_err(Error::from) + .insert(self.key.clone(), self.value.clone()) })?; state_transaction .world - .emit_events(Some(AccountEvent::MetadataInserted(MetadataChanged { + .emit_events(Some(AccountEvent::MetadataInsert(MetadataChanged { target: account_id, key: self.key, value: self.value, @@ -224,7 +217,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AccountEvent::MetadataRemoved(MetadataChanged { + .emit_events(Some(AccountEvent::MetadataRemove(MetadataChanged { target: account_id, key: self.key, value, @@ -262,7 +255,7 @@ pub mod isi { .account_contains_inherent_permission(&account_id, &permission) { return Err(RepetitionError { - instruction_type: InstructionType::Grant, + instruction_type: InstructionId::Grant, id: permission.id.into(), } .into()); @@ -274,7 +267,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AccountEvent::PermissionAdded( + .emit_events(Some(AccountEvent::PermissionAdd( AccountPermissionChanged { account: account_id, permission: permission_id, @@ -307,7 +300,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AccountEvent::PermissionRemoved( + .emit_events(Some(AccountEvent::PermissionRemove( AccountPermissionChanged { account: account_id, permission: permission.id, @@ -350,7 +343,7 @@ pub mod isi { .is_some() { return Err(RepetitionError { - instruction_type: InstructionType::Grant, + instruction_type: InstructionId::Grant, id: IdBox::RoleId(role_id), } .into()); @@ -364,8 +357,8 @@ pub mod isi { account: account_id, permission: permission_id, }) - .map(AccountEvent::PermissionAdded) - .chain(std::iter::once(AccountEvent::RoleGranted( + .map(AccountEvent::PermissionAdd) + .chain(std::iter::once(AccountEvent::RoleGrant( AccountRoleChanged { account: account_id_clone, role: role_id, @@ -417,8 +410,8 @@ pub mod isi { account: account_id, permission: permission_id, }) - .map(AccountEvent::PermissionRemoved) - .chain(std::iter::once(AccountEvent::RoleRevoked( + .map(AccountEvent::PermissionRemove) + .chain(std::iter::once(AccountEvent::RoleRevoke( AccountRoleChanged { account: account_id_clone, role: role_id, @@ -459,7 +452,7 @@ pub mod isi { .asset_definition_mut(definition_id)?; forbid_minting(asset_definition)?; state_transaction.world.emit_events(Some( - AssetDefinitionEvent::MintabilityChanged(definition_id.clone()), + AssetDefinitionEvent::MintabilityChange(definition_id.clone()), )); } Ok(()) diff --git a/core/src/smartcontracts/isi/asset.rs b/core/src/smartcontracts/isi/asset.rs index 38621f4ec5d..000b036e237 100644 --- a/core/src/smartcontracts/isi/asset.rs +++ b/core/src/smartcontracts/isi/asset.rs @@ -62,26 +62,21 @@ pub mod isi { .increase_asset_total_amount(&asset_id.definition, Numeric::ONE)?; } - let asset_metadata_limits = state_transaction.config.asset_metadata_limits; let asset = state_transaction .world - .asset_or_insert(asset_id.clone(), Metadata::new())?; + .asset_or_insert(asset_id.clone(), Metadata::default())?; { let AssetValue::Store(store) = &mut asset.value else { return Err(Error::Conversion("Expected store asset type".to_owned())); }; - store.insert_with_limits( - self.key.clone(), - self.value.clone(), - asset_metadata_limits, - )?; + store.insert(self.key.clone(), self.value.clone()); } state_transaction .world - .emit_events(Some(AssetEvent::MetadataInserted(MetadataChanged { + .emit_events(Some(AssetEvent::MetadataInsert(MetadataChanged { target: asset_id, key: self.key, value: self.value, @@ -120,7 +115,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AssetEvent::MetadataRemoved(MetadataChanged { + .emit_events(Some(AssetEvent::MetadataRemove(MetadataChanged { target: asset_id, key: self.key, value, @@ -164,8 +159,8 @@ pub mod isi { }; state_transaction.world.emit_events([ - AssetEvent::Deleted(asset_id), - AssetEvent::Created(destination_store), + AssetEvent::Delete(asset_id), + AssetEvent::Create(destination_store), ]); Ok(()) @@ -211,7 +206,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AssetEvent::Added(AssetChanged { + .emit_events(Some(AssetEvent::Add(AssetChanged { asset: asset_id, amount: self.object.into(), }))); @@ -264,7 +259,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AssetEvent::Removed(AssetChanged { + .emit_events(Some(AssetEvent::Remove(AssetChanged { asset: asset_id.clone(), amount: self.object.into(), }))); @@ -328,11 +323,11 @@ pub mod isi { } state_transaction.world.emit_events([ - AssetEvent::Removed(AssetChanged { + AssetEvent::Remove(AssetChanged { asset: source_id, amount: self.object.into(), }), - AssetEvent::Added(AssetChanged { + AssetEvent::Add(AssetChanged { asset: destination_id, amount: self.object.into(), }), @@ -394,9 +389,11 @@ pub mod isi { .world .asset_definition_mut(&asset_definition_id)?; forbid_minting(asset_definition)?; - state_transaction.world.emit_events(Some( - AssetDefinitionEvent::MintabilityChanged(asset_definition_id), - )); + state_transaction + .world + .emit_events(Some(AssetDefinitionEvent::MintabilityChange( + asset_definition_id, + ))); Ok(()) } } diff --git a/core/src/smartcontracts/isi/domain.rs b/core/src/smartcontracts/isi/domain.rs index 5dcad8e7b58..b77b4acb149 100644 --- a/core/src/smartcontracts/isi/domain.rs +++ b/core/src/smartcontracts/isi/domain.rs @@ -57,7 +57,7 @@ pub mod isi { let _domain = state_transaction.world.domain_mut(&account_id.domain)?; if state_transaction.world.account(&account_id).is_ok() { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::AccountId(account_id), } .into()); @@ -69,7 +69,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(DomainEvent::Account(AccountEvent::Created(account)))); + .emit_events(Some(DomainEvent::Account(AccountEvent::Create(account)))); Ok(()) } @@ -113,7 +113,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AccountEvent::Deleted(account_id))); + .emit_events(Some(AccountEvent::Delete(account_id))); Ok(()) } @@ -127,11 +127,6 @@ pub mod isi { state_transaction: &mut StateTransaction<'_, '_>, ) -> Result<(), Error> { let asset_definition = self.object.build(authority); - asset_definition - .id() - .name - .validate_len(state_transaction.config.ident_length_limits) - .map_err(Error::from)?; let asset_definition_id = asset_definition.id().clone(); let domain = state_transaction @@ -139,7 +134,7 @@ pub mod isi { .domain_mut(&asset_definition_id.domain)?; if domain.asset_definitions.contains_key(&asset_definition_id) { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::AssetDefinitionId(asset_definition_id), } .into()); @@ -152,7 +147,7 @@ pub mod isi { state_transaction .world .emit_events(Some(DomainEvent::AssetDefinition( - AssetDefinitionEvent::Created(asset_definition), + AssetDefinitionEvent::Create(asset_definition), ))); Ok(()) @@ -196,7 +191,7 @@ pub mod isi { error!(%asset_id, "asset not found. This is a bug"); } - events.push(AccountEvent::Asset(AssetEvent::Deleted(asset_id)).into()); + events.push(AccountEvent::Asset(AssetEvent::Delete(asset_id)).into()); } let domain = state_transaction @@ -212,7 +207,7 @@ pub mod isi { domain.remove_asset_total_quantity(&asset_definition_id); events.push(DataEvent::from(DomainEvent::AssetDefinition( - AssetDefinitionEvent::Deleted(asset_definition_id), + AssetDefinitionEvent::Delete(asset_definition_id), ))); state_transaction.world.emit_events(events); @@ -230,21 +225,19 @@ pub mod isi { ) -> Result<(), Error> { let asset_definition_id = self.object; - let metadata_limits = state_transaction.config.asset_definition_metadata_limits; state_transaction .world .asset_definition_mut(&asset_definition_id) .map_err(Error::from) - .and_then(|asset_definition| { + .map(|asset_definition| { asset_definition .metadata - .insert_with_limits(self.key.clone(), self.value.clone(), metadata_limits) - .map_err(Error::from) + .insert(self.key.clone(), self.value.clone()) })?; state_transaction .world - .emit_events(Some(AssetDefinitionEvent::MetadataInserted( + .emit_events(Some(AssetDefinitionEvent::MetadataInsert( MetadataChanged { target: asset_definition_id, key: self.key, @@ -277,7 +270,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(AssetDefinitionEvent::MetadataRemoved( + .emit_events(Some(AssetDefinitionEvent::MetadataRemove( MetadataChanged { target: asset_definition_id, key: self.key, @@ -298,16 +291,12 @@ pub mod isi { ) -> Result<(), Error> { let domain_id = self.object; - let limits = state_transaction.config.domain_metadata_limits; - let domain = state_transaction.world.domain_mut(&domain_id)?; - domain - .metadata - .insert_with_limits(self.key.clone(), self.value.clone(), limits)?; + domain.metadata.insert(self.key.clone(), self.value.clone()); state_transaction .world - .emit_events(Some(DomainEvent::MetadataInserted(MetadataChanged { + .emit_events(Some(DomainEvent::MetadataInsert(MetadataChanged { target: domain_id, key: self.key, value: self.value, @@ -334,7 +323,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(DomainEvent::MetadataRemoved(MetadataChanged { + .emit_events(Some(DomainEvent::MetadataRemove(MetadataChanged { target: domain_id, key: self.key, value, @@ -368,7 +357,7 @@ pub mod isi { domain.owned_by = destination.clone(); state_transaction .world - .emit_events(Some(DomainEvent::OwnerChanged(DomainOwnerChanged { + .emit_events(Some(DomainEvent::OwnerChange(DomainOwnerChanged { domain: object, new_owner: destination, }))); diff --git a/core/src/smartcontracts/isi/mod.rs b/core/src/smartcontracts/isi/mod.rs index 72282ac66b4..e62defc6da3 100644 --- a/core/src/smartcontracts/isi/mod.rs +++ b/core/src/smartcontracts/isi/mod.rs @@ -55,7 +55,6 @@ impl Execute for InstructionBox { Self::Revoke(isi) => isi.execute(authority, state_transaction), Self::ExecuteTrigger(isi) => isi.execute(authority, state_transaction), Self::SetParameter(isi) => isi.execute(authority, state_transaction), - Self::NewParameter(isi) => isi.execute(authority, state_transaction), Self::Upgrade(isi) => isi.execute(authority, state_transaction), Self::Log(isi) => isi.execute(authority, state_transaction), Self::Custom(_) => { diff --git a/core/src/smartcontracts/isi/query.rs b/core/src/smartcontracts/isi/query.rs index a7f295cba25..fe382438ffd 100644 --- a/core/src/smartcontracts/isi/query.rs +++ b/core/src/smartcontracts/isi/query.rs @@ -169,6 +169,7 @@ impl_lazy! { iroha_data_model::query::TransactionQueryOutput, iroha_data_model::executor::ExecutorDataModel, iroha_data_model::trigger::Trigger, + iroha_data_model::param::Parameters, } /// Query Request statefully validated on the Iroha node side. @@ -256,6 +257,7 @@ impl ValidQuery for QueryBox { FindAssetDefinitionKeyValueByIdAndKey, FindTriggerKeyValueByIdAndKey, FindExecutorDataModel, + FindAllParameters, } FindAllAccounts, @@ -281,7 +283,6 @@ impl ValidQuery for QueryBox { FindAllRoles, FindAllRoleIds, FindRolesByAccountId, - FindAllParameters, } } } @@ -292,8 +293,9 @@ mod tests { use iroha_crypto::{Hash, HashOf, KeyPair}; use iroha_data_model::{ - metadata::MetadataValueBox, query::error::FindError, transaction::TransactionLimits, + metadata::MetadataValueBox, param::TransactionLimits, query::error::FindError, }; + use nonzero_ext::nonzero; use test_samples::{gen_account_in, ALICE_ID, ALICE_KEYPAIR}; use tokio::test; @@ -331,12 +333,11 @@ mod tests { ) .is_none()); - let mut store = Metadata::new(); + let mut store = Metadata::default(); store - .insert_with_limits( + .insert( Name::from_str("Bytes").expect("Valid"), MetadataValueBox::Vec(vec![1_u32.into(), 2_u32.into(), 3_u32.into()]), - MetadataLimits::new(10, 100), ) .unwrap(); let asset_id = AssetId::new(asset_definition_id, account.id().clone()); @@ -347,12 +348,11 @@ mod tests { } fn world_with_test_account_with_metadata() -> Result { - let mut metadata = Metadata::new(); - metadata.insert_with_limits( + let mut metadata = Metadata::default(); + metadata.insert( Name::from_str("Bytes")?, MetadataValueBox::Vec(vec![1_u32.into(), 2_u32.into(), 3_u32.into()]), - MetadataLimits::new(10, 100), - )?; + ); let mut domain = Domain::new(DomainId::from_str("wonderland")?).build(&ALICE_ID); let account = Account::new(ALICE_ID.clone()) @@ -378,15 +378,15 @@ mod tests { { let mut state_block = state.block(); let limits = TransactionLimits { - max_instruction_number: 1, - max_wasm_size_bytes: 0, + max_instructions: nonzero!(1000_u64), + smart_contract_size: nonzero!(1024_u64), }; let huge_limits = TransactionLimits { - max_instruction_number: 1000, - max_wasm_size_bytes: 0, + max_instructions: nonzero!(1000_u64), + smart_contract_size: nonzero!(1024_u64), }; - state_block.config.transaction_limits = limits; + state_block.world.parameters.transaction_limits = limits; let valid_tx = { let instructions: [InstructionBox; 0] = []; @@ -606,12 +606,11 @@ mod tests { async fn domain_metadata() -> Result<()> { let kura = Kura::blank_kura_for_testing(); let state = { - let mut metadata = Metadata::new(); - metadata.insert_with_limits( + let mut metadata = Metadata::default(); + metadata.insert( Name::from_str("Bytes")?, MetadataValueBox::Vec(vec![1_u32.into(), 2_u32.into(), 3_u32.into()]), - MetadataLimits::new(10, 100), - )?; + ); let mut domain = Domain::new(DomainId::from_str("wonderland")?) .with_metadata(metadata) .build(&ALICE_ID); diff --git a/core/src/smartcontracts/isi/triggers/mod.rs b/core/src/smartcontracts/isi/triggers/mod.rs index aeb80783ea6..f92f2df3438 100644 --- a/core/src/smartcontracts/isi/triggers/mod.rs +++ b/core/src/smartcontracts/isi/triggers/mod.rs @@ -99,7 +99,7 @@ pub mod isi { if !success { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: trigger_id.into(), } .into()); @@ -107,7 +107,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(TriggerEvent::Created(trigger_id))); + .emit_events(Some(TriggerEvent::Create(trigger_id))); Ok(()) } @@ -126,11 +126,11 @@ pub mod isi { if triggers.remove(trigger_id.clone()) { state_transaction .world - .emit_events(Some(TriggerEvent::Deleted(trigger_id))); + .emit_events(Some(TriggerEvent::Delete(trigger_id))); Ok(()) } else { Err(RepetitionError { - instruction_type: InstructionType::Unregister, + instruction_type: InstructionId::Unregister, id: trigger_id.into(), } .into()) @@ -165,7 +165,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(TriggerEvent::Extended( + .emit_events(Some(TriggerEvent::Extend( TriggerNumberOfExecutionsChanged { trigger: id, by: self.object, @@ -193,7 +193,7 @@ pub mod isi { // when they will match some of the events? state_transaction .world - .emit_events(Some(TriggerEvent::Shortened( + .emit_events(Some(TriggerEvent::Shorten( TriggerNumberOfExecutionsChanged { trigger, by: self.object, @@ -213,22 +213,19 @@ pub mod isi { ) -> Result<(), Error> { let trigger_id = self.object; - let trigger_metadata_limits = state_transaction.config.account_metadata_limits; state_transaction .world .triggers .inspect_by_id_mut(&trigger_id, |action| { - action.metadata_mut().insert_with_limits( - self.key.clone(), - self.value.clone(), - trigger_metadata_limits, - ) + action + .metadata_mut() + .insert(self.key.clone(), self.value.clone()) }) - .ok_or(FindError::Trigger(trigger_id.clone()))??; + .ok_or(FindError::Trigger(trigger_id.clone()))?; state_transaction .world - .emit_events(Some(TriggerEvent::MetadataInserted(MetadataChanged { + .emit_events(Some(TriggerEvent::MetadataInsert(MetadataChanged { target: trigger_id, key: self.key, value: self.value, @@ -260,7 +257,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(TriggerEvent::MetadataRemoved(MetadataChanged { + .emit_events(Some(TriggerEvent::MetadataRemove(MetadataChanged { target: trigger_id, key: self.key, value, diff --git a/core/src/smartcontracts/isi/triggers/specialized.rs b/core/src/smartcontracts/isi/triggers/specialized.rs index 5409cf8a070..a3deafa5d83 100644 --- a/core/src/smartcontracts/isi/triggers/specialized.rs +++ b/core/src/smartcontracts/isi/triggers/specialized.rs @@ -45,7 +45,7 @@ impl SpecializedAction { // TODO: At this point the authority is meaningless. authority, filter, - metadata: Metadata::new(), + metadata: Metadata::default(), } } } diff --git a/core/src/smartcontracts/isi/world.rs b/core/src/smartcontracts/isi/world.rs index 72b65dc194b..3797bde1d19 100644 --- a/core/src/smartcontracts/isi/world.rs +++ b/core/src/smartcontracts/isi/world.rs @@ -21,7 +21,8 @@ pub mod isi { use eyre::Result; use iroha_data_model::{ - isi::error::{InstructionExecutionError, InvalidParameterError, RepetitionError}, + isi::error::{InvalidParameterError, RepetitionError}, + param::Parameter, prelude::*, query::error::FindError, Level, @@ -43,13 +44,13 @@ pub mod isi { if let PushResult::Duplicate(duplicate) = world.trusted_peers_ids.push(peer_id.clone()) { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::PeerId(duplicate), } .into()); } - world.emit_events(Some(PeerEvent::Added(peer_id))); + world.emit_events(Some(PeerEvent::Add(peer_id))); Ok(()) } @@ -70,7 +71,7 @@ pub mod isi { world.trusted_peers_ids.remove(index); - world.emit_events(Some(PeerEvent::Removed(peer_id))); + world.emit_events(Some(PeerEvent::Remove(peer_id))); Ok(()) } @@ -86,21 +87,10 @@ pub mod isi { let domain: Domain = self.object.build(authority); let domain_id = domain.id().clone(); - domain_id - .name - .validate_len(state_transaction.config.ident_length_limits) - .map_err(Error::from)?; - - if domain_id == *iroha_genesis::GENESIS_DOMAIN_ID { - return Err(InstructionExecutionError::InvariantViolation( - "Not allowed to register genesis domain".to_owned(), - )); - } - let world = &mut state_transaction.world; if world.domains.get(&domain_id).is_some() { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::DomainId(domain_id), } .into()); @@ -108,7 +98,7 @@ pub mod isi { world.domains.insert(domain_id, domain.clone()); - world.emit_events(Some(DomainEvent::Created(domain))); + world.emit_events(Some(DomainEvent::Create(domain))); Ok(()) } @@ -161,7 +151,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(DomainEvent::Deleted(domain_id))); + .emit_events(Some(DomainEvent::Delete(domain_id))); Ok(()) } @@ -178,7 +168,7 @@ pub mod isi { if state_transaction.world.roles.get(role.id()).is_some() { return Err(RepetitionError { - instruction_type: InstructionType::Register, + instruction_type: InstructionId::Register, id: IdBox::RoleId(role.id), } .into()); @@ -199,7 +189,7 @@ pub mod isi { let role_id = role.id().clone(); world.roles.insert(role_id, role.clone()); - world.emit_events(Some(RoleEvent::Created(role))); + world.emit_events(Some(RoleEvent::Create(role))); Ok(()) } @@ -237,7 +227,7 @@ pub mod isi { return Err(FindError::Role(role_id).into()); } - world.emit_events(Some(RoleEvent::Deleted(role_id))); + world.emit_events(Some(RoleEvent::Delete(role_id))); Ok(()) } @@ -269,7 +259,7 @@ pub mod isi { if !role.permissions.insert(permission.clone()) { return Err(RepetitionError { - instruction_type: InstructionType::Grant, + instruction_type: InstructionId::Grant, id: permission.id.into(), } .into()); @@ -277,7 +267,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(RoleEvent::PermissionAdded(RolePermissionChanged { + .emit_events(Some(RoleEvent::PermissionAdd(RolePermissionChanged { role: role_id, permission: permission_id, }))); @@ -307,7 +297,7 @@ pub mod isi { state_transaction .world - .emit_events(Some(RoleEvent::PermissionRemoved(RolePermissionChanged { + .emit_events(Some(RoleEvent::PermissionRemove(RolePermissionChanged { role: role_id, permission: permission_id, }))); @@ -323,43 +313,90 @@ pub mod isi { _authority: &AccountId, state_transaction: &mut StateTransaction<'_, '_>, ) -> Result<(), Error> { - let parameter = self.parameter; - let parameter_id = parameter.id.clone(); + match self.0 { + Parameter::BlockTime(duration) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.block_time, + duration, + ); - if !state_transaction.world.parameters.swap_remove(¶meter) { - return Err(FindError::Parameter(parameter_id).into()); - } - state_transaction.world.parameters.insert(parameter.clone()); - state_transaction - .world - .emit_events(Some(ConfigurationEvent::Changed(parameter_id))); - state_transaction.try_apply_core_parameter(parameter); + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change(Parameter::BlockTime( + old_param, + )))); + } + Parameter::CommitTime(duration) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.commit_time, + duration, + ); - Ok(()) - } - } + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change(Parameter::CommitTime( + old_param, + )))); + } + Parameter::BlockLimits(block_limits) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.block_limits, + block_limits, + ); - impl Execute for NewParameter { - #[metrics(+"new_parameter")] - fn execute( - self, - _authority: &AccountId, - state_transaction: &mut StateTransaction<'_, '_>, - ) -> Result<(), Error> { - let parameter = self.parameter; - let parameter_id = parameter.id.clone(); + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change(Parameter::BlockLimits( + old_param, + )))); + } + Parameter::TransactionLimits(txn_limits) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.transaction_limits, + txn_limits, + ); - if !state_transaction.world.parameters.insert(parameter.clone()) { - return Err(RepetitionError { - instruction_type: InstructionType::NewParameter, - id: IdBox::ParameterId(parameter_id), + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change( + Parameter::TransactionLimits(old_param), + ))); + } + Parameter::SmartContractLimits(limits) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.smart_contract_limits, + limits, + ); + + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change( + Parameter::SmartContractLimits(old_param), + ))); + } + Parameter::ExecutorLimits(limits) => { + let old_param = core::mem::replace( + &mut state_transaction.world.parameters.executor_limits, + limits, + ); + + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change(Parameter::ExecutorLimits( + old_param, + )))); + } + Parameter::Custom(custom) => { + let old_param = + core::mem::replace(&mut state_transaction.world.parameters.custom, custom); + + state_transaction + .world + .emit_events(Some(ConfigurationEvent::Change(Parameter::Custom( + old_param, + )))); } - .into()); } - state_transaction - .world - .emit_events(Some(ConfigurationEvent::Created(parameter_id))); - state_transaction.try_apply_core_parameter(parameter); Ok(()) } @@ -398,7 +435,7 @@ pub mod isi { state_transaction .world - .emit_events(std::iter::once(ExecutorEvent::Upgraded(ExecutorUpgrade { + .emit_events(std::iter::once(ExecutorEvent::Upgrade(ExecutorUpgrade { new_data_model: state_transaction.world.executor_data_model.clone(), }))); @@ -492,7 +529,7 @@ pub mod isi { pub mod query { use eyre::Result; use iroha_data_model::{ - parameter::Parameter, + param::Parameters, peer::Peer, prelude::*, query::error::{FindError, QueryExecutionFail as Error}, @@ -570,11 +607,8 @@ pub mod query { impl ValidQuery for FindAllParameters { #[metrics("find_all_parameters")] - fn execute<'state>( - &self, - state_ro: &'state impl StateReadOnly, - ) -> Result + 'state>, Error> { - Ok(Box::new(state_ro.world().parameters_iter().cloned())) + fn execute(&self, state_ro: &impl StateReadOnly) -> Result { + Ok(state_ro.world().parameters().clone()) } } } diff --git a/core/src/smartcontracts/wasm.rs b/core/src/smartcontracts/wasm.rs index 9ab00dcbcf3..7b38d8c30d4 100644 --- a/core/src/smartcontracts/wasm.rs +++ b/core/src/smartcontracts/wasm.rs @@ -2,15 +2,15 @@ //! `WebAssembly` VM Smartcontracts can be written in Rust, compiled //! to wasm format and submitted in a transaction -use std::borrow::Borrow; +use std::{borrow::Borrow, num::NonZeroU64}; use error::*; use import::traits::{ExecuteOperations as _, GetExecutorPayloads as _, SetDataModel as _}; -use iroha_config::parameters::actual::WasmRuntime as Config; use iroha_data_model::{ account::AccountId, executor::{self, ExecutorDataModel, MigrationResult}, isi::InstructionBox, + param::SmartContractLimits as Config, prelude::*, query::{QueryBox, QueryId, QueryOutputBox, QueryRequest, SmartContractQuery}, smart_contract::payloads::{self, Validate}, @@ -299,12 +299,12 @@ struct LimitsExecutor { /// Number of instructions in the smartcontract instruction_count: u64, /// Max allowed number of instructions in the smartcontract - max_instruction_count: u64, + max_instruction_count: NonZeroU64, } impl LimitsExecutor { /// Create new [`LimitsExecutor`] - pub fn new(max_instruction_count: u64) -> Self { + pub fn new(max_instruction_count: NonZeroU64) -> Self { Self { instruction_count: 0, max_instruction_count, @@ -320,7 +320,7 @@ impl LimitsExecutor { pub fn check_instruction_limits(&mut self) -> Result<(), ValidationFail> { self.instruction_count += 1; - if self.instruction_count > self.max_instruction_count { + if self.instruction_count > self.max_instruction_count.get() { return Err(ValidationFail::TooComplex); } @@ -344,8 +344,14 @@ pub mod state { /// Panics if failed to convert `u32` into `usize` which should not happen /// on any supported platform pub fn store_limits_from_config(config: &Config) -> StoreLimits { + let memory_size = config + .memory + .get() + .try_into() + .expect("INTERNAL BUG: memory limit exceeds u64::MAX"); + StoreLimitsBuilder::new() - .memory_size(config.max_memory.get() as usize) + .memory_size(memory_size) .instances(1) .memories(1) .tables(1) @@ -738,7 +744,7 @@ impl Runtime> { store.limiter(|s| &mut s.store_limits); store - .set_fuel(self.config.fuel_limit) + .set_fuel(self.config.fuel.get()) .expect("Wasm Runtime config is malformed, this is a bug"); store @@ -899,7 +905,7 @@ impl<'wrld, 'block: 'wrld, 'state: 'block> Runtime, authority: AccountId, bytes: impl AsRef<[u8]>, - max_instruction_count: u64, + max_instruction_count: NonZeroU64, ) -> Result<()> { let span = wasm_log_span!("Smart contract validation", %authority); let state = state::SmartContract::new( @@ -1706,6 +1712,7 @@ impl GetExport for (&wasmtime::Instance, C) { #[cfg(test)] mod tests { use iroha_data_model::query::{predicate::PredicateBox, sorting::Sorting, Pagination}; + use nonzero_ext::nonzero; use parity_scale_codec::Encode; use test_samples::gen_account_in; use tokio::test; @@ -1893,7 +1900,12 @@ mod tests { ); let mut runtime = RuntimeBuilder::::new().build()?; - let res = runtime.validate(&mut state.block().transaction(), authority, wat, 1); + let res = runtime.validate( + &mut state.block().transaction(), + authority, + wat, + nonzero!(1_u64), + ); if let Error::ExportFnCall(ExportFnCallError::Other(report)) = res.expect_err("Execution should fail") @@ -1942,7 +1954,12 @@ mod tests { ); let mut runtime = RuntimeBuilder::::new().build()?; - let res = runtime.validate(&mut state.block().transaction(), authority, wat, 1); + let res = runtime.validate( + &mut state.block().transaction(), + authority, + wat, + nonzero!(1_u64), + ); if let Error::ExportFnCall(ExportFnCallError::HostExecution(report)) = res.expect_err("Execution should fail") @@ -1986,7 +2003,12 @@ mod tests { ); let mut runtime = RuntimeBuilder::::new().build()?; - let res = runtime.validate(&mut state.block().transaction(), authority, wat, 1); + let res = runtime.validate( + &mut state.block().transaction(), + authority, + wat, + nonzero!(1_u64), + ); if let Error::ExportFnCall(ExportFnCallError::HostExecution(report)) = res.expect_err("Execution should fail") diff --git a/core/src/state.rs b/core/src/state.rs index 0c00cb5467b..21d666be45a 100644 --- a/core/src/state.rs +++ b/core/src/state.rs @@ -1,15 +1,9 @@ //! This module provides the [`State`] — an in-memory representation of the current blockchain state. use std::{ - borrow::Borrow, - collections::BTreeSet, - marker::PhantomData, - num::{NonZeroU32, NonZeroUsize}, - sync::Arc, - time::Duration, + collections::BTreeSet, marker::PhantomData, num::NonZeroUsize, sync::Arc, time::Duration, }; use eyre::Result; -use iroha_config::{base::util::Bytes, parameters::actual::ChainWide as Config}; use iroha_crypto::HashOf; use iroha_data_model::{ account::AccountId, @@ -22,7 +16,7 @@ use iroha_data_model::{ }, executor::ExecutorDataModel, isi::error::{InstructionExecutionError as Error, MathError}, - parameter::{Parameter, ParameterValueBox}, + param::Parameters, permission::Permissions, prelude::*, query::error::{FindError, QueryExecutionFail}, @@ -62,14 +56,14 @@ use crate::{ wasm, Execute, }, tx::TransactionExecutor, - Parameters, PeersIds, + PeersIds, }; /// The global entity consisting of `domains`, `triggers` and etc. /// For example registration of domain, will have this as an ISI target. #[derive(Default, Serialize)] pub struct World { - /// Iroha config parameters. + /// Iroha on-chain built-in parameters. pub(crate) parameters: Cell, /// Identifications of discovered trusted peers. pub(crate) trusted_peers_ids: Cell, @@ -93,8 +87,8 @@ pub struct World { /// Struct for block's aggregated changes pub struct WorldBlock<'world> { - /// Iroha config parameters. - pub(crate) parameters: CellBlock<'world, Parameters>, + /// Iroha on-chain built-in parameters. + pub parameters: CellBlock<'world, Parameters>, /// Identifications of discovered trusted peers. pub(crate) trusted_peers_ids: CellBlock<'world, PeersIds>, /// Registered domains. @@ -119,7 +113,7 @@ pub struct WorldBlock<'world> { /// Struct for single transaction's aggregated changes pub struct WorldTransaction<'block, 'world> { - /// Iroha config parameters. + /// Iroha on-chain built-in parameters. pub(crate) parameters: CellTransaction<'block, 'world, Parameters>, /// Identifications of discovered trusted peers. pub(crate) trusted_peers_ids: CellTransaction<'block, 'world, PeersIds>, @@ -153,7 +147,7 @@ struct TransactionEventBuffer<'block> { /// Consistent point in time view of the [`World`] pub struct WorldView<'world> { - /// Iroha config parameters. + /// Iroha on-chain built-in parameters. pub(crate) parameters: CellView<'world, Parameters>, /// Identifications of discovered trusted peers. pub(crate) trusted_peers_ids: CellView<'world, PeersIds>, @@ -180,13 +174,11 @@ pub struct WorldView<'world> { pub struct State { /// The world. Contains `domains`, `triggers`, `roles` and other data representing the current state of the blockchain. pub world: World, - /// Configuration of World State View. - pub config: Cell, /// Blockchain. // TODO: Cell is redundant here since block_hashes is very easy to rollback by just popping the last element pub block_hashes: Cell>>, /// Hashes of transactions mapped onto block height where they stored - pub transactions: Storage, usize>, + pub transactions: Storage, NonZeroUsize>, /// Engine for WASM [`Runtime`](wasm::Runtime) to execute triggers. #[serde(skip)] pub engine: wasmtime::Engine, @@ -207,12 +199,10 @@ pub struct State { pub struct StateBlock<'state> { /// The world. Contains `domains`, `triggers`, `roles` and other data representing the current state of the blockchain. pub world: WorldBlock<'state>, - /// Configuration of World State View. - pub config: CellBlock<'state, Config>, /// Blockchain. pub block_hashes: CellBlock<'state, Vec>>, /// Hashes of transactions mapped onto block height where they stored - pub transactions: StorageBlock<'state, HashOf, usize>, + pub transactions: StorageBlock<'state, HashOf, NonZeroUsize>, /// Engine for WASM [`Runtime`](wasm::Runtime) to execute triggers. pub engine: &'state wasmtime::Engine, @@ -229,12 +219,10 @@ pub struct StateBlock<'state> { pub struct StateTransaction<'block, 'state> { /// The world. Contains `domains`, `triggers`, `roles` and other data representing the current state of the blockchain. pub world: WorldTransaction<'block, 'state>, - /// Configuration of World State View. - pub config: CellTransaction<'block, 'state, Config>, /// Blockchain. pub block_hashes: CellTransaction<'block, 'state, Vec>>, /// Hashes of transactions mapped onto block height where they stored - pub transactions: StorageTransaction<'block, 'state, HashOf, usize>, + pub transactions: StorageTransaction<'block, 'state, HashOf, NonZeroUsize>, /// Engine for WASM [`Runtime`](wasm::Runtime) to execute triggers. pub engine: &'state wasmtime::Engine, @@ -251,12 +239,10 @@ pub struct StateTransaction<'block, 'state> { pub struct StateView<'state> { /// The world. Contains `domains`, `triggers`, `roles` and other data representing the current state of the blockchain. pub world: WorldView<'state>, - /// Configuration of World State View. - pub config: CellView<'state, Config>, /// Blockchain. pub block_hashes: CellView<'state, Vec>>, /// Hashes of transactions mapped onto block height where they stored - pub transactions: StorageView<'state, HashOf, usize>, + pub transactions: StorageView<'state, HashOf, NonZeroUsize>, /// Engine for WASM [`Runtime`](wasm::Runtime) to execute triggers. pub engine: &'state wasmtime::Engine, @@ -289,11 +275,11 @@ impl World { .into_iter() .map(|account| (account.id().clone(), account)) .collect(); - World { + Self { trusted_peers_ids: Cell::new(trusted_peers_ids), domains, accounts, - ..World::new() + ..Self::new() } } @@ -331,7 +317,7 @@ impl World { } } - /// Create point in time view of the [`World`] + /// Create point in time view of the [`Self`] pub fn view(&self) -> WorldView { WorldView { parameters: self.parameters.view(), @@ -573,26 +559,6 @@ pub trait WorldReadOnly { self.trusted_peers_ids().iter() } - /// Get all `Parameter`s registered in the world. - fn parameters_iter(&self) -> impl Iterator { - self.parameters().iter() - } - - /// Query parameter and convert it to a proper type - fn query_param, P: core::hash::Hash + Eq + ?Sized>( - &self, - param: &P, - ) -> Option - where - Parameter: Borrow

, - { - Parameters::get(self.parameters(), param) - .as_ref() - .map(|param| ¶m.val) - .cloned() - .and_then(|param_val| param_val.try_into().ok()) - } - /// Returns reference for trusted peer ids #[inline] fn peers_ids(&self) -> &PeersIds { @@ -796,7 +762,7 @@ impl WorldTransaction<'_, '_> { Self::emit_events_impl( &mut self.triggers, &mut self.events_buffer, - Some(AccountEvent::Asset(AssetEvent::Created(asset.clone()))), + Some(AccountEvent::Asset(AssetEvent::Create(asset.clone()))), ); asset })) @@ -841,7 +807,7 @@ impl WorldTransaction<'_, '_> { self.emit_events({ Some(DomainEvent::AssetDefinition( - AssetDefinitionEvent::TotalQuantityChanged(AssetDefinitionTotalQuantityChanged { + AssetDefinitionEvent::TotalQuantityChange(AssetDefinitionTotalQuantityChanged { asset_definition: definition_id.clone(), total_amount: asset_total_amount, }), @@ -874,7 +840,7 @@ impl WorldTransaction<'_, '_> { self.emit_events({ Some(DomainEvent::AssetDefinition( - AssetDefinitionEvent::TotalQuantityChanged(AssetDefinitionTotalQuantityChanged { + AssetDefinitionEvent::TotalQuantityChange(AssetDefinitionTotalQuantityChanged { asset_definition: definition_id.clone(), total_amount: asset_total_amount, }), @@ -960,26 +926,25 @@ impl Drop for TransactionEventBuffer<'_> { } } +impl StateBlock<'_> { + pub(crate) fn consensus_estimation(&self) -> Duration { + let Parameters { + block_time, + commit_time, + .. + } = self.world.parameters(); + + *block_time + (*commit_time / 2) + } +} + impl State { /// Construct [`State`] with given [`World`]. #[must_use] #[inline] pub fn new(world: World, kura: Arc, query_handle: LiveQueryStoreHandle) -> Self { - // Added to remain backward compatible with other code primary in tests - Self::from_config(Config::default(), world, kura, query_handle) - } - - /// Construct [`State`] with specific [`Configuration`]. - #[inline] - pub fn from_config( - config: Config, - world: World, - kura: Arc, - query_handle: LiveQueryStoreHandle, - ) -> Self { Self { world, - config: Cell::new(config), transactions: Storage::new(), block_hashes: Cell::new(Vec::new()), new_tx_amounts: Arc::new(Mutex::new(Vec::new())), @@ -993,7 +958,6 @@ impl State { pub fn block(&self) -> StateBlock<'_> { StateBlock { world: self.world.block(), - config: self.config.block(), block_hashes: self.block_hashes.block(), transactions: self.transactions.block(), engine: &self.engine, @@ -1007,7 +971,6 @@ impl State { pub fn block_and_revert(&self) -> StateBlock<'_> { StateBlock { world: self.world.block_and_revert(), - config: self.config.block_and_revert(), block_hashes: self.block_hashes.block_and_revert(), transactions: self.transactions.block_and_revert(), engine: &self.engine, @@ -1021,7 +984,6 @@ impl State { pub fn view(&self) -> StateView<'_> { StateView { world: self.world.view(), - config: self.config.view(), block_hashes: self.block_hashes.view(), transactions: self.transactions.view(), engine: &self.engine, @@ -1036,9 +998,8 @@ impl State { #[allow(missing_docs)] pub trait StateReadOnly { fn world(&self) -> &impl WorldReadOnly; - fn config(&self) -> &Config; fn block_hashes(&self) -> &[HashOf]; - fn transactions(&self) -> &impl StorageReadOnly, usize>; + fn transactions(&self) -> &impl StorageReadOnly, NonZeroUsize>; fn engine(&self) -> &wasmtime::Engine; fn kura(&self) -> &Kura; fn query_handle(&self) -> &LiveQueryStoreHandle; @@ -1108,8 +1069,7 @@ pub trait StateReadOnly { fn block_with_tx(&self, hash: &HashOf) -> Option> { self.transactions() .get(hash) - .and_then(|&height| NonZeroUsize::new(height)) - .and_then(|height| self.kura().get_block_by_height(height)) + .and_then(|&height| self.kura().get_block_by_height(height)) } /// Returns [`Some`] milliseconds since the genesis block was @@ -1140,7 +1100,7 @@ pub trait StateReadOnly { /// Get transaction executor fn transaction_executor(&self) -> TransactionExecutor { - TransactionExecutor::new(self.config().transaction_limits) + TransactionExecutor::new(self.world().parameters().transaction_limits) } } @@ -1150,13 +1110,10 @@ macro_rules! impl_state_ro { fn world(&self) -> &impl WorldReadOnly { &self.world } - fn config(&self) -> &Config { - &self.config - } fn block_hashes(&self) -> &[HashOf] { &self.block_hashes } - fn transactions(&self) -> &impl StorageReadOnly, usize> { + fn transactions(&self) -> &impl StorageReadOnly, NonZeroUsize> { &self.transactions } fn engine(&self) -> &wasmtime::Engine { @@ -1184,7 +1141,6 @@ impl<'state> StateBlock<'state> { pub fn transaction(&mut self) -> StateTransaction<'_, 'state> { StateTransaction { world: self.world.trasaction(), - config: self.config.transaction(), block_hashes: self.block_hashes.transaction(), transactions: self.transactions.transaction(), engine: self.engine, @@ -1198,7 +1154,6 @@ impl<'state> StateBlock<'state> { pub fn commit(self) { self.transactions.commit(); self.block_hashes.commit(); - self.config.commit(); self.world.commit(); } @@ -1374,101 +1329,9 @@ impl StateTransaction<'_, '_> { pub fn apply(self) { self.transactions.apply(); self.block_hashes.apply(); - self.config.apply(); self.world.apply(); } - /// If given [`Parameter`] represents some of the core chain-wide - /// parameters ([`Config`]), apply it - pub fn try_apply_core_parameter(&mut self, parameter: Parameter) { - use iroha_data_model::parameter::default::*; - - struct Reader(Option); - - impl Reader { - fn try_and_then>( - self, - id: &str, - fun: impl FnOnce(T), - ) -> Self { - if let Some(param) = self.0 { - if param.id().name().as_ref() == id { - if let Ok(value) = param.val.try_into() { - fun(value); - } - Self(None) - } else { - Self(Some(param)) - } - } else { - Self(None) - } - } - - fn try_and_write>( - self, - id: &str, - destination: &mut T, - ) -> Self { - self.try_and_then(id, |value| { - *destination = value; - }) - } - - fn try_and_write_duration(self, id: &str, destination: &mut Duration) -> Self { - self.try_and_then(id, |value| *destination = Duration::from_millis(value)) - } - - fn try_and_write_bytes(self, id: &str, destination: &mut Bytes) -> Self { - self.try_and_then(id, |value| *destination = Bytes(value)) - } - } - - Reader(Some(parameter)) - .try_and_then(MAX_TRANSACTIONS_IN_BLOCK, |value| { - if let Some(checked) = NonZeroU32::new(value) { - self.config.max_transactions_in_block = checked; - } - }) - .try_and_write_duration(BLOCK_TIME, &mut self.config.block_time) - .try_and_write_duration(COMMIT_TIME_LIMIT, &mut self.config.commit_time) - .try_and_write( - WSV_DOMAIN_METADATA_LIMITS, - &mut self.config.domain_metadata_limits, - ) - .try_and_write( - WSV_ASSET_DEFINITION_METADATA_LIMITS, - &mut self.config.asset_definition_metadata_limits, - ) - .try_and_write( - WSV_ACCOUNT_METADATA_LIMITS, - &mut self.config.account_metadata_limits, - ) - .try_and_write( - WSV_ASSET_METADATA_LIMITS, - &mut self.config.asset_metadata_limits, - ) - .try_and_write( - WSV_TRIGGER_METADATA_LIMITS, - &mut self.config.trigger_metadata_limits, - ) - .try_and_write( - WSV_IDENT_LENGTH_LIMITS, - &mut self.config.ident_length_limits, - ) - .try_and_write( - EXECUTOR_FUEL_LIMIT, - &mut self.config.executor_runtime.fuel_limit, - ) - .try_and_write_bytes( - EXECUTOR_MAX_MEMORY, - &mut self.config.executor_runtime.max_memory, - ) - .try_and_write(WASM_FUEL_LIMIT, &mut self.config.wasm_runtime.fuel_limit) - .try_and_write_bytes(WASM_MAX_MEMORY, &mut self.config.wasm_runtime.max_memory) - .try_and_write(TRANSACTION_LIMITS, &mut self.config.transaction_limits); - } - fn process_executable(&mut self, executable: &Executable, authority: AccountId) -> Result<()> { match executable { Executable::Instructions(instructions) => { @@ -1476,7 +1339,7 @@ impl StateTransaction<'_, '_> { } Executable::Wasm(bytes) => { let mut wasm_runtime = wasm::RuntimeBuilder::::new() - .with_config(self.config.wasm_runtime) + .with_config(self.world().parameters().smart_contract_limits) .with_engine(self.engine.clone()) // Cloning engine is cheap .build()?; wasm_runtime @@ -1518,7 +1381,7 @@ impl StateTransaction<'_, '_> { .expect("INTERNAL BUG: contract is not present") .clone(); let mut wasm_runtime = wasm::RuntimeBuilder::::new() - .with_config(self.config.wasm_runtime) + .with_config(self.world().parameters().smart_contract_limits) .with_engine(self.engine.clone()) // Cloning engine is cheap .build()?; wasm_runtime @@ -1875,7 +1738,6 @@ pub(crate) mod deserialize { M: MapAccess<'de>, { let mut world = None; - let mut config = None; let mut block_hashes = None; let mut transactions = None; @@ -1891,9 +1753,6 @@ pub(crate) mod deserialize { "world" => { world = Some(map.next_value_seed(wasm_seed.cast::())?); } - "config" => { - config = Some(map.next_value()?); - } "block_hashes" => { block_hashes = Some(map.next_value()?); } @@ -1906,7 +1765,6 @@ pub(crate) mod deserialize { Ok(State { world: world.ok_or_else(|| serde::de::Error::missing_field("world"))?, - config: config.ok_or_else(|| serde::de::Error::missing_field("config"))?, block_hashes: block_hashes .ok_or_else(|| serde::de::Error::missing_field("block_hashes"))?, transactions: transactions @@ -1921,7 +1779,7 @@ pub(crate) mod deserialize { deserializer.deserialize_struct( "WorldState", - &["world", "config", "block_hashes", "transactions"], + &["world", "block_hashes", "transactions"], StateVisitor { loader: self }, ) } @@ -1930,6 +1788,8 @@ pub(crate) mod deserialize { #[cfg(test)] mod tests { + use core::num::NonZeroU64; + use iroha_data_model::block::BlockPayload; use test_samples::gen_account_in; @@ -1963,7 +1823,7 @@ mod tests { let mut block_hashes = vec![]; for i in 1..=BLOCK_CNT { let block = new_dummy_block_with_payload(|payload| { - payload.header.height = i as u64; + payload.header.height = NonZeroU64::new(i as u64).unwrap(); payload.header.prev_block_hash = block_hashes.last().copied(); }); @@ -1988,7 +1848,7 @@ mod tests { for i in 1..=BLOCK_CNT { let block = new_dummy_block_with_payload(|payload| { - payload.header.height = i as u64; + payload.header.height = NonZeroU64::new(i as u64).unwrap(); }); let _events = state_block.apply(&block).unwrap(); @@ -1999,7 +1859,7 @@ mod tests { &state_block .all_blocks() .skip(7) - .map(|block| block.header().height()) + .map(|block| block.header().height().get()) .collect::>(), &[8, 9, 10] ); diff --git a/core/src/sumeragi/main_loop.rs b/core/src/sumeragi/main_loop.rs index 861bb556f66..de0eebbba22 100644 --- a/core/src/sumeragi/main_loop.rs +++ b/core/src/sumeragi/main_loop.rs @@ -2,7 +2,9 @@ use std::{collections::BTreeSet, sync::mpsc}; use iroha_crypto::{HashOf, KeyPair}; -use iroha_data_model::{block::*, events::pipeline::PipelineEventBox, peer::PeerId}; +use iroha_data_model::{ + block::*, events::pipeline::PipelineEventBox, param::Parameters, peer::PeerId, +}; use iroha_p2p::UpdateTopology; use tracing::{span, Level}; @@ -21,14 +23,6 @@ pub struct Sumeragi { pub peer_id: PeerId, /// An actor that sends events pub events_sender: EventsSender, - /// Time by which a newly created block should be committed. Prevents malicious nodes - /// from stalling the network by not participating in consensus - pub commit_time: Duration, - /// Time by which a new block should be created regardless if there were enough transactions or not. - /// Used to force block commits when there is a small influx of new transactions. - pub block_time: Duration, - /// The maximum number of transactions in the block - pub max_txs_in_block: usize, /// Kura instance used for IO pub kura: Arc, /// [`iroha_p2p::Network`] actor address @@ -69,6 +63,10 @@ impl Debug for Sumeragi { } impl Sumeragi { + fn pipeline_time(parameters: &Parameters) -> Duration { + parameters.block_time + parameters.commit_time + } + fn role(&self) -> Role { self.topology.role(&self.peer_id) } @@ -122,12 +120,6 @@ impl Sumeragi { self.network.update_topology(UpdateTopology(peers)); } - /// The maximum time a sumeragi round can take to produce a block when - /// there are no faulty peers in the a set. - fn pipeline_time(&self) -> Duration { - self.block_time + self.commit_time - } - fn send_event(&self, event: impl Into) { let _ = self.events_sender.send(event.into()); } @@ -345,8 +337,6 @@ impl Sumeragi { let state_events = state_block.apply_without_execution(&block); - // Parameters are updated before updating public copy of sumeragi - self.update_params(&state_block); self.cache_transaction(&state_block); self.topology @@ -383,12 +373,6 @@ impl Sumeragi { self.was_commit = true; } - fn update_params(&mut self, state_block: &StateBlock<'_>) { - self.block_time = state_block.config.block_time; - self.commit_time = state_block.config.commit_time; - self.max_txs_in_block = state_block.config.max_transactions_in_block.get() as usize; - } - fn cache_transaction(&mut self, state_block: &StateBlock<'_>) { self.transaction_cache.retain(|tx| { !state_block.has_transaction(tx.as_ref().hash()) && !self.queue.is_expired(tx) @@ -807,7 +791,9 @@ impl Sumeragi { #[cfg(debug_assertions)] if is_genesis_peer && self.debug_force_soft_fork { - std::thread::sleep(self.pipeline_time() * 2); + std::thread::sleep( + Sumeragi::pipeline_time(voting_block.state_block.world.parameters()) * 2, + ); } else { let msg = BlockCommitted::from(&committed_block); self.broadcast_packet(msg); @@ -835,8 +821,17 @@ impl Sumeragi { ) { assert_eq!(self.role(), Role::Leader); - let tx_cache_full = self.transaction_cache.len() >= self.max_txs_in_block; - let deadline_reached = self.round_start_time.elapsed() > self.block_time; + let max_transactions: NonZeroUsize = state + .world + .view() + .parameters + .block_limits + .max_transactions + .try_into() + .expect("INTERNAL BUG: transactions in block exceed usize::MAX"); + let block_time = state.world.view().parameters.block_time; + let tx_cache_full = self.transaction_cache.len() >= max_transactions.get(); + let deadline_reached = self.round_start_time.elapsed() > block_time; let tx_cache_non_empty = !self.transaction_cache.is_empty(); if tx_cache_full || (deadline_reached && tx_cache_non_empty) { @@ -853,7 +848,7 @@ impl Sumeragi { .unpack(|e| self.send_event(e)); let created_in = create_block_start_time.elapsed(); - if created_in > self.pipeline_time() / 2 { + if created_in > Sumeragi::pipeline_time(state.world.view().parameters()) / 2 { warn!( role=%self.role(), peer_id=%self.peer_id, @@ -999,7 +994,7 @@ pub(crate) fn run( let mut should_sleep = false; let mut view_change_proof_chain = ProofChain::default(); // Duration after which a view change is suggested - let mut view_change_time = sumeragi.pipeline_time(); + let mut view_change_time = Sumeragi::pipeline_time(state.world.view().parameters()); // Instant when the previous view change or round happened. let mut last_view_change_time = Instant::now(); @@ -1029,7 +1024,14 @@ pub(crate) fn run( sumeragi.queue.get_transactions_for_block( &state_view, - sumeragi.max_txs_in_block, + state + .world + .view() + .parameters + .block_limits + .max_transactions + .try_into() + .expect("INTERNAL BUG: transactions in block exceed usize::MAX"), &mut sumeragi.transaction_cache, ); @@ -1042,7 +1044,7 @@ pub(crate) fn run( reset_state( &sumeragi.peer_id, - sumeragi.pipeline_time(), + Sumeragi::pipeline_time(state.world.view().parameters()), view_change_index, &mut sumeragi.was_commit, &mut sumeragi.topology, @@ -1127,12 +1129,12 @@ pub(crate) fn run( // NOTE: View change must be periodically suggested until it is accepted. // Must be initialized to pipeline time but can increase by chosen amount - view_change_time += sumeragi.pipeline_time(); + view_change_time += Sumeragi::pipeline_time(state.world.view().parameters()); } reset_state( &sumeragi.peer_id, - sumeragi.pipeline_time(), + Sumeragi::pipeline_time(state.world.view().parameters()), view_change_index, &mut sumeragi.was_commit, &mut sumeragi.topology, @@ -1224,7 +1226,7 @@ enum BlockSyncError { }, BlockNotProperHeight { peer_height: usize, - block_height: usize, + block_height: NonZeroUsize, }, } @@ -1235,18 +1237,18 @@ fn handle_block_sync<'state, F: Fn(PipelineEventBox)>( genesis_account: &AccountId, handle_events: &F, ) -> Result, (SignedBlock, BlockSyncError)> { - let block_height = block + let block_height: NonZeroUsize = block .header() .height .try_into() .expect("INTERNAL BUG: Block height exceeds usize::MAX"); let state_height = state.view().height(); - let (mut state_block, soft_fork) = if state_height + 1 == block_height { + let (mut state_block, soft_fork) = if state_height + 1 == block_height.get() { // NOTE: Normal branch for adding new block on top of current (state.block(), false) - } else if state_height == block_height && block_height > 1 { + } else if state_height == block_height.get() && block_height.get() > 1 { // NOTE: Soft fork branch for replacing current block with valid one let latest_block = state @@ -1319,6 +1321,7 @@ fn handle_block_sync<'state, F: Fn(PipelineEventBox)>( #[cfg(test)] mod tests { use iroha_genesis::GENESIS_DOMAIN_ID; + use nonzero_ext::nonzero; use test_samples::gen_account_in; use tokio::test; @@ -1500,20 +1503,26 @@ mod tests { // Change block height let block = clone_and_modify_payload(&block, &leader_private_key, |payload| { - payload.header.height = 42; + payload.header.height = nonzero!(42_u64); }); let result = handle_block_sync(&chain_id, block, &state, &genesis_public_key, &|_| {}); + assert!(matches!( result, - Err(( - _, - BlockSyncError::BlockNotProperHeight { - peer_height: 1, - block_height: 42 - } - )) - )) + Err((_, BlockSyncError::BlockNotProperHeight { .. })) + )); + if let Err(( + _, + BlockSyncError::BlockNotProperHeight { + peer_height, + block_height, + }, + )) = result + { + assert_eq!(peer_height, 1); + assert_eq!(block_height, nonzero!(42_usize)); + } } #[test] @@ -1644,19 +1653,25 @@ mod tests { // Soft-fork on genesis block is not possible let block = clone_and_modify_payload(&block, &leader_private_key, |payload| { payload.header.view_change_index = 42; - payload.header.height = 1; + payload.header.height = nonzero!(1_u64); }); let result = handle_block_sync(&chain_id, block, &state, &genesis_public_key, &|_| {}); + assert!(matches!( result, - Err(( - _, - BlockSyncError::BlockNotProperHeight { - peer_height: 1, - block_height: 1, - } - )) - )) + Err((_, BlockSyncError::BlockNotProperHeight { .. })) + )); + if let Err(( + _, + BlockSyncError::BlockNotProperHeight { + peer_height, + block_height, + }, + )) = result + { + assert_eq!(peer_height, 1); + assert_eq!(block_height, nonzero!(1_usize)); + } } } diff --git a/core/src/sumeragi/mod.rs b/core/src/sumeragi/mod.rs index 9763fe7324c..42a7921a617 100644 --- a/core/src/sumeragi/mod.rs +++ b/core/src/sumeragi/mod.rs @@ -211,9 +211,6 @@ impl SumeragiHandle { peer_id: peer_id.clone(), queue: Arc::clone(&queue), events_sender, - commit_time: state.view().config.commit_time, - block_time: state.view().config.block_time, - max_txs_in_block: state.view().config.max_transactions_in_block.get() as usize, kura: Arc::clone(&kura), network: network.clone(), control_message_receiver, diff --git a/core/src/tx.rs b/core/src/tx.rs index 5c7bc266c35..798c006bcf5 100644 --- a/core/src/tx.rs +++ b/core/src/tx.rs @@ -14,7 +14,7 @@ pub use iroha_data_model::prelude::*; use iroha_data_model::{ isi::error::Mismatch, query::error::FindError, - transaction::{error::TransactionLimitError, TransactionLimits, TransactionPayload}, + transaction::{error::TransactionLimitError, TransactionPayload}, }; use iroha_genesis::GenesisTransaction; use iroha_logger::{debug, error}; @@ -114,12 +114,12 @@ impl AcceptedTransaction { match &tx.instructions() { Executable::Instructions(instructions) => { let instruction_count = instructions.len(); - if Self::len_u64(instruction_count) > limits.max_instruction_number { + if Self::len_u64(instruction_count) > limits.max_instructions.get() { return Err(AcceptTransactionFail::TransactionLimit( TransactionLimitError { reason: format!( "Too many instructions in payload, max number is {}, but got {}", - limits.max_instruction_number, instruction_count + limits.max_instructions, instruction_count ), }, )); @@ -130,13 +130,15 @@ impl AcceptedTransaction { // // Should we allow infinite instructions in wasm? And deny only based on fuel and size Executable::Wasm(smart_contract) => { - let size_bytes = Self::len_u64(smart_contract.size_bytes()); - let max_wasm_size_bytes = limits.max_wasm_size_bytes; + let smart_contract_size = Self::len_u64(smart_contract.size_bytes()); - if size_bytes > max_wasm_size_bytes { + if smart_contract_size > limits.smart_contract_size.get() { return Err(AcceptTransactionFail::TransactionLimit( TransactionLimitError { - reason: format!("Wasm binary too large, max size is {max_wasm_size_bytes}, but got {size_bytes}"), + reason: format!( + "Wasm binary too large, max size is {}, but got {}", + limits.smart_contract_size, smart_contract_size + ), }, )); } @@ -245,7 +247,7 @@ impl TransactionExecutor { state_transaction, authority, wasm, - self.transaction_limits.max_instruction_number, + self.transaction_limits.max_instructions, ) }) .map_err(|error| WasmExecutionFail { diff --git a/core/test_network/src/lib.rs b/core/test_network/src/lib.rs index f35df530fe2..0c2dac06854 100644 --- a/core/test_network/src/lib.rs +++ b/core/test_network/src/lib.rs @@ -628,13 +628,9 @@ impl PeerBuilder { /// Create and start a peer, create a client and connect it to the peer and return both. pub async fn start_with_client(self) -> (Peer, Client) { - let config = self.config.clone().unwrap_or_else(Config::test); - let peer = self.start().await; - let client = Client::test(&peer.api_address); - - time::sleep(config.chain_wide.pipeline_time()).await; + time::sleep(::pipeline_time()).await; (peer, client) } @@ -781,7 +777,8 @@ impl TestConfig for Config { } fn pipeline_time() -> Duration { - Self::test().chain_wide.pipeline_time() + let defaults = iroha_data_model::param::Parameters::default(); + defaults.block_time + defaults.commit_time } fn block_sync_gossip_time() -> Duration { diff --git a/data_model/src/account.rs b/data_model/src/account.rs index 0e99bf6d495..6d75fc54358 100644 --- a/data_model/src/account.rs +++ b/data_model/src/account.rs @@ -234,10 +234,10 @@ pub mod prelude { } #[cfg(test)] +#[cfg(feature = "transparent_api")] mod tests { use super::*; - #[cfg(feature = "transparent_api")] #[test] fn parse_account_id() { const SIGNATORY: &str = diff --git a/data_model/src/block.rs b/data_model/src/block.rs index e1f03cea332..e8957749559 100644 --- a/data_model/src/block.rs +++ b/data_model/src/block.rs @@ -22,6 +22,8 @@ use crate::{events::prelude::*, peer, peer::PeerId, transaction::prelude::*}; #[model] mod model { + use core::num::NonZeroU64; + use getset::{CopyGetters, Getters}; use super::*; @@ -52,7 +54,7 @@ mod model { pub struct BlockHeader { /// Number of blocks in the chain including this block. #[getset(get_copy = "pub")] - pub height: u64, + pub height: NonZeroU64, /// Hash of the previous block in the chain. #[getset(get_copy = "pub")] pub prev_block_hash: Option>, @@ -143,7 +145,7 @@ impl BlockHeader { #[inline] #[cfg(feature = "transparent_api")] pub const fn is_genesis(&self) -> bool { - self.height == 1 + self.height.get() == 1 } /// Creation timestamp diff --git a/data_model/src/events/data/events.rs b/data_model/src/events/data/events.rs index 766872cc0d2..efe00d42fae 100644 --- a/data_model/src/events/data/events.rs +++ b/data_model/src/events/data/events.rs @@ -111,16 +111,16 @@ mod asset { #[has_origin(origin = Asset)] pub enum AssetEvent { #[has_origin(asset => asset.id())] - Created(Asset), - Deleted(AssetId), + Create(Asset), + Delete(AssetId), #[has_origin(asset_changed => &asset_changed.asset)] - Added(AssetChanged), + Add(AssetChanged), #[has_origin(asset_changed => &asset_changed.asset)] - Removed(AssetChanged), + Remove(AssetChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(AssetMetadataChanged), + MetadataInsert(AssetMetadataChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(AssetMetadataChanged), + MetadataRemove(AssetMetadataChanged), } } @@ -128,17 +128,17 @@ mod asset { #[has_origin(origin = AssetDefinition)] pub enum AssetDefinitionEvent { #[has_origin(asset_definition => asset_definition.id())] - Created(AssetDefinition), - MintabilityChanged(AssetDefinitionId), - #[has_origin(ownership_changed => &ownership_changed.asset_definition)] - OwnerChanged(AssetDefinitionOwnerChanged), - Deleted(AssetDefinitionId), + Create(AssetDefinition), + Delete(AssetDefinitionId), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(AssetDefinitionMetadataChanged), + MetadataInsert(AssetDefinitionMetadataChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(AssetDefinitionMetadataChanged), + MetadataRemove(AssetDefinitionMetadataChanged), + MintabilityChange(AssetDefinitionId), #[has_origin(total_quantity_changed => &total_quantity_changed.asset_definition)] - TotalQuantityChanged(AssetDefinitionTotalQuantityChanged), + TotalQuantityChange(AssetDefinitionTotalQuantityChanged), + #[has_origin(ownership_changed => &ownership_changed.asset_definition)] + OwnerChange(AssetDefinitionOwnerChanged), } } @@ -224,8 +224,8 @@ mod peer { data_event! { #[has_origin(origin = Peer)] pub enum PeerEvent { - Added(PeerId), - Removed(PeerId), + Add(PeerId), + Remove(PeerId), } } } @@ -242,16 +242,16 @@ mod role { #[has_origin(origin = Role)] pub enum RoleEvent { #[has_origin(role => role.id())] - Created(Role), - Deleted(RoleId), - /// [`Permission`]s with particular [`PermissionId`] - /// were removed from the role. - #[has_origin(permission_removed => &permission_removed.role)] - PermissionRemoved(RolePermissionChanged), + Create(Role), + Delete(RoleId), /// [`Permission`]s with particular [`PermissionId`] /// were removed added to the role. #[has_origin(permission_added => &permission_added.role)] - PermissionAdded(RolePermissionChanged), + PermissionAdd(RolePermissionChanged), + /// [`Permission`]s with particular [`PermissionId`] + /// were removed from the role. + #[has_origin(permission_removed => &permission_removed.role)] + PermissionRemove(RolePermissionChanged), } } @@ -298,25 +298,25 @@ mod account { data_event! { #[has_origin(origin = Account)] pub enum AccountEvent { + #[has_origin(account => account.id())] + Create(Account), + Delete(AccountId), + AuthenticationAdd(AccountId), + AuthenticationRemove(AccountId), #[has_origin(asset_event => &asset_event.origin().account)] Asset(AssetEvent), - #[has_origin(account => account.id())] - Created(Account), - Deleted(AccountId), - AuthenticationAdded(AccountId), - AuthenticationRemoved(AccountId), #[has_origin(permission_changed => &permission_changed.account)] - PermissionAdded(AccountPermissionChanged), + PermissionAdd(AccountPermissionChanged), #[has_origin(permission_changed => &permission_changed.account)] - PermissionRemoved(AccountPermissionChanged), + PermissionRemove(AccountPermissionChanged), #[has_origin(role_changed => &role_changed.account)] - RoleRevoked(AccountRoleChanged), + RoleGrant(AccountRoleChanged), #[has_origin(role_changed => &role_changed.account)] - RoleGranted(AccountRoleChanged), + RoleRevoke(AccountRoleChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(AccountMetadataChanged), + MetadataInsert(AccountMetadataChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(AccountMetadataChanged), + MetadataRemove(AccountMetadataChanged), } } @@ -390,19 +390,19 @@ mod domain { data_event! { #[has_origin(origin = Domain)] pub enum DomainEvent { - #[has_origin(account_event => &account_event.origin().domain)] - Account(AccountEvent), + #[has_origin(domain => domain.id())] + Create(Domain), + Delete(DomainId), #[has_origin(asset_definition_event => &asset_definition_event.origin().domain)] AssetDefinition(AssetDefinitionEvent), - #[has_origin(domain => domain.id())] - Created(Domain), - Deleted(DomainId), + #[has_origin(account_event => &account_event.origin().domain)] + Account(AccountEvent), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(DomainMetadataChanged), + MetadataInsert(DomainMetadataChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(DomainMetadataChanged), + MetadataRemove(DomainMetadataChanged), #[has_origin(owner_changed => &owner_changed.domain)] - OwnerChanged(DomainOwnerChanged), + OwnerChange(DomainOwnerChanged), } } @@ -447,16 +447,16 @@ mod trigger { data_event! { #[has_origin(origin = Trigger)] pub enum TriggerEvent { - Created(TriggerId), - Deleted(TriggerId), + Create(TriggerId), + Delete(TriggerId), #[has_origin(number_of_executions_changed => &number_of_executions_changed.trigger)] - Extended(TriggerNumberOfExecutionsChanged), + Extend(TriggerNumberOfExecutionsChanged), #[has_origin(number_of_executions_changed => &number_of_executions_changed.trigger)] - Shortened(TriggerNumberOfExecutionsChanged), + Shorten(TriggerNumberOfExecutionsChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataInserted(TriggerMetadataChanged), + MetadataInsert(TriggerMetadataChanged), #[has_origin(metadata_changed => &metadata_changed.target)] - MetadataRemoved(TriggerMetadataChanged), + MetadataRemove(TriggerMetadataChanged), } } @@ -489,14 +489,32 @@ mod trigger { } mod config { + pub use self::model::*; use super::*; + use crate::param::Parameter; - data_event! { - #[has_origin(origin = Parameter)] + #[model] + mod model { + use super::*; + + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + EventSet, + FromVariant, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[ffi_type] pub enum ConfigurationEvent { - Changed(ParameterId), - Created(ParameterId), - Deleted(ParameterId), + Change(Parameter), } } } @@ -538,7 +556,7 @@ mod executor { #[serde(untagged)] // Unaffected by #3330, as single unit variant #[repr(transparent)] pub enum ExecutorEvent { - Upgraded(ExecutorUpgrade), + Upgrade(ExecutorUpgrade), } /// Information about the updated executor data model. diff --git a/data_model/src/events/data/filters.rs b/data_model/src/events/data/filters.rs index 86bb1a886f3..88e044873bc 100644 --- a/data_model/src/events/data/filters.rs +++ b/data_model/src/events/data/filters.rs @@ -223,8 +223,6 @@ mod model { IntoSchema, )] pub struct ConfigurationEventFilter { - /// If specified matches only events originating from this configuration - pub(super) id_matcher: Option, /// Matches only event from this set pub(super) event_set: ConfigurationEventSet, } @@ -598,18 +596,10 @@ impl ConfigurationEventFilter { /// Creates a new [`ConfigurationEventFilter`] accepting all [`ConfigurationEvent`]s. pub const fn new() -> Self { Self { - id_matcher: None, event_set: ConfigurationEventSet::all(), } } - /// Modifies a [`ConfigurationEventFilter`] to accept only [`ConfigurationEvent`]s originating from ids matching `id_matcher`. - #[must_use] - pub fn for_parameter(mut self, id_matcher: ParameterId) -> Self { - self.id_matcher = Some(id_matcher); - self - } - /// Modifies a [`ConfigurationEventFilter`] to accept only [`ConfigurationEvent`]s of types matching `event_set`. #[must_use] pub const fn for_events(mut self, event_set: ConfigurationEventSet) -> Self { @@ -629,12 +619,6 @@ impl super::EventFilter for ConfigurationEventFilter { type Event = super::ConfigurationEvent; fn matches(&self, event: &Self::Event) -> bool { - if let Some(id_matcher) = &self.id_matcher { - if id_matcher != event.origin() { - return false; - } - } - if !self.event_set.matches(event) { return false; } @@ -765,10 +749,10 @@ mod tests { // the first one is just a domain event // the second one is an account event with a domain event inside // the third one is an asset event with an account event with a domain event inside - let domain_created = DomainEvent::Created(domain).into(); - let account_created = DomainEvent::Account(AccountEvent::Created(account)).into(); + let domain_created = DomainEvent::Create(domain).into(); + let account_created = DomainEvent::Account(AccountEvent::Create(account)).into(); let asset_created = - DomainEvent::Account(AccountEvent::Asset(AssetEvent::Created(asset))).into(); + DomainEvent::Account(AccountEvent::Asset(AssetEvent::Create(asset))).into(); // test how the differently nested filters with with the events let domain_filter = DataEventFilter::Domain(DomainEventFilter::new().for_domain(domain_id)); diff --git a/data_model/src/events/pipeline.rs b/data_model/src/events/pipeline.rs index 731e194c505..0fa4f02f44c 100644 --- a/data_model/src/events/pipeline.rs +++ b/data_model/src/events/pipeline.rs @@ -2,6 +2,7 @@ #[cfg(not(feature = "std"))] use alloc::{boxed::Box, format, string::String, vec::Vec}; +use core::num::NonZeroU64; use iroha_crypto::HashOf; use iroha_data_model_derive::model; @@ -84,7 +85,7 @@ mod model { #[getset(get = "pub")] pub hash: HashOf, #[getset(get_copy = "pub")] - pub block_height: Option, + pub block_height: Option, #[getset(get = "pub")] pub status: TransactionStatus, } @@ -181,7 +182,7 @@ mod model { #[ffi_type] pub struct BlockEventFilter { #[getset(get_copy = "pub")] - pub height: Option, + pub height: Option, #[getset(get = "pub")] pub status: Option, } @@ -205,7 +206,7 @@ mod model { pub struct TransactionEventFilter { #[getset(get = "pub")] pub hash: Option>, - pub block_height: Option>, + pub block_height: Option>, #[getset(get = "pub")] pub status: Option, } @@ -223,7 +224,7 @@ impl BlockEventFilter { /// Match only block with the given height #[must_use] - pub fn for_height(mut self, height: u64) -> Self { + pub fn for_height(mut self, height: NonZeroU64) -> Self { self.height = Some(height); self } @@ -249,7 +250,7 @@ impl TransactionEventFilter { /// Match only transactions with the given block height #[must_use] - pub fn for_block_height(mut self, block_height: Option) -> Self { + pub fn for_block_height(mut self, block_height: Option) -> Self { self.block_height = Some(block_height); self } @@ -270,7 +271,7 @@ impl TransactionEventFilter { /// Block height // TODO: Derive with getset - pub fn block_height(&self) -> Option> { + pub fn block_height(&self) -> Option> { self.block_height } } @@ -345,12 +346,13 @@ mod tests { use alloc::{string::ToString as _, vec, vec::Vec}; use iroha_crypto::Hash; + use nonzero_ext::nonzero; use super::{super::EventFilter, *}; use crate::{transaction::error::TransactionRejectionReason::*, ValidationFail}; impl BlockHeader { - fn dummy(height: u64) -> Self { + fn dummy(height: NonZeroU64) -> Self { Self { height, prev_block_hash: None, @@ -375,7 +377,7 @@ mod tests { .into(), TransactionEvent { hash: HashOf::from_untyped_unchecked(Hash::prehashed([0_u8; Hash::LENGTH])), - block_height: Some(3), + block_height: Some(nonzero!(3_u64)), status: TransactionStatus::Rejected(Box::new(Validation( ValidationFail::TooComplex, ))), @@ -388,7 +390,7 @@ mod tests { } .into(), BlockEvent { - header: BlockHeader::dummy(7), + header: BlockHeader::dummy(nonzero!(7_u64)), hash: HashOf::from_untyped_unchecked(Hash::prehashed([7_u8; Hash::LENGTH])), status: BlockStatus::Committed, } @@ -418,7 +420,7 @@ mod tests { .into(), TransactionEvent { hash: HashOf::from_untyped_unchecked(Hash::prehashed([0_u8; Hash::LENGTH])), - block_height: Some(3), + block_height: Some(nonzero!(3_u64)), status: TransactionStatus::Rejected(Box::new(Validation( ValidationFail::TooComplex, ))), @@ -439,7 +441,7 @@ mod tests { vec![BlockEvent { status: BlockStatus::Committed, hash: HashOf::from_untyped_unchecked(Hash::prehashed([7_u8; Hash::LENGTH])), - header: BlockHeader::dummy(7), + header: BlockHeader::dummy(nonzero!(7_u64)), } .into()], ); diff --git a/data_model/src/executor.rs b/data_model/src/executor.rs index 4e030b1c3b6..8836c40219e 100644 --- a/data_model/src/executor.rs +++ b/data_model/src/executor.rs @@ -83,13 +83,9 @@ mod model { /// /// These IDs refer to the types in the schema. pub permissions: BTreeSet, - /// Type id in the schema. - /// Corresponds to payload of `InstructionBox::Custom`. + /// Corresponds to the id of [`InstructionBox::Custom`]. /// - /// Note that technically it is not needed - /// (custom instructions can be used without specifying it), - /// however it is recommended to set it, - /// so clients could retrieve it through Iroha API. + /// It is recommended to set it, so clients can retrieve it through Iroha API. pub custom_instruction: Option, /// Data model JSON schema, typically produced by [`IntoSchema`]. pub schema: JsonString, diff --git a/data_model/src/isi.rs b/data_model/src/isi.rs index c7024cb8d2f..dd6f5a7ea6a 100644 --- a/data_model/src/isi.rs +++ b/data_model/src/isi.rs @@ -59,7 +59,7 @@ mod model { )] #[enum_ref(derive(Encode, FromVariant))] #[strum_discriminants( - name(InstructionType), + name(InstructionId), derive( Display, PartialOrd, @@ -111,8 +111,6 @@ mod model { #[debug(fmt = "{_0:?}")] SetParameter(SetParameter), #[debug(fmt = "{_0:?}")] - NewParameter(NewParameter), - #[debug(fmt = "{_0:?}")] Upgrade(Upgrade), #[debug(fmt = "{_0:?}")] Log(Log), @@ -174,7 +172,6 @@ impl_instruction! { Revoke, Revoke, SetParameter, - NewParameter, Upgrade, ExecuteTrigger, Log, @@ -248,31 +245,16 @@ mod transparent { }; } - isi! { - /// Generic instruction for setting a chain-wide config parameter. - #[derive(Constructor, Display)] - #[display(fmt = "SET `{parameter}`")] - #[serde(transparent)] - #[repr(transparent)] - pub struct SetParameter { - /// The configuration parameter being changed. - #[serde(flatten)] - pub parameter: Parameter, - } - } - - isi! { - /// Sized structure for all possible on-chain configuration parameters when they are first created. + iroha_data_model_derive::model_single! { /// Generic instruction for setting a chain-wide config parameter. - #[derive(Constructor, Display)] - #[display(fmt = "SET `{parameter}`")] + #[derive(Debug, Display, Clone, PartialEq, Eq, PartialOrd, Ord, Constructor)] + #[derive(parity_scale_codec::Decode, parity_scale_codec::Encode)] + #[derive(serde::Deserialize, serde::Serialize)] + #[derive(iroha_schema::IntoSchema)] + #[display(fmt = "SET `{_0}`")] #[serde(transparent)] #[repr(transparent)] - pub struct NewParameter { - /// Parameter to be changed. - #[serde(flatten)] - pub parameter: Parameter, - } + pub struct SetParameter(pub Parameter); } isi! { @@ -786,7 +768,7 @@ mod transparent { pub fn asset_store(asset_id: AssetId, to: AccountId) -> Self { Self { source: asset_id, - object: Metadata::new(), + object: Metadata::default(), destination: to, } } @@ -994,14 +976,16 @@ mod transparent { } isi! { - /// Custom instruction with arbitrary payload. - /// Should be handled in custom executor, where it will be translated to usual ISIs. + /// Blockchain specific instruction (defined in the executor). /// Can be used to extend instruction set or add expression system. - /// See `executor_custom_instructions_simple` and `executor_custom_instructions_complex` - /// examples in `client/tests/integration/smartcontracts`. /// - /// Note: If using custom instructions, it is recommended - /// to set `ExecutorDataModel::custom_instruction` in custom executor `migrate` entrypoint. + /// Note: If using custom instructions remember to set (during the executor migration) + /// [`ExecutorDataModel::custom_instruction`] + /// + /// # Examples + /// + /// Check `executor_custom_instructions_simple` and `executor_custom_instructions_complex` + /// integration tests #[derive(Display)] #[display(fmt = "CUSTOM({payload})")] pub struct Custom { @@ -1248,10 +1232,9 @@ pub mod error { use parity_scale_codec::{Decode, Encode}; pub use self::model::*; - use super::InstructionType; + use super::InstructionId; use crate::{ asset::AssetValueType, - metadata, query::error::{FindError, QueryExecutionFail}, IdBox, }; @@ -1301,8 +1284,6 @@ pub mod error { Mintability(#[cfg_attr(feature = "std", source)] MintabilityError), /// Illegal math operation Math(#[cfg_attr(feature = "std", source)] MathError), - /// Metadata error - Metadata(#[cfg_attr(feature = "std", source)] metadata::MetadataError), /// Execution failed: {0} Fail( #[skip_from] @@ -1342,7 +1323,7 @@ pub mod error { #[ffi_type(opaque)] pub enum InstructionEvaluationError { /// Unsupported parameter type for instruction of type `{0}` - Unsupported(InstructionType), + Unsupported(InstructionId), /// Failed to find parameter in a permission: {0} PermissionParameter(String), /// Incorrect value type @@ -1523,7 +1504,7 @@ pub mod error { #[ffi_type] pub struct RepetitionError { /// Instruction type - pub instruction_type: InstructionType, + pub instruction_type: InstructionId, /// Id of the object being repeated pub id: IdBox, } @@ -1540,7 +1521,7 @@ pub mod error { pub mod prelude { pub use super::{ AssetTransferBox, Burn, BurnBox, Custom, ExecuteTrigger, Fail, Grant, GrantBox, - InstructionBox, Log, Mint, MintBox, NewParameter, Register, RegisterBox, RemoveKeyValue, + InstructionBox, Log, Mint, MintBox, Register, RegisterBox, RemoveKeyValue, RemoveKeyValueBox, Revoke, RevokeBox, SetKeyValue, SetKeyValueBox, SetParameter, Transfer, TransferBox, Unregister, UnregisterBox, Upgrade, }; diff --git a/data_model/src/lib.rs b/data_model/src/lib.rs index aecffef2df4..829f82d679a 100644 --- a/data_model/src/lib.rs +++ b/data_model/src/lib.rs @@ -15,19 +15,18 @@ use alloc::{ string::{String, ToString}, vec::Vec, }; -use core::{fmt, fmt::Debug, ops::RangeInclusive, str::FromStr}; +use core::{fmt, fmt::Debug, str::FromStr}; -use derive_more::{Constructor, Display, From, FromStr}; +use derive_more::{Constructor, Display, FromStr}; use getset::Getters; use iroha_crypto::PublicKey; -use iroha_data_model_derive::{model, EnumRef, IdEqOrdHash}; +use iroha_data_model_derive::{model, EnumRef}; use iroha_macro::FromVariant; use iroha_schema::IntoSchema; use iroha_version::{declare_versioned, version_with_scale}; use parity_scale_codec::{Decode, Encode}; use prelude::Executable; use serde::{Deserialize, Serialize}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use strum::FromRepr; pub use self::model::*; @@ -43,6 +42,7 @@ pub mod ipfs; pub mod isi; pub mod metadata; pub mod name; +pub mod param; pub mod peer; pub mod permission; pub mod query; @@ -117,7 +117,6 @@ mod seal { Revoke, SetParameter, - NewParameter, Upgrade, ExecuteTrigger, Log, @@ -213,409 +212,6 @@ impl EnumTryAsError { #[cfg(feature = "std")] impl std::error::Error for EnumTryAsError {} -pub mod parameter { - //! Structures, traits and impls related to `Paramater`s. - - use core::borrow::Borrow; - - use iroha_primitives::numeric::Numeric; - - pub use self::model::*; - use super::*; - use crate::isi::InstructionBox; - - /// Set of parameter names currently used by Iroha - #[allow(missing_docs)] - pub mod default { - pub const MAX_TRANSACTIONS_IN_BLOCK: &str = "MaxTransactionsInBlock"; - pub const BLOCK_TIME: &str = "BlockTime"; - pub const COMMIT_TIME_LIMIT: &str = "CommitTimeLimit"; - pub const TRANSACTION_LIMITS: &str = "TransactionLimits"; - pub const WSV_DOMAIN_METADATA_LIMITS: &str = "WSVDomainMetadataLimits"; - pub const WSV_ASSET_DEFINITION_METADATA_LIMITS: &str = "WSVAssetDefinitionMetadataLimits"; - pub const WSV_ACCOUNT_METADATA_LIMITS: &str = "WSVAccountMetadataLimits"; - pub const WSV_ASSET_METADATA_LIMITS: &str = "WSVAssetMetadataLimits"; - pub const WSV_TRIGGER_METADATA_LIMITS: &str = "WSVTriggerMetadataLimits"; - pub const WSV_IDENT_LENGTH_LIMITS: &str = "WSVIdentLengthLimits"; - pub const EXECUTOR_FUEL_LIMIT: &str = "ExecutorFuelLimit"; - pub const EXECUTOR_MAX_MEMORY: &str = "ExecutorMaxMemory"; - pub const WASM_FUEL_LIMIT: &str = "WASMFuelLimit"; - pub const WASM_MAX_MEMORY: &str = "WASMMaxMemory"; - } - - #[model] - mod model { - use super::*; - - #[derive( - Debug, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - FromVariant, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[ffi_type(local)] - pub enum ParameterValueBox { - TransactionLimits(transaction::TransactionLimits), - MetadataLimits(metadata::Limits), - LengthLimits(LengthLimits), - Numeric( - #[skip_from] - #[skip_try_from] - Numeric, - ), - } - - /// Identification of a [`Parameter`]. - #[derive( - Debug, - Display, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Getters, - FromStr, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[display(fmt = "{name}")] - #[getset(get = "pub")] - #[serde(transparent)] - #[repr(transparent)] - #[ffi_type(opaque)] - pub struct ParameterId { - /// [`Name`] unique to a [`Parameter`]. - pub name: Name, - } - - #[derive( - Debug, - Display, - Clone, - Constructor, - IdEqOrdHash, - Decode, - Encode, - DeserializeFromStr, - SerializeDisplay, - IntoSchema, - )] - #[display(fmt = "?{id}={val}")] - /// A chain-wide configuration parameter and its value. - #[ffi_type] - pub struct Parameter { - /// Unique [`Id`] of the [`Parameter`]. - pub id: ParameterId, - /// Current value of the [`Parameter`]. - pub val: ParameterValueBox, - } - } - - // TODO: Maybe derive - impl core::fmt::Display for ParameterValueBox { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::MetadataLimits(v) => core::fmt::Display::fmt(&v, f), - Self::TransactionLimits(v) => core::fmt::Display::fmt(&v, f), - Self::LengthLimits(v) => core::fmt::Display::fmt(&v, f), - Self::Numeric(v) => core::fmt::Display::fmt(&v, f), - } - } - } - - impl> From for ParameterValueBox { - fn from(value: T) -> Self { - Self::Numeric(value.into()) - } - } - - impl TryFrom for u32 { - type Error = iroha_macro::error::ErrorTryFromEnum; - - fn try_from(value: ParameterValueBox) -> Result { - use iroha_macro::error::ErrorTryFromEnum; - - let ParameterValueBox::Numeric(numeric) = value else { - return Err(ErrorTryFromEnum::default()); - }; - - numeric.try_into().map_err(|_| ErrorTryFromEnum::default()) - } - } - - impl TryFrom for u64 { - type Error = iroha_macro::error::ErrorTryFromEnum; - - fn try_from(value: ParameterValueBox) -> Result { - use iroha_macro::error::ErrorTryFromEnum; - - let ParameterValueBox::Numeric(numeric) = value else { - return Err(ErrorTryFromEnum::default()); - }; - - numeric.try_into().map_err(|_| ErrorTryFromEnum::default()) - } - } - - impl Parameter { - /// Current value of the [`Parameter`]. - pub fn val(&self) -> &ParameterValueBox { - &self.val - } - } - - impl Borrow for ParameterId { - fn borrow(&self) -> &str { - self.name.borrow() - } - } - - impl Borrow for Parameter { - fn borrow(&self) -> &str { - self.id.borrow() - } - } - - impl FromStr for Parameter { - type Err = ParseError; - - fn from_str(string: &str) -> Result { - if let Some((parameter_id_candidate, val_candidate)) = string.rsplit_once('=') { - if let Some(parameter_id_candidate) = parameter_id_candidate.strip_prefix('?') { - let param_id: ParameterId = - parameter_id_candidate.parse().map_err(|_| ParseError { - reason: "Failed to parse the `param_id` part of the `Parameter`.", - })?; - if let Some((val, ty)) = val_candidate.rsplit_once('_') { - let val = match ty { - // Shorthand for `LengthLimits` - "LL" => { - let (lower, upper) = val.rsplit_once(',').ok_or( ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `LengthLimits`. Two comma-separated values are expected.", - })?; - let lower = lower.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `LengthLimits`. Invalid lower `u32` bound.", - })?; - let upper = upper.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `LengthLimits`. Invalid upper `u32` bound.", - })?; - LengthLimits::new(lower, upper).into() - } - // Shorthand for `TransactionLimits` - "TL" => { - let (max_instr, max_wasm_size) = val.rsplit_once(',').ok_or( ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `TransactionLimits`. Two comma-separated values are expected.", - })?; - let max_instr = max_instr.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `TransactionLimits`. `max_instruction_number` field should be a valid `u64`.", - })?; - let max_wasm_size = max_wasm_size.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `TransactionLimits`. `max_wasm_size_bytes` field should be a valid `u64`.", - })?; - transaction::TransactionLimits::new( - max_instr, - max_wasm_size, - ).into() - } - // Shorthand for `MetadataLimits` - "ML" => { - let (lower, upper) = val.rsplit_once(',').ok_or( ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `MetadataLimits`. Two comma-separated values are expected.", - })?; - let lower = lower.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `MetadataLimits`. Invalid `u32` in `capacity` field.", - })?; - let upper = upper.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `MetadataLimits`. Invalid `u32` in `max_entry_len` field.", - })?; - metadata::Limits::new(lower, upper).into() - } - _ => return Err(ParseError { - reason: - "Unsupported type provided for the `val` part of the `Parameter`.", - }), - }; - Ok(Self::new(param_id, val)) - } else { - let val = val_candidate.parse::().map_err(|_| ParseError { - reason: - "Failed to parse the `val` part of the `Parameter` as `Numeric`.", - })?; - - Ok(Self::new(param_id, val.into())) - } - } else { - Err(ParseError { - reason: "`param_id` part of `Parameter` must start with `?`", - }) - } - } else { - Err(ParseError { - reason: "The `Parameter` string did not contain the `=` character.", - }) - } - } - } - - /// Convenience tool for setting parameters - #[derive(Default)] - #[must_use] - pub struct ParametersBuilder { - parameters: Vec, - } - - /// Error associated with parameters builder - #[derive(From, Debug, Display, Copy, Clone)] - pub enum ParametersBuilderError { - /// Error emerged during parsing of parameter id - Parse(ParseError), - } - - #[cfg(feature = "std")] - impl std::error::Error for ParametersBuilderError {} - - impl ParametersBuilder { - /// Construct [`Self`] - pub fn new() -> Self { - Self::default() - } - - /// Add [`Parameter`] to self - /// - /// # Errors - /// - [`ParameterId`] parsing failed - pub fn add_parameter( - mut self, - parameter_id: &str, - val: impl Into, - ) -> Result { - let parameter = Parameter { - id: parameter_id.parse()?, - val: val.into(), - }; - self.parameters.push(parameter); - Ok(self) - } - - /// Create sequence isi for setting parameters - pub fn into_set_parameters(self) -> Vec { - self.parameters - .into_iter() - .map(isi::SetParameter::new) - .map(Into::into) - .collect() - } - - /// Create sequence isi for creating parameters - pub fn into_create_parameters(self) -> Vec { - self.parameters - .into_iter() - .map(isi::NewParameter::new) - .map(Into::into) - .collect() - } - } - - pub mod prelude { - //! Prelude: re-export of most commonly used traits, structs and macros in this crate. - - pub use super::{Parameter, ParameterId}; - } - - #[cfg(test)] - mod tests { - use super::*; - use crate::{ - prelude::{numeric, MetadataLimits}, - transaction::TransactionLimits, - }; - - const INVALID_PARAM: [&str; 4] = [ - "", - "Block?SyncGossipPeriod=20000", - "?BlockSyncGossipPeriod20000", - "?BlockSyncGossipPeriod=20000_u32", - ]; - - #[test] - fn test_invalid_parameter_str() { - assert!(matches!( - parameter::Parameter::from_str(INVALID_PARAM[0]), - Err(err) if err.reason == "The `Parameter` string did not contain the `=` character." - )); - assert!(matches!( - parameter::Parameter::from_str(INVALID_PARAM[1]), - Err(err) if err.reason == "`param_id` part of `Parameter` must start with `?`" - )); - assert!(matches!( - parameter::Parameter::from_str(INVALID_PARAM[2]), - Err(err) if err.to_string() == "The `Parameter` string did not contain the `=` character." - )); - assert!(matches!( - parameter::Parameter::from_str(INVALID_PARAM[3]), - Err(err) if err.to_string() == "Unsupported type provided for the `val` part of the `Parameter`." - )); - } - - #[test] - fn test_parameter_serialize_deserialize_consistent() { - let parameters = [ - Parameter::new( - ParameterId::from_str("TransactionLimits") - .expect("Failed to parse `ParameterId`"), - TransactionLimits::new(42, 24).into(), - ), - Parameter::new( - ParameterId::from_str("MetadataLimits").expect("Failed to parse `ParameterId`"), - MetadataLimits::new(42, 24).into(), - ), - Parameter::new( - ParameterId::from_str("LengthLimits").expect("Failed to parse `ParameterId`"), - LengthLimits::new(24, 42).into(), - ), - Parameter::new( - ParameterId::from_str("Int").expect("Failed to parse `ParameterId`"), - numeric!(42).into(), - ), - ]; - - for parameter in parameters { - assert_eq!( - parameter, - serde_json::to_string(¶meter) - .and_then(|parameter| serde_json::from_str(¶meter)) - .unwrap_or_else(|_| panic!( - "Failed to de/serialize parameter {:?}", - ¶meter - )) - ); - } - } - } -} - #[model] #[allow(clippy::redundant_pub_crate)] mod model { @@ -689,8 +285,6 @@ mod model { RoleId(role::RoleId), /// [`Permission`](`permission::Permission`) variant. PermissionId(permission::PermissionId), - /// [`ParameterId`](`parameter::ParameterId`) variant. - ParameterId(parameter::ParameterId), } /// Sized container for all possible entities. @@ -735,35 +329,6 @@ mod model { Trigger(trigger::Trigger), /// [`Role`](`role::Role`) variant. Role(role::Role), - /// [`Parameter`](`parameter::Parameter`) variant. - Parameter(parameter::Parameter), - } - - /// Limits of length of the identifiers (e.g. in [`domain::Domain`], [`account::Account`], [`asset::AssetDefinition`]) in number of chars - #[derive( - Debug, - Display, - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Getters, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[display(fmt = "{min},{max}_LL")] - #[getset(get = "pub")] - #[ffi_type] - pub struct LengthLimits { - /// Minimal length in number of chars (inclusive). - pub(super) min: u32, - /// Maximal length in number of chars (inclusive). - pub(super) max: u32, } /// Operation validation failed. @@ -976,7 +541,6 @@ impl_encode_as_id_box! { trigger::TriggerId, permission::PermissionId, role::RoleId, - parameter::ParameterId, } impl_encode_as_identifiable_box! { @@ -991,7 +555,6 @@ impl_encode_as_identifiable_box! { asset::Asset, trigger::Trigger, role::Role, - parameter::Parameter, } impl Decode for ChainId { @@ -1030,7 +593,6 @@ impl IdentifiableBox { IdentifiableBox::Asset(a) => a.id().clone().into(), IdentifiableBox::Trigger(a) => a.id().clone().into(), IdentifiableBox::Role(a) => a.id().clone().into(), - IdentifiableBox::Parameter(a) => a.id().clone().into(), } } } @@ -1081,20 +643,6 @@ pub trait Registered: Identifiable { type With; } -impl LengthLimits { - /// Constructor. - pub const fn new(min: u32, max: u32) -> Self { - Self { min, max } - } -} - -impl From for RangeInclusive { - #[inline] - fn from(limits: LengthLimits) -> Self { - RangeInclusive::new(limits.min, limits.max) - } -} - declare_versioned!( BatchedResponse serde::Deserialize<'de>> 1..2, Debug, Clone, iroha_macro::FromVariant, IntoSchema @@ -1155,8 +703,8 @@ pub mod prelude { pub use super::{ account::prelude::*, asset::prelude::*, domain::prelude::*, events::prelude::*, executor::prelude::*, isi::prelude::*, metadata::prelude::*, name::prelude::*, - parameter::prelude::*, peer::prelude::*, permission::prelude::*, query::prelude::*, + param::prelude::*, peer::prelude::*, permission::prelude::*, query::prelude::*, role::prelude::*, transaction::prelude::*, trigger::prelude::*, ChainId, EnumTryAsError, - HasMetadata, IdBox, Identifiable, IdentifiableBox, LengthLimits, ValidationFail, + HasMetadata, IdBox, Identifiable, IdentifiableBox, ValidationFail, }; } diff --git a/data_model/src/metadata.rs b/data_model/src/metadata.rs index 110a13fd2cb..bf3d1be835d 100644 --- a/data_model/src/metadata.rs +++ b/data_model/src/metadata.rs @@ -25,9 +25,6 @@ use crate::Name; /// A path slice, composed of [`Name`]s. pub type Path = [Name]; -/// Collection of parameters by their names. -pub type UnlimitedMetadata = btree_map::BTreeMap; - #[model] mod model { use super::*; @@ -78,7 +75,6 @@ mod model { Name(Name), Bytes(Vec), Numeric(Numeric), - LimitedMetadata(Metadata), Vec( #[skip_from] @@ -86,97 +82,6 @@ mod model { Vec, ), } - - /// Limits for [`Metadata`]. - #[derive( - Debug, - Display, - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[ffi_type] - #[display(fmt = "{capacity},{max_entry_len}_ML")] - pub struct Limits { - /// Maximum number of entries - pub capacity: u32, - /// Maximum length of entry - pub max_entry_len: u32, - } - - /// Metadata related errors. - #[derive( - Debug, - displaydoc::Display, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[ffi_type(local)] - #[cfg_attr(feature = "std", derive(thiserror::Error))] - pub enum MetadataError { - /// Path specification empty - EmptyPath, - /// Metadata entry is too big - EntryTooBig(#[cfg_attr(feature = "std", source)] SizeError), - /// Metadata exceeds overall length limit - MaxCapacity(#[cfg_attr(feature = "std", source)] SizeError), - /// `{0}`: path segment not found, i.e. nothing was found at that key - MissingSegment(Name), - /// `{0}`: path segment not an instance of metadata - InvalidSegment(Name), - } - - /// Size limits exhaustion error - #[derive( - Debug, - Display, - Copy, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[ffi_type] - #[cfg_attr(feature = "std", derive(thiserror::Error))] - #[display(fmt = "Limits are {limits}, while the actual value is {actual}")] - pub struct SizeError { - /// The limits that were set for this entry - pub limits: Limits, - /// The actual *entry* size in bytes - pub actual: u64, - } -} - -impl Limits { - /// Constructor. - pub const fn new(capacity: u32, max_entry_len: u32) -> Limits { - Limits { - capacity, - max_entry_len, - } - } } impl From for MetadataValueBox { @@ -261,7 +166,6 @@ impl core::fmt::Display for MetadataValueBox { // one value stops and another one begins. write!(f, "{list_of_display:?}") } - MetadataValueBox::LimitedMetadata(v) => core::fmt::Display::fmt(&v, f), } } } @@ -275,40 +179,17 @@ impl MetadataValueBox { match self { Bool(_) | String(_) | Name(_) | Bytes(_) | Numeric(_) => 1, Vec(v) => v.iter().map(Self::len).sum::() + 1, - LimitedMetadata(data) => data.nested_len() + 1, } } } impl Metadata { - /// Constructor. - #[inline] - pub fn new() -> Self { - Self(UnlimitedMetadata::new()) - } - /// Get the (expensive) cumulative length of all [`Value`]s housed /// in this map. pub fn nested_len(&self) -> usize { self.0.values().map(|v| 1 + v.len()).sum() } - /// Get metadata given path. If the path is malformed, or - /// incorrect (if e.g. any of interior path segments are not - /// [`Metadata`] instances return `None`. Else borrow the value - /// corresponding to that path. - pub fn nested_get(&self, path: &Path) -> Option<&MetadataValueBox> { - let key = path.last()?; - let mut map = &self.0; - for k in path.iter().take(path.len() - 1) { - map = match map.get(k)? { - MetadataValueBox::LimitedMetadata(data) => &data.0, - _ => return None, - }; - } - map.get(key) - } - /// Check if the internal map contains the given key. pub fn contains(&self, key: &Name) -> bool { self.0.contains_key(key) @@ -328,69 +209,16 @@ impl Metadata { self.0.get(key) } - fn len_u64(&self) -> u64 { - self.0 - .len() - .try_into() - .expect("`usize` should always fit into `u64`") - } - - /// Insert the given [`Value`] into the given path. If the path is - /// complete, check the limits and only then insert. The creation - /// of the path is the responsibility of the user. - /// - /// # Errors - /// - If the path is empty. - /// - If one of the intermediate keys is absent. - /// - If some intermediate key is a leaf node. - pub fn nested_insert_with_limits( - &mut self, - path: &Path, - value: impl Into, - limits: Limits, - ) -> Result, MetadataError> { - if self.0.len() >= limits.capacity as usize { - return Err(MetadataError::MaxCapacity(SizeError { - limits, - actual: self.len_u64(), - })); - } - let key = path.last().ok_or(MetadataError::EmptyPath)?; - let mut layer = self; - for k in path.iter().take(path.len() - 1) { - layer = match layer - .0 - .get_mut(k) - .ok_or_else(|| MetadataError::MissingSegment(k.clone()))? - { - MetadataValueBox::LimitedMetadata(data) => data, - _ => return Err(MetadataError::InvalidSegment(k.clone())), - }; - } - layer.insert_with_limits(key.clone(), value, limits) - } - /// Insert [`Value`] under the given key. Returns `Some(value)` /// if the value was already present, `None` otherwise. - /// - /// # Errors - /// Fails if `max_entry_len` or `capacity` from `limits` are exceeded. - pub fn insert_with_limits( + pub fn insert( &mut self, key: Name, value: impl Into, - limits: Limits, - ) -> Result, MetadataError> { + ) -> Option { let value = value.into(); - if self.0.len() >= limits.capacity as usize && !self.0.contains_key(&key) { - return Err(MetadataError::MaxCapacity(SizeError { - limits, - actual: self.len_u64(), - })); - } - check_size_limits(&key, value.clone(), limits)?; - Ok(self.0.insert(key, value)) + self.0.insert(key, value) } } @@ -406,194 +234,9 @@ impl Metadata { { self.0.remove(key) } - - /// Remove leaf node in metadata, given path. If the path is - /// malformed, or incorrect (if e.g. any of interior path segments - /// are not [`Metadata`] instances) return `None`. Else return the - /// owned value corresponding to that path. - pub fn nested_remove(&mut self, path: &Path) -> Option { - let key = path.last()?; - let mut map = &mut self.0; - for k in path.iter().take(path.len() - 1) { - map = match map.get_mut(k)? { - MetadataValueBox::LimitedMetadata(data) => &mut data.0, - _ => return None, - }; - } - map.remove(key) - } -} - -fn check_size_limits( - key: &Name, - value: MetadataValueBox, - limits: Limits, -) -> Result<(), MetadataError> { - let entry_bytes: Vec = (key, value).encode(); - let byte_size = entry_bytes.len(); - if byte_size > limits.max_entry_len as usize { - return Err(MetadataError::EntryTooBig(SizeError { - limits, - actual: byte_size - .try_into() - .expect("`usize` should always fit into `u64`"), - })); - } - Ok(()) } pub mod prelude { //! Prelude: re-export most commonly used traits, structs and macros from this module. - pub use super::{Limits as MetadataLimits, Metadata, UnlimitedMetadata}; -} - -#[cfg(test)] -mod tests { - #[cfg(not(feature = "std"))] - use alloc::{borrow::ToOwned as _, vec}; - use core::str::FromStr as _; - - use super::*; - use crate::ParseError; - - /// Error used in testing to make text more readable using the `?` operator. - #[derive(Debug, Display, Clone, FromVariant)] - pub enum TestError { - Parse(ParseError), - Metadata(MetadataError), - } - - #[test] - fn nested_fns_ignore_empty_path() { - let mut metadata = Metadata::new(); - let empty_path = vec![]; - assert!(metadata.nested_get(&empty_path).is_none()); - assert!(metadata - .nested_insert_with_limits(&empty_path, "0".to_owned(), Limits::new(12, 12)) - .is_err()); - #[cfg(feature = "transparent_api")] - assert!(metadata.nested_remove(&empty_path).is_none()); - } - - #[test] - #[cfg(feature = "transparent_api")] - fn nesting_inserts_removes() -> Result<(), TestError> { - let mut metadata = Metadata::new(); - let limits = Limits::new(1024, 1024); - // TODO: If we allow a `unsafe`, we could create the path. - metadata - .insert_with_limits(Name::from_str("0")?, Metadata::new(), limits) - .expect("Valid"); - metadata - .nested_insert_with_limits( - &[Name::from_str("0")?, Name::from_str("1")?], - Metadata::new(), - limits, - ) - .expect("Valid"); - let path = [ - Name::from_str("0")?, - Name::from_str("1")?, - Name::from_str("2")?, - ]; - metadata - .nested_insert_with_limits(&path, "Hello World".to_owned(), limits) - .expect("Valid"); - assert_eq!( - *metadata.nested_get(&path).expect("Valid"), - MetadataValueBox::from("Hello World".to_owned()) - ); - assert_eq!(metadata.nested_len(), 6); // Three nested path segments. - metadata.nested_remove(&path); - assert!(metadata.nested_get(&path).is_none()); - Ok(()) - } - - #[test] - fn non_existent_path_segment_fails() -> Result<(), TestError> { - let mut metadata = Metadata::new(); - let limits = Limits::new(10, 15); - metadata.insert_with_limits(Name::from_str("0")?, Metadata::new(), limits)?; - metadata.nested_insert_with_limits( - &[Name::from_str("0")?, Name::from_str("1")?], - Metadata::new(), - limits, - )?; - let path = vec![ - Name::from_str("0")?, - Name::from_str("1")?, - Name::from_str("2")?, - ]; - metadata.nested_insert_with_limits(&path, "Hello World".to_owned(), limits)?; - let bad_path = vec![ - Name::from_str("0")?, - Name::from_str("3")?, - Name::from_str("2")?, - ]; - assert!(metadata - .nested_insert_with_limits(&bad_path, "Hello World".to_owned(), limits) - .is_err()); - assert!(metadata.nested_get(&bad_path).is_none()); - #[cfg(feature = "transparent_api")] - assert!(metadata.nested_remove(&bad_path).is_none()); - Ok(()) - } - - #[test] - fn nesting_respects_limits() -> Result<(), TestError> { - let mut metadata = Metadata::new(); - let limits = Limits::new(10, 14); - // TODO: If we allow a `unsafe`, we could create the path. - metadata.insert_with_limits(Name::from_str("0")?, Metadata::new(), limits)?; - metadata - .nested_insert_with_limits( - &[Name::from_str("0")?, Name::from_str("1")?], - Metadata::new(), - limits, - ) - .expect("Valid"); - let path = vec![ - Name::from_str("0")?, - Name::from_str("1")?, - Name::from_str("2")?, - ]; - let failing_insert = - metadata.nested_insert_with_limits(&path, "Hello World".to_owned(), limits); - - assert!(failing_insert.is_err()); - Ok(()) - } - - #[test] - fn insert_exceeds_entry_size() -> Result<(), TestError> { - let mut metadata = Metadata::new(); - let limits = Limits::new(10, 5); - assert!(metadata - .insert_with_limits(Name::from_str("1")?, "2".to_owned(), limits) - .is_ok()); - assert!(metadata - .insert_with_limits(Name::from_str("1")?, "23456".to_owned(), limits) - .is_err()); - Ok(()) - } - - #[test] - // This test is a good candidate for both property-based and parameterised testing - fn insert_exceeds_len() -> Result<(), TestError> { - let mut metadata = Metadata::new(); - let limits = Limits::new(2, 5); - assert!(metadata - .insert_with_limits(Name::from_str("1")?, "0".to_owned(), limits) - .is_ok()); - assert!(metadata - .insert_with_limits(Name::from_str("2")?, "0".to_owned(), limits) - .is_ok()); - assert!(metadata - .insert_with_limits(Name::from_str("2")?, "1".to_owned(), limits) - .is_ok()); - assert!(metadata - .insert_with_limits(Name::from_str("3")?, "0".to_owned(), limits) - .is_err()); - Ok(()) - } + pub use super::Metadata; } diff --git a/data_model/src/param.rs b/data_model/src/param.rs new file mode 100644 index 00000000000..b1a9358c604 --- /dev/null +++ b/data_model/src/param.rs @@ -0,0 +1,246 @@ +//! Structures, traits and impls related to `Paramater`s. +use core::{num::NonZeroU64, time::Duration}; + +use nonzero_ext::nonzero; +use strum::EnumDiscriminants; + +pub use self::model::*; +use super::*; + +#[model] +mod model { + use getset::CopyGetters; + + use super::*; + + /// Limits that a transaction must obey to be accepted. + #[derive( + Debug, + Display, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + CopyGetters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[display(fmt = "{max_instructions},{smart_contract_size}_TL")] + #[getset(get_copy = "pub")] + pub struct TransactionLimits { + /// Maximum number of instructions per transaction + pub max_instructions: NonZeroU64, + /// Maximum size of wasm binary in bytes + pub smart_contract_size: NonZeroU64, + } + + /// Limits that a block must obey to be accepted. + #[derive( + Debug, + Display, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + CopyGetters, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[display(fmt = "{max_transactions}_BL")] + #[getset(get_copy = "pub")] + pub struct BlockLimits { + /// Maximal number of transactions in a block. + /// + /// A block is created if this limit is reached or `Self::BlockTime` has expired, + /// whichever comes first. Regardless of the limits, an empty block is never created. + pub max_transactions: NonZeroU64, + } + + /// Limits that a smart contract must obey at runtime to not be considered invalid. + #[derive( + Debug, + Display, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + CopyGetters, + Decode, + Encode, + Serialize, + Deserialize, + IntoSchema, + )] + #[display(fmt = "{fuel},{memory}_SL")] + #[getset(get_copy = "pub")] + pub struct SmartContractLimits { + /// Maximum amount of fuel that a smart contract can consume + pub fuel: NonZeroU64, + /// Maximum amount of memory that a smart contract can use + pub memory: NonZeroU64, + } + + /// Single blockchain [`Parameter`]. Controls how blockchain works. + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + EnumDiscriminants, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[ffi_type(opaque)] + pub enum Parameter { + /// Maximal amount of time a peer will wait before forcing creation of a new block. + /// + /// A block is created if this limit or `Self::TransactionsInBlock` limit is reached, + /// whichever comes first. Regardless of the limits, an empty block is never created. + BlockTime(Duration), + /// How long a peer will wait for a block to be committed. + /// + /// If this period expires the block will request a view change + CommitTime(Duration), + /// Block limits + BlockLimits(BlockLimits), + /// Transaction limits. + TransactionLimits(TransactionLimits), + /// Smart contract limits (user submitted smart contracts and triggers) + SmartContractLimits(SmartContractLimits), + /// Executor limits + ExecutorLimits(SmartContractLimits), + /// Blockchain specific parameter (defined in the executor) + Custom(JsonString), + } + + /// Set of all current blockchain parameter values + /// + /// See [`Parameter`] for details + #[derive( + Debug, + Clone, + PartialEq, + Eq, + PartialOrd, + Ord, + Decode, + Encode, + Deserialize, + Serialize, + IntoSchema, + )] + #[allow(missing_docs)] + pub struct Parameters { + pub block_time: Duration, + pub commit_time: Duration, + pub block_limits: BlockLimits, + pub transaction_limits: TransactionLimits, + pub executor_limits: SmartContractLimits, + pub smart_contract_limits: SmartContractLimits, + /// Collection of all custom parameters + pub custom: JsonString, + } +} + +impl core::fmt::Display for Parameter { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::BlockTime(v) | Self::CommitTime(v) => core::fmt::Debug::fmt(&v, f), + Self::BlockLimits(v) => core::fmt::Display::fmt(&v, f), + Self::TransactionLimits(v) => core::fmt::Display::fmt(&v, f), + Self::SmartContractLimits(v) | Self::ExecutorLimits(v) => { + core::fmt::Display::fmt(&v, f) + } + Self::Custom(v) => write!(f, "Custom({})", v.0), + } + } +} + +impl Default for Parameters { + fn default() -> Self { + /// Default value for [`Parameters::BlockTime`] + pub const DEFAULT_BLOCK_TIME: Duration = Duration::from_secs(2); + /// Default value for [`Parameters::CommitTime`] + pub const DEFAULT_COMMIT_TIME: Duration = Duration::from_secs(4); + + Self { + block_time: DEFAULT_BLOCK_TIME, + commit_time: DEFAULT_COMMIT_TIME, + block_limits: BlockLimits::default(), + transaction_limits: TransactionLimits::default(), + executor_limits: SmartContractLimits::default(), + smart_contract_limits: SmartContractLimits::default(), + custom: JsonString::default(), + } + } +} + +impl Default for BlockLimits { + fn default() -> Self { + /// Default value for [`Parameters::MaxTransactionsInBlock`] + pub const DEFAULT_TRANSACTIONS_IN_BLOCK: NonZeroU64 = nonzero!(2_u64.pow(9)); + + Self::new(DEFAULT_TRANSACTIONS_IN_BLOCK) + } +} + +impl Default for TransactionLimits { + fn default() -> Self { + const DEFAULT_INSTRUCTION_NUMBER: NonZeroU64 = nonzero!(2_u64.pow(12)); + const DEFAULT_SMART_CONTRACT_SIZE: NonZeroU64 = nonzero!(4 * 2_u64.pow(20)); + + Self::new(DEFAULT_INSTRUCTION_NUMBER, DEFAULT_SMART_CONTRACT_SIZE) + } +} + +impl Default for SmartContractLimits { + fn default() -> Self { + const DEFAULT_FUEL: NonZeroU64 = nonzero!(55_000_000_u64); + const DEFAULT_MEMORY: NonZeroU64 = nonzero!(55_000_000_u64); + + Self { + fuel: DEFAULT_FUEL, + memory: DEFAULT_MEMORY, + } + } +} + +impl BlockLimits { + /// Construct [`Self`] + pub const fn new(max_transactions: NonZeroU64) -> Self { + Self { max_transactions } + } +} + +impl TransactionLimits { + /// Construct [`Self`] + pub const fn new(max_instructions: NonZeroU64, smart_contract_size: NonZeroU64) -> Self { + Self { + max_instructions, + smart_contract_size, + } + } +} + +pub mod prelude { + //! Prelude: re-export of most commonly used traits, structs and macros in this crate. + + pub use super::{Parameter, Parameters, SmartContractLimits, TransactionLimits}; +} diff --git a/data_model/src/query/mod.rs b/data_model/src/query/mod.rs index 92ec08b6750..a39d13225ec 100644 --- a/data_model/src/query/mod.rs +++ b/data_model/src/query/mod.rs @@ -161,7 +161,7 @@ mod model { #[enum_ref(derive(Encode, FromVariant))] #[strum_discriminants( vis(pub(super)), - name(QueryType), + name(QueryId), derive(Encode), allow(clippy::enum_variant_names) )] @@ -231,6 +231,7 @@ mod model { Identifiable(IdentifiableBox), Transaction(TransactionQueryOutput), Permission(crate::permission::Permission), + Parameters(crate::param::Parameters), LimitedMetadata(MetadataValueBox), Numeric(Numeric), BlockHeader(BlockHeader), @@ -240,7 +241,7 @@ mod model { Vec( #[skip_from] #[skip_try_from] - Vec, + Vec, ), } @@ -421,7 +422,7 @@ impl_queries! { FindDomainById => crate::domain::Domain, FindDomainKeyValueByIdAndKey => MetadataValueBox, FindAllPeers => Vec, - FindAllParameters => Vec, + FindAllParameters => crate::param::Parameters, FindAllActiveTriggerIds => Vec, FindTriggerById => crate::trigger::Trigger, FindTriggerKeyValueByIdAndKey => MetadataValueBox, @@ -448,17 +449,18 @@ impl core::fmt::Display for QueryOutputBox { // TODO: Maybe derive fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - QueryOutputBox::Id(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::Identifiable(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::Transaction(_) => write!(f, "TransactionQueryOutput"), - QueryOutputBox::Permission(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::Block(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::BlockHeader(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::Numeric(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::LimitedMetadata(v) => core::fmt::Display::fmt(&v, f), - QueryOutputBox::ExecutorDataModel(v) => core::fmt::Display::fmt(&v, f), - - QueryOutputBox::Vec(v) => { + Self::Id(v) => core::fmt::Display::fmt(&v, f), + Self::Identifiable(v) => core::fmt::Display::fmt(&v, f), + Self::Transaction(_) => write!(f, "TransactionQueryOutput"), + Self::Permission(v) => core::fmt::Display::fmt(&v, f), + Self::Parameters(v) => core::fmt::Debug::fmt(&v, f), + Self::Block(v) => core::fmt::Display::fmt(&v, f), + Self::BlockHeader(v) => core::fmt::Display::fmt(&v, f), + Self::Numeric(v) => core::fmt::Display::fmt(&v, f), + Self::LimitedMetadata(v) => core::fmt::Display::fmt(&v, f), + Self::ExecutorDataModel(v) => core::fmt::Display::fmt(&v, f), + + Self::Vec(v) => { // TODO: Remove so we can derive. let list_of_display: Vec<_> = v.iter().map(ToString::to_string).collect(); // this prints with quotation marks, which is fine 90% @@ -487,7 +489,7 @@ macro_rules! from_and_try_from_value_idbox { impl From<$ty> for QueryOutputBox { fn from(id: $ty) -> Self { - QueryOutputBox::Id(IdBox::$variant(id)) + Self::Id(IdBox::$variant(id)) } })+ }; @@ -509,7 +511,7 @@ macro_rules! from_and_try_from_value_identifiable { impl From<$ty> for QueryOutputBox { fn from(id: $ty) -> Self { - QueryOutputBox::Identifiable(IdentifiableBox::$variant(id)) + Self::Identifiable(IdentifiableBox::$variant(id)) } } )+ }; @@ -523,7 +525,6 @@ from_and_try_from_value_idbox!( AssetDefinitionId(crate::asset::AssetDefinitionId), TriggerId(crate::trigger::TriggerId), RoleId(crate::role::RoleId), - ParameterId(crate::parameter::ParameterId), // TODO: Should we wrap String with new type in order to convert like here? //from_and_try_from_value_idbox!((DomainName(Name), ErrorValueTryFromDomainName),); ); @@ -540,12 +541,11 @@ from_and_try_from_value_identifiable!( Asset(crate::asset::Asset), Trigger(crate::trigger::Trigger), Role(crate::role::Role), - Parameter(crate::parameter::Parameter), ); impl> From> for QueryOutputBox { - fn from(values: Vec) -> QueryOutputBox { - QueryOutputBox::Vec(values.into_iter().map(Into::into).collect()) + fn from(values: Vec) -> Self { + Self::Vec(values.into_iter().map(Into::into).collect()) } } @@ -604,7 +604,7 @@ pub mod role { use derive_more::Display; use parity_scale_codec::Encode; - use super::{Query, QueryType}; + use super::{Query, QueryId}; use crate::prelude::*; queries! { @@ -660,7 +660,7 @@ pub mod permission { use derive_more::Display; use parity_scale_codec::Encode; - use super::{Query, QueryType}; + use super::{Query, QueryId}; use crate::prelude::*; queries! { @@ -692,7 +692,7 @@ pub mod account { use derive_more::Display; use parity_scale_codec::Encode; - use super::{MetadataValueBox, Query, QueryType}; + use super::{MetadataValueBox, Query, QueryId}; use crate::prelude::*; queries! { @@ -772,7 +772,7 @@ pub mod asset { use iroha_primitives::numeric::Numeric; use parity_scale_codec::Encode; - use super::{MetadataValueBox, Query, QueryType}; + use super::{MetadataValueBox, Query, QueryId}; use crate::prelude::*; queries! { @@ -873,7 +873,7 @@ pub mod asset { } /// [`FindAssetQuantityById`] Iroha Query gets [`AssetId`] as input and finds [`Asset::quantity`] - /// parameter's value if [`Asset`] is presented in Iroha Peer. + /// value if [`Asset`] is presented in Iroha Peer. #[derive(Display)] #[display(fmt = "Find quantity of the `{id}` asset")] #[repr(transparent)] @@ -945,7 +945,7 @@ pub mod domain { use derive_more::Display; use parity_scale_codec::Encode; - use super::{MetadataValueBox, Query, QueryType}; + use super::{MetadataValueBox, Query, QueryId}; use crate::prelude::*; queries! { @@ -994,7 +994,7 @@ pub mod peer { use derive_more::Display; use parity_scale_codec::Encode; - use super::{Query, QueryType}; + use super::{Query, QueryId}; queries! { /// [`FindAllPeers`] Iroha Query finds all trusted [`Peer`]s presented in current Iroha [`Peer`]. @@ -1046,7 +1046,7 @@ pub mod trigger { use derive_more::Display; use parity_scale_codec::Encode; - use super::{MetadataValueBox, Query, QueryType}; + use super::{MetadataValueBox, Query, QueryId}; use crate::{ account::AccountId, domain::prelude::*, @@ -1130,7 +1130,7 @@ pub mod transaction { use iroha_crypto::HashOf; use parity_scale_codec::Encode; - use super::{Query, QueryType, TransactionQueryOutput}; + use super::{Query, QueryId, TransactionQueryOutput}; use crate::{account::AccountId, prelude::Account, transaction::SignedTransaction}; queries! { @@ -1557,8 +1557,6 @@ pub mod error { Role(RoleId), /// Failed to find [`Permission`] by id. Permission(PermissionId), - /// Parameter with id `{0}` not found - Parameter(ParameterId), /// Failed to find public key: `{0}` PublicKey(PublicKey), } diff --git a/data_model/src/query/predicate.rs b/data_model/src/query/predicate.rs index 87b4e80917e..a0d7e152900 100644 --- a/data_model/src/query/predicate.rs +++ b/data_model/src/query/predicate.rs @@ -602,7 +602,6 @@ pub mod string { IdBox::TriggerId(id) => self.applies(&id.to_string()), IdBox::RoleId(id) => self.applies(&id.to_string()), IdBox::PermissionId(id) => self.applies(&id.to_string()), - IdBox::ParameterId(id) => self.applies(&id.to_string()), } } } diff --git a/data_model/src/transaction.rs b/data_model/src/transaction.rs index 7ced1cab628..961e96bc80f 100644 --- a/data_model/src/transaction.rs +++ b/data_model/src/transaction.rs @@ -23,13 +23,13 @@ pub use self::model::*; use crate::{ account::AccountId, isi::{Instruction, InstructionBox}, - metadata::UnlimitedMetadata, + metadata::Metadata, ChainId, }; #[model] mod model { - use getset::{CopyGetters, Getters}; + use getset::Getters; use super::*; use crate::account::AccountId; @@ -114,34 +114,7 @@ mod model { /// Random value to make different hashes for transactions which occur repeatedly and simultaneously. pub nonce: Option, /// Store for additional information. - pub metadata: UnlimitedMetadata, - } - - /// Container for limits that transactions must obey. - #[derive( - Debug, - Display, - Clone, - Copy, - PartialEq, - Eq, - PartialOrd, - Ord, - CopyGetters, - Decode, - Encode, - Deserialize, - Serialize, - IntoSchema, - )] - #[display(fmt = "{max_instruction_number},{max_wasm_size_bytes}_TL")] - #[getset(get_copy = "pub")] - #[ffi_type] - pub struct TransactionLimits { - /// Maximum number of instructions per transaction - pub max_instruction_number: u64, - /// Maximum size of wasm binary - pub max_wasm_size_bytes: u64, + pub metadata: Metadata, } /// Signature of transaction @@ -206,16 +179,6 @@ mod model { } } -impl TransactionLimits { - /// Construct [`Self`] - pub const fn new(max_instruction_number: u64, max_wasm_size_bytes: u64) -> Self { - Self { - max_instruction_number, - max_wasm_size_bytes, - } - } -} - impl FromIterator for Executable { fn from_iter>(iter: T) -> Self { Self::Instructions(iter.into_iter().map(Into::into).collect()) @@ -282,7 +245,7 @@ impl SignedTransaction { /// Return transaction metadata. #[inline] - pub fn metadata(&self) -> &UnlimitedMetadata { + pub fn metadata(&self) -> &Metadata { let SignedTransaction::V1(tx) = self; &tx.payload.metadata } @@ -597,7 +560,6 @@ pub mod error { Revoke(_) => "revoke", ExecuteTrigger(_) => "execute trigger", SetParameter(_) => "set parameter", - NewParameter(_) => "new parameter", Upgrade(_) => "upgrade", Log(_) => "log", Custom(_) => "custom", @@ -656,7 +618,7 @@ mod http { nonce: None, time_to_live_ms: None, instructions: Vec::::new().into(), - metadata: UnlimitedMetadata::new(), + metadata: Metadata::default(), }, } } @@ -723,7 +685,7 @@ mod http { } /// Adds metadata to the `Transaction` - pub fn with_metadata(mut self, metadata: UnlimitedMetadata) -> Self { + pub fn with_metadata(mut self, metadata: Metadata) -> Self { self.payload.metadata = metadata; self } diff --git a/data_model/src/trigger.rs b/data_model/src/trigger.rs index 1170a87c4e2..8893ff88084 100644 --- a/data_model/src/trigger.rs +++ b/data_model/src/trigger.rs @@ -189,7 +189,7 @@ pub mod action { // TODO: At this point the authority is meaningless. authority, filter: filter.into(), - metadata: Metadata::new(), + metadata: Metadata::default(), } } diff --git a/data_model/src/visit.rs b/data_model/src/visit.rs index bf0dcfacdf0..90be6e969c0 100644 --- a/data_model/src/visit.rs +++ b/data_model/src/visit.rs @@ -40,7 +40,6 @@ pub trait Visit { visit_upgrade(&Upgrade), visit_execute_trigger(&ExecuteTrigger), - visit_new_parameter(&NewParameter), visit_set_parameter(&SetParameter), visit_log(&Log), visit_custom(&Custom), @@ -233,9 +232,6 @@ pub fn visit_instruction( isi: &InstructionBox, ) { match isi { - InstructionBox::NewParameter(variant_value) => { - visitor.visit_new_parameter(authority, variant_value) - } InstructionBox::SetParameter(variant_value) => { visitor.visit_set_parameter(authority, variant_value) } @@ -428,7 +424,6 @@ leaf_visitors! { visit_mint_trigger_repetitions(&Mint), visit_burn_trigger_repetitions(&Burn), visit_upgrade(&Upgrade), - visit_new_parameter(&NewParameter), visit_set_parameter(&SetParameter), visit_execute_trigger(&ExecuteTrigger), visit_fail(&Fail), diff --git a/docs/source/references/schema.json b/docs/source/references/schema.json index e633ae613e1..06cb3c9e6fc 100644 --- a/docs/source/references/schema.json +++ b/docs/source/references/schema.json @@ -18,57 +18,57 @@ "AccountEvent": { "Enum": [ { - "tag": "Asset", + "tag": "Create", "discriminant": 0, - "type": "AssetEvent" + "type": "Account" }, { - "tag": "Created", + "tag": "Delete", "discriminant": 1, - "type": "Account" + "type": "AccountId" }, { - "tag": "Deleted", + "tag": "AuthenticationAdd", "discriminant": 2, "type": "AccountId" }, { - "tag": "AuthenticationAdded", + "tag": "AuthenticationRemove", "discriminant": 3, "type": "AccountId" }, { - "tag": "AuthenticationRemoved", + "tag": "Asset", "discriminant": 4, - "type": "AccountId" + "type": "AssetEvent" }, { - "tag": "PermissionAdded", + "tag": "PermissionAdd", "discriminant": 5, "type": "AccountPermissionChanged" }, { - "tag": "PermissionRemoved", + "tag": "PermissionRemove", "discriminant": 6, "type": "AccountPermissionChanged" }, { - "tag": "RoleRevoked", + "tag": "RoleGrant", "discriminant": 7, "type": "AccountRoleChanged" }, { - "tag": "RoleGranted", + "tag": "RoleRevoke", "discriminant": 8, "type": "AccountRoleChanged" }, { - "tag": "MetadataInserted", + "tag": "MetadataInsert", "discriminant": 9, "type": "MetadataChanged" }, { - "tag": "MetadataRemoved", + "tag": "MetadataRemove", "discriminant": 10, "type": "MetadataChanged" } @@ -91,47 +91,47 @@ "repr": "u32", "masks": [ { - "name": "AnyAsset", + "name": "Create", "mask": 1 }, { - "name": "Created", + "name": "Delete", "mask": 2 }, { - "name": "Deleted", + "name": "AuthenticationAdd", "mask": 4 }, { - "name": "AuthenticationAdded", + "name": "AuthenticationRemove", "mask": 8 }, { - "name": "AuthenticationRemoved", + "name": "AnyAsset", "mask": 16 }, { - "name": "PermissionAdded", + "name": "PermissionAdd", "mask": 32 }, { - "name": "PermissionRemoved", + "name": "PermissionRemove", "mask": 64 }, { - "name": "RoleRevoked", + "name": "RoleGrant", "mask": 128 }, { - "name": "RoleGranted", + "name": "RoleRevoke", "mask": 256 }, { - "name": "MetadataInserted", + "name": "MetadataInsert", "mask": 512 }, { - "name": "MetadataRemoved", + "name": "MetadataRemove", "mask": 1024 } ] @@ -290,39 +290,39 @@ "AssetDefinitionEvent": { "Enum": [ { - "tag": "Created", + "tag": "Create", "discriminant": 0, "type": "AssetDefinition" }, { - "tag": "MintabilityChanged", + "tag": "Delete", "discriminant": 1, "type": "AssetDefinitionId" }, { - "tag": "OwnerChanged", + "tag": "MetadataInsert", "discriminant": 2, - "type": "AssetDefinitionOwnerChanged" + "type": "MetadataChanged" }, { - "tag": "Deleted", + "tag": "MetadataRemove", "discriminant": 3, - "type": "AssetDefinitionId" + "type": "MetadataChanged" }, { - "tag": "MetadataInserted", + "tag": "MintabilityChange", "discriminant": 4, - "type": "MetadataChanged" + "type": "AssetDefinitionId" }, { - "tag": "MetadataRemoved", + "tag": "TotalQuantityChange", "discriminant": 5, - "type": "MetadataChanged" + "type": "AssetDefinitionTotalQuantityChanged" }, { - "tag": "TotalQuantityChanged", + "tag": "OwnerChange", "discriminant": 6, - "type": "AssetDefinitionTotalQuantityChanged" + "type": "AssetDefinitionOwnerChanged" } ] }, @@ -343,31 +343,31 @@ "repr": "u32", "masks": [ { - "name": "Created", + "name": "Create", "mask": 1 }, { - "name": "MintabilityChanged", + "name": "Delete", "mask": 2 }, { - "name": "OwnerChanged", + "name": "MetadataInsert", "mask": 4 }, { - "name": "Deleted", + "name": "MetadataRemove", "mask": 8 }, { - "name": "MetadataInserted", + "name": "MintabilityChange", "mask": 16 }, { - "name": "MetadataRemoved", + "name": "TotalQuantityChange", "mask": 32 }, { - "name": "TotalQuantityChanged", + "name": "OwnerChange", "mask": 64 } ] @@ -412,32 +412,32 @@ "AssetEvent": { "Enum": [ { - "tag": "Created", + "tag": "Create", "discriminant": 0, "type": "Asset" }, { - "tag": "Deleted", + "tag": "Delete", "discriminant": 1, "type": "AssetId" }, { - "tag": "Added", + "tag": "Add", "discriminant": 2, "type": "AssetChanged" }, { - "tag": "Removed", + "tag": "Remove", "discriminant": 3, "type": "AssetChanged" }, { - "tag": "MetadataInserted", + "tag": "MetadataInsert", "discriminant": 4, "type": "MetadataChanged" }, { - "tag": "MetadataRemoved", + "tag": "MetadataRemove", "discriminant": 5, "type": "MetadataChanged" } @@ -460,27 +460,27 @@ "repr": "u32", "masks": [ { - "name": "Created", + "name": "Create", "mask": 1 }, { - "name": "Deleted", + "name": "Delete", "mask": 2 }, { - "name": "Added", + "name": "Add", "mask": 4 }, { - "name": "Removed", + "name": "Remove", "mask": 8 }, { - "name": "MetadataInserted", + "name": "MetadataInsert", "mask": 16 }, { - "name": "MetadataRemoved", + "name": "MetadataRemove", "mask": 32 } ] @@ -592,7 +592,7 @@ "Struct": [ { "name": "height", - "type": "Option" + "type": "Option>" }, { "name": "status", @@ -604,7 +604,7 @@ "Struct": [ { "name": "height", - "type": "u64" + "type": "NonZero" }, { "name": "prev_block_hash", @@ -628,6 +628,14 @@ } ] }, + "BlockLimits": { + "Struct": [ + { + "name": "max_transactions", + "type": "NonZero" + } + ] + }, "BlockMessage": "SignedBlock", "BlockPayload": { "Struct": [ @@ -773,28 +781,14 @@ "ConfigurationEvent": { "Enum": [ { - "tag": "Changed", + "tag": "Change", "discriminant": 0, - "type": "ParameterId" - }, - { - "tag": "Created", - "discriminant": 1, - "type": "ParameterId" - }, - { - "tag": "Deleted", - "discriminant": 2, - "type": "ParameterId" + "type": "Parameter" } ] }, "ConfigurationEventFilter": { "Struct": [ - { - "name": "id_matcher", - "type": "Option" - }, { "name": "event_set", "type": "ConfigurationEventSet" @@ -806,16 +800,8 @@ "repr": "u32", "masks": [ { - "name": "Changed", + "name": "Change", "mask": 1 - }, - { - "name": "Created", - "mask": 2 - }, - { - "name": "Deleted", - "mask": 4 } ] } @@ -965,37 +951,37 @@ "DomainEvent": { "Enum": [ { - "tag": "Account", + "tag": "Create", "discriminant": 0, - "type": "AccountEvent" + "type": "Domain" }, { - "tag": "AssetDefinition", + "tag": "Delete", "discriminant": 1, - "type": "AssetDefinitionEvent" + "type": "DomainId" }, { - "tag": "Created", + "tag": "AssetDefinition", "discriminant": 2, - "type": "Domain" + "type": "AssetDefinitionEvent" }, { - "tag": "Deleted", + "tag": "Account", "discriminant": 3, - "type": "DomainId" + "type": "AccountEvent" }, { - "tag": "MetadataInserted", + "tag": "MetadataInsert", "discriminant": 4, "type": "MetadataChanged" }, { - "tag": "MetadataRemoved", + "tag": "MetadataRemove", "discriminant": 5, "type": "MetadataChanged" }, { - "tag": "OwnerChanged", + "tag": "OwnerChange", "discriminant": 6, "type": "DomainOwnerChanged" } @@ -1018,31 +1004,31 @@ "repr": "u32", "masks": [ { - "name": "AnyAccount", + "name": "Create", "mask": 1 }, { - "name": "AnyAssetDefinition", + "name": "Delete", "mask": 2 }, { - "name": "Created", + "name": "AnyAssetDefinition", "mask": 4 }, { - "name": "Deleted", + "name": "AnyAccount", "mask": 8 }, { - "name": "MetadataInserted", + "name": "MetadataInsert", "mask": 16 }, { - "name": "MetadataRemoved", + "name": "MetadataRemove", "mask": 32 }, { - "name": "OwnerChanged", + "name": "OwnerChange", "mask": 64 } ] @@ -1220,7 +1206,7 @@ "ExecutorEvent": { "Enum": [ { - "tag": "Upgraded", + "tag": "Upgrade", "discriminant": 0, "type": "ExecutorUpgrade" } @@ -1239,7 +1225,7 @@ "repr": "u32", "masks": [ { - "name": "Upgraded", + "name": "Upgrade", "mask": 1 } ] @@ -1494,14 +1480,9 @@ "discriminant": 10, "type": "PermissionId" }, - { - "tag": "Parameter", - "discriminant": 11, - "type": "ParameterId" - }, { "tag": "PublicKey", - "discriminant": 12, + "discriminant": 11, "type": "PublicKey" } ] @@ -1727,11 +1708,6 @@ "tag": "PermissionId", "discriminant": 7, "type": "PermissionId" - }, - { - "tag": "ParameterId", - "discriminant": 8, - "type": "ParameterId" } ] }, @@ -1791,11 +1767,6 @@ "tag": "Role", "discriminant": 10, "type": "Role" - }, - { - "tag": "Parameter", - "discriminant": 11, - "type": "Parameter" } ] }, @@ -1856,29 +1827,24 @@ "discriminant": 10, "type": "SetParameter" }, - { - "tag": "NewParameter", - "discriminant": 11, - "type": "NewParameter" - }, { "tag": "Upgrade", - "discriminant": 12, + "discriminant": 11, "type": "Upgrade" }, { "tag": "Log", - "discriminant": 13, + "discriminant": 12, "type": "Log" }, { "tag": "Custom", - "discriminant": 14, + "discriminant": 13, "type": "Custom" }, { "tag": "Fail", - "discriminant": 15, + "discriminant": 14, "type": "Fail" } ] @@ -1888,7 +1854,7 @@ { "tag": "Unsupported", "discriminant": 0, - "type": "InstructionType" + "type": "InstructionId" }, { "tag": "PermissionParameter", @@ -1939,24 +1905,19 @@ "discriminant": 6, "type": "MathError" }, - { - "tag": "Metadata", - "discriminant": 7, - "type": "MetadataError" - }, { "tag": "Fail", - "discriminant": 8, + "discriminant": 7, "type": "String" }, { "tag": "InvalidParameter", - "discriminant": 9, + "discriminant": 8, "type": "InvalidParameterError" }, { "tag": "InvariantViolation", - "discriminant": 10, + "discriminant": 9, "type": "String" } ] @@ -1973,7 +1934,7 @@ } ] }, - "InstructionType": { + "InstructionId": { "Enum": [ { "tag": "Register", @@ -2019,25 +1980,21 @@ "tag": "SetParameter", "discriminant": 10 }, - { - "tag": "NewParameter", - "discriminant": 11 - }, { "tag": "Upgrade", - "discriminant": 12 + "discriminant": 11 }, { "tag": "Log", - "discriminant": 13 + "discriminant": 12 }, { "tag": "Custom", - "discriminant": 14 + "discriminant": 13 }, { "tag": "Fail", - "discriminant": 15 + "discriminant": 14 } ] }, @@ -2062,18 +2019,6 @@ "Ipv4Addr": "Array", "Ipv6Addr": "Array", "JsonString": "String", - "LengthLimits": { - "Struct": [ - { - "name": "min", - "type": "u32" - }, - { - "name": "max", - "type": "u32" - } - ] - }, "Level": { "Enum": [ { @@ -2098,18 +2043,6 @@ } ] }, - "Limits": { - "Struct": [ - { - "name": "capacity", - "type": "u32" - }, - { - "name": "max_entry_len", - "type": "u32" - } - ] - }, "Log": { "Struct": [ { @@ -2239,34 +2172,6 @@ } ] }, - "MetadataError": { - "Enum": [ - { - "tag": "EmptyPath", - "discriminant": 0 - }, - { - "tag": "EntryTooBig", - "discriminant": 1, - "type": "SizeError" - }, - { - "tag": "MaxCapacity", - "discriminant": 2, - "type": "SizeError" - }, - { - "tag": "MissingSegment", - "discriminant": 3, - "type": "Name" - }, - { - "tag": "InvalidSegment", - "discriminant": 4, - "type": "Name" - } - ] - }, "MetadataValueBox": { "Enum": [ { @@ -2294,14 +2199,9 @@ "discriminant": 4, "type": "Numeric" }, - { - "tag": "LimitedMetadata", - "discriminant": 5, - "type": "Metadata" - }, { "tag": "Vec", - "discriminant": 6, + "discriminant": 5, "type": "Vec" } ] @@ -2437,14 +2337,6 @@ } ] }, - "NewParameter": { - "Struct": [ - { - "name": "parameter", - "type": "Parameter" - } - ] - }, "NewRole": { "Struct": [ { @@ -2512,11 +2404,8 @@ "Option>": { "Option": "NonZero" }, - "Option>": { - "Option": "Option" - }, - "Option": { - "Option": "ParameterId" + "Option>>": { + "Option": "Option>" }, "Option": { "Option": "PeerId" @@ -2545,9 +2434,6 @@ "Option": { "Option": "u32" }, - "Option": { - "Option": "u64" - }, "Pagination": { "Struct": [ { @@ -2561,46 +2447,73 @@ ] }, "Parameter": { - "Struct": [ + "Enum": [ { - "name": "id", - "type": "ParameterId" + "tag": "BlockTime", + "discriminant": 0, + "type": "Duration" + }, + { + "tag": "CommitTime", + "discriminant": 1, + "type": "Duration" + }, + { + "tag": "BlockLimits", + "discriminant": 2, + "type": "BlockLimits" + }, + { + "tag": "TransactionLimits", + "discriminant": 3, + "type": "TransactionLimits" }, { - "name": "val", - "type": "ParameterValueBox" + "tag": "SmartContractLimits", + "discriminant": 4, + "type": "SmartContractLimits" + }, + { + "tag": "ExecutorLimits", + "discriminant": 5, + "type": "SmartContractLimits" + }, + { + "tag": "Custom", + "discriminant": 6, + "type": "JsonString" } ] }, - "ParameterId": { + "Parameters": { "Struct": [ { - "name": "name", - "type": "Name" - } - ] - }, - "ParameterValueBox": { - "Enum": [ + "name": "block_time", + "type": "Duration" + }, { - "tag": "TransactionLimits", - "discriminant": 0, + "name": "commit_time", + "type": "Duration" + }, + { + "name": "block_limits", + "type": "BlockLimits" + }, + { + "name": "transaction_limits", "type": "TransactionLimits" }, { - "tag": "MetadataLimits", - "discriminant": 1, - "type": "Limits" + "name": "executor_limits", + "type": "SmartContractLimits" }, { - "tag": "LengthLimits", - "discriminant": 2, - "type": "LengthLimits" + "name": "smart_contract_limits", + "type": "SmartContractLimits" }, { - "tag": "Numeric", - "discriminant": 3, - "type": "Numeric" + "name": "custom", + "type": "JsonString" } ] }, @@ -2615,12 +2528,12 @@ "PeerEvent": { "Enum": [ { - "tag": "Added", + "tag": "Add", "discriminant": 0, "type": "PeerId" }, { - "tag": "Removed", + "tag": "Remove", "discriminant": 1, "type": "PeerId" } @@ -2643,11 +2556,11 @@ "repr": "u32", "masks": [ { - "name": "Added", + "name": "Add", "mask": 1 }, { - "name": "Removed", + "name": "Remove", "mask": 2 } ] @@ -2978,33 +2891,38 @@ "type": "Permission" }, { - "tag": "LimitedMetadata", + "tag": "Parameters", "discriminant": 4, + "type": "Parameters" + }, + { + "tag": "LimitedMetadata", + "discriminant": 5, "type": "MetadataValueBox" }, { "tag": "Numeric", - "discriminant": 5, + "discriminant": 6, "type": "Numeric" }, { "tag": "BlockHeader", - "discriminant": 6, + "discriminant": 7, "type": "BlockHeader" }, { "tag": "Block", - "discriminant": 7, + "discriminant": 8, "type": "SignedBlock" }, { "tag": "ExecutorDataModel", - "discriminant": 8, + "discriminant": 9, "type": "ExecutorDataModel" }, { "tag": "Vec", - "discriminant": 9, + "discriminant": 10, "type": "Vec" } ] @@ -3264,7 +3182,7 @@ "Struct": [ { "name": "instruction_type", - "type": "InstructionType" + "type": "InstructionId" }, { "name": "id", @@ -3342,22 +3260,22 @@ "RoleEvent": { "Enum": [ { - "tag": "Created", + "tag": "Create", "discriminant": 0, "type": "Role" }, { - "tag": "Deleted", + "tag": "Delete", "discriminant": 1, "type": "RoleId" }, { - "tag": "PermissionRemoved", + "tag": "PermissionAdd", "discriminant": 2, "type": "RolePermissionChanged" }, { - "tag": "PermissionAdded", + "tag": "PermissionRemove", "discriminant": 3, "type": "RolePermissionChanged" } @@ -3380,19 +3298,19 @@ "repr": "u32", "masks": [ { - "name": "Created", + "name": "Create", "mask": 1 }, { - "name": "Deleted", + "name": "Delete", "mask": 2 }, { - "name": "PermissionRemoved", + "name": "PermissionAdd", "mask": 4 }, { - "name": "PermissionAdded", + "name": "PermissionRemove", "mask": 8 } ] @@ -3572,14 +3490,7 @@ } ] }, - "SetParameter": { - "Struct": [ - { - "name": "parameter", - "type": "Parameter" - } - ] - }, + "SetParameter": "Parameter", "Signature": { "Struct": [ { @@ -3654,15 +3565,15 @@ } ] }, - "SizeError": { + "SmartContractLimits": { "Struct": [ { - "name": "limits", - "type": "Limits" + "name": "fuel", + "type": "NonZero" }, { - "name": "actual", - "type": "u64" + "name": "memory", + "type": "NonZero" } ] }, @@ -3817,7 +3728,7 @@ }, { "name": "block_height", - "type": "Option" + "type": "Option>" }, { "name": "status", @@ -3833,7 +3744,7 @@ }, { "name": "block_height", - "type": "Option>" + "type": "Option>>" }, { "name": "status", @@ -3852,12 +3763,12 @@ "TransactionLimits": { "Struct": [ { - "name": "max_instruction_number", - "type": "u64" + "name": "max_instructions", + "type": "NonZero" }, { - "name": "max_wasm_size_bytes", - "type": "u64" + "name": "smart_contract_size", + "type": "NonZero" } ] }, @@ -3889,7 +3800,7 @@ }, { "name": "metadata", - "type": "SortedMap" + "type": "Metadata" } ] }, @@ -4103,32 +4014,32 @@ "TriggerEvent": { "Enum": [ { - "tag": "Created", + "tag": "Create", "discriminant": 0, "type": "TriggerId" }, { - "tag": "Deleted", + "tag": "Delete", "discriminant": 1, "type": "TriggerId" }, { - "tag": "Extended", + "tag": "Extend", "discriminant": 2, "type": "TriggerNumberOfExecutionsChanged" }, { - "tag": "Shortened", + "tag": "Shorten", "discriminant": 3, "type": "TriggerNumberOfExecutionsChanged" }, { - "tag": "MetadataInserted", + "tag": "MetadataInsert", "discriminant": 4, "type": "MetadataChanged" }, { - "tag": "MetadataRemoved", + "tag": "MetadataRemove", "discriminant": 5, "type": "MetadataChanged" } @@ -4151,27 +4062,27 @@ "repr": "u32", "masks": [ { - "name": "Created", + "name": "Create", "mask": 1 }, { - "name": "Deleted", + "name": "Delete", "mask": 2 }, { - "name": "Extended", + "name": "Extend", "mask": 4 }, { - "name": "Shortened", + "name": "Shorten", "mask": 8 }, { - "name": "MetadataInserted", + "name": "MetadataInsert", "mask": 16 }, { - "name": "MetadataRemoved", + "name": "MetadataRemove", "mask": 32 } ] diff --git a/ffi/src/std_impls.rs b/ffi/src/std_impls.rs index d45d2ece14e..ff65bbae07b 100644 --- a/ffi/src/std_impls.rs +++ b/ffi/src/std_impls.rs @@ -47,17 +47,25 @@ ffi_type! { niche_value=RefMutSlice::null_mut() } } +ffi_type! { + unsafe impl Transparent for core::ptr::NonNull { + type Target = *mut T; + + validation_fn=unsafe {|target: &*mut T| !target.is_null()}, + niche_value=core::ptr::null_mut() + } +} ffi_type! { unsafe impl Transparent for core::mem::ManuallyDrop { type Target = T; } } ffi_type! { - unsafe impl Transparent for core::ptr::NonNull { - type Target = *mut T; + unsafe impl Transparent for core::num::NonZeroU64 { + type Target = u64; - validation_fn=unsafe {|target: &*mut T| !target.is_null()}, - niche_value=core::ptr::null_mut() + validation_fn=unsafe {|target: &u64| *target != 0}, + niche_value=0 } } diff --git a/schema/gen/src/lib.rs b/schema/gen/src/lib.rs index 312c3f23ce7..a49b893c35a 100644 --- a/schema/gen/src/lib.rs +++ b/schema/gen/src/lib.rs @@ -204,12 +204,11 @@ types!( InstructionEvaluationError, InstructionExecutionError, InstructionExecutionFail, - InstructionType, + InstructionId, InvalidParameterError, IpfsPath, Ipv4Addr, Ipv6Addr, - LengthLimits, Level, Log, MathError, @@ -220,8 +219,6 @@ types!( MetadataChanged, MetadataChanged, MetadataChanged, - MetadataError, - MetadataLimits, MetadataValueBox, Mint, Mint, @@ -233,7 +230,6 @@ types!( NewAccount, NewAssetDefinition, NewDomain, - NewParameter, NewRole, NonTrivial, NonZeroU32, @@ -255,7 +251,6 @@ types!( Option, Option, Option>, - Option, Option, Option, Option, @@ -266,8 +261,6 @@ types!( Option, Pagination, Parameter, - ParameterId, - ParameterValueBox, Peer, PeerEvent, PeerEventFilter, @@ -330,7 +323,6 @@ types!( SignedQueryV1, SignedTransaction, SignedTransactionV1, - SizeError, SocketAddr, SocketAddrHost, SocketAddrV4, @@ -346,7 +338,6 @@ types!( TransactionEvent, TransactionEventFilter, TransactionLimitError, - TransactionLimits, TransactionPayload, TransactionQueryOutput, TransactionRejectionReason, @@ -429,10 +420,9 @@ pub mod complete_data_model { InstructionEvaluationError, InstructionExecutionError, InvalidParameterError, MathError, MintabilityError, Mismatch, RepetitionError, TypeError, }, - InstructionType, + InstructionId, }, - metadata::{MetadataError, MetadataValueBox, SizeError}, - parameter::ParameterValueBox, + metadata::MetadataValueBox, prelude::*, query::{ error::{FindError, QueryExecutionFail}, @@ -445,8 +435,8 @@ pub mod complete_data_model { ForwardCursor, Pagination, QueryOutputBox, Sorting, }, transaction::{ - error::TransactionLimitError, SignedTransactionV1, TransactionLimits, - TransactionPayload, TransactionSignature, + error::TransactionLimitError, SignedTransactionV1, TransactionPayload, + TransactionSignature, }, BatchedResponse, BatchedResponseV1, JsonString, Level, }; diff --git a/smart_contract/executor/derive/src/default.rs b/smart_contract/executor/derive/src/default.rs index 6b436fc7019..218c78cdfb0 100644 --- a/smart_contract/executor/derive/src/default.rs +++ b/smart_contract/executor/derive/src/default.rs @@ -156,7 +156,6 @@ pub fn impl_derive_visit(emitter: &mut Emitter, input: &syn::DeriveInput) -> Tok "fn visit_burn_trigger_repetitions(operation: &Burn)", "fn visit_execute_trigger(operation: &ExecuteTrigger)", "fn visit_set_parameter(operation: &SetParameter)", - "fn visit_new_parameter(operation: &NewParameter)", "fn visit_upgrade(operation: &Upgrade)", "fn visit_log(operation: &Log)", "fn visit_custom(operation: &Custom)", diff --git a/smart_contract/executor/src/default.rs b/smart_contract/executor/src/default.rs index 6a685fa757f..43d3060c5a0 100644 --- a/smart_contract/executor/src/default.rs +++ b/smart_contract/executor/src/default.rs @@ -28,7 +28,7 @@ pub use executor::visit_upgrade; pub use fail::visit_fail; use iroha_smart_contract::data_model::isi::InstructionBox; pub use log::visit_log; -pub use parameter::{visit_new_parameter, visit_set_parameter}; +pub use parameter::visit_set_parameter; pub use peer::{visit_register_peer, visit_unregister_peer}; pub use permission::{visit_grant_account_permission, visit_revoke_account_permission}; use permissions::AnyPermission; @@ -86,9 +86,6 @@ pub fn visit_instruction( isi: &InstructionBox, ) { match isi { - InstructionBox::NewParameter(isi) => { - executor.visit_new_parameter(authority, isi); - } InstructionBox::SetParameter(isi) => { executor.visit_set_parameter(authority, isi); } @@ -1121,25 +1118,6 @@ pub mod asset { pub mod parameter { use super::*; - #[allow(clippy::needless_pass_by_value)] - pub fn visit_new_parameter( - executor: &mut V, - authority: &AccountId, - isi: &NewParameter, - ) { - if is_genesis(executor) { - execute!(executor, isi); - } - if permissions::parameter::CanCreateParameters.is_owned_by(authority) { - execute!(executor, isi); - } - - deny!( - executor, - "Can't create new configuration parameters outside genesis without permission" - ); - } - #[allow(clippy::needless_pass_by_value)] pub fn visit_set_parameter( executor: &mut V, diff --git a/tools/kagami/src/genesis/generate.rs b/tools/kagami/src/genesis/generate.rs index 323a9ae612f..c6412978ae3 100644 --- a/tools/kagami/src/genesis/generate.rs +++ b/tools/kagami/src/genesis/generate.rs @@ -5,12 +5,7 @@ use std::{ use clap::{Parser, Subcommand}; use color_eyre::eyre::WrapErr as _; -use iroha_config::parameters::defaults::chain_wide as chain_wide_defaults; -use iroha_data_model::{ - metadata::Limits, - parameter::{default::*, ParametersBuilder}, - prelude::*, -}; +use iroha_data_model::prelude::*; use iroha_genesis::{GenesisBuilder, RawGenesisTransaction, GENESIS_DOMAIN_ID}; use serde_json::json; use test_samples::{gen_account_in, ALICE_ID, BOB_ID, CARPENTER_ID}; @@ -92,8 +87,8 @@ pub fn generate_default( genesis_public_key: PublicKey, ) -> color_eyre::Result { let genesis_account_id = AccountId::new(GENESIS_DOMAIN_ID.clone(), genesis_public_key); - let mut meta = Metadata::new(); - meta.insert_with_limits("key".parse()?, "value".to_owned(), Limits::new(1024, 1024))?; + let mut meta = Metadata::default(); + meta.insert("key".parse()?, "value".to_owned()); let mut builder = builder .domain_with_metadata("wonderland".parse()?, meta.clone()) @@ -134,7 +129,7 @@ pub fn generate_default( "wonderland".parse()?, ALICE_ID.clone(), ); - let register_user_metadata_access = Register::role( + let register_user_metadata_access: InstructionBox = Register::role( Role::new("ALICE_METADATA_ACCESS".parse()?) .add_permission(Permission::new( "CanSetKeyValueInAccount".parse()?, @@ -147,62 +142,6 @@ pub fn generate_default( ) .into(); - let parameter_defaults = ParametersBuilder::new() - .add_parameter( - MAX_TRANSACTIONS_IN_BLOCK, - Numeric::new(chain_wide_defaults::MAX_TXS.get().into(), 0), - )? - .add_parameter( - BLOCK_TIME, - Numeric::new(chain_wide_defaults::BLOCK_TIME.as_millis(), 0), - )? - .add_parameter( - COMMIT_TIME_LIMIT, - Numeric::new(chain_wide_defaults::COMMIT_TIME.as_millis(), 0), - )? - .add_parameter(TRANSACTION_LIMITS, chain_wide_defaults::TRANSACTION_LIMITS)? - .add_parameter( - WSV_DOMAIN_METADATA_LIMITS, - chain_wide_defaults::METADATA_LIMITS, - )? - .add_parameter( - WSV_ASSET_DEFINITION_METADATA_LIMITS, - chain_wide_defaults::METADATA_LIMITS, - )? - .add_parameter( - WSV_ACCOUNT_METADATA_LIMITS, - chain_wide_defaults::METADATA_LIMITS, - )? - .add_parameter( - WSV_ASSET_METADATA_LIMITS, - chain_wide_defaults::METADATA_LIMITS, - )? - .add_parameter( - WSV_TRIGGER_METADATA_LIMITS, - chain_wide_defaults::METADATA_LIMITS, - )? - .add_parameter( - WSV_IDENT_LENGTH_LIMITS, - chain_wide_defaults::IDENT_LENGTH_LIMITS, - )? - .add_parameter( - EXECUTOR_FUEL_LIMIT, - Numeric::new(chain_wide_defaults::WASM_FUEL_LIMIT.into(), 0), - )? - .add_parameter( - EXECUTOR_MAX_MEMORY, - Numeric::new(chain_wide_defaults::WASM_MAX_MEMORY.get().into(), 0), - )? - .add_parameter( - WASM_FUEL_LIMIT, - Numeric::new(chain_wide_defaults::WASM_FUEL_LIMIT.into(), 0), - )? - .add_parameter( - WASM_MAX_MEMORY, - Numeric::new(chain_wide_defaults::WASM_MAX_MEMORY.get().into(), 0), - )? - .into_create_parameters(); - for isi in [ mint.into(), mint_cabbage.into(), @@ -211,7 +150,6 @@ pub fn generate_default( grant_permission_to_set_parameters.into(), ] .into_iter() - .chain(parameter_defaults.into_iter()) .chain(std::iter::once(register_user_metadata_access)) { builder = builder.append_instruction(isi); diff --git a/tools/parity_scale_cli/samples/trigger.bin b/tools/parity_scale_cli/samples/trigger.bin index c6493efbb4f..d46095a94fd 100644 Binary files a/tools/parity_scale_cli/samples/trigger.bin and b/tools/parity_scale_cli/samples/trigger.bin differ diff --git a/tools/parity_scale_cli/src/main.rs b/tools/parity_scale_cli/src/main.rs index 1ff425768d1..9319362a3b0 100644 --- a/tools/parity_scale_cli/src/main.rs +++ b/tools/parity_scale_cli/src/main.rs @@ -313,13 +313,11 @@ mod tests { #[test] fn decode_account_sample() { - let limits = MetadataLimits::new(256, 256); - let mut metadata = Metadata::new(); + let mut metadata = Metadata::default(); metadata - .insert_with_limits( + .insert( "hat".parse().expect("Valid"), "white".parse::().unwrap(), - limits, ) .expect("Valid"); let account = Account::new(ALICE_ID.clone()).with_metadata(metadata); @@ -329,10 +327,9 @@ mod tests { #[test] fn decode_domain_sample() { - let limits = MetadataLimits::new(256, 256); - let mut metadata = Metadata::new(); + let mut metadata = Metadata::default(); metadata - .insert_with_limits("Is_Jabberwocky_alive".parse().expect("Valid"), true, limits) + .insert("Is_Jabberwocky_alive".parse().expect("Valid"), true) .expect("Valid"); let domain = Domain::new("wonderland".parse().expect("Valid")) .with_logo( diff --git a/torii/src/routing.rs b/torii/src/routing.rs index 87c2381673e..10ba3dde66c 100644 --- a/torii/src/routing.rs +++ b/torii/src/routing.rs @@ -52,7 +52,7 @@ pub async fn handle_transaction( transaction: SignedTransaction, ) -> Result { let state_view = state.view(); - let transaction_limits = state_view.config.transaction_limits; + let transaction_limits = state_view.world().parameters().transaction_limits; let transaction = AcceptedTransaction::accept(transaction, &chain_id, transaction_limits) .map_err(Error::AcceptTransaction)?; queue