diff --git a/contracts/stake/tests/partial_stake.rs b/contracts/stake/tests/partial_stake.rs index e4759b8679..c45b5c1bfa 100644 --- a/contracts/stake/tests/partial_stake.rs +++ b/contracts/stake/tests/partial_stake.rs @@ -10,7 +10,9 @@ use dusk_core::signatures::bls::{ }; use dusk_core::stake::{Reward, RewardReason, EPOCH, STAKE_CONTRACT}; use dusk_core::transfer::TRANSFER_CONTRACT; -use dusk_vm::{execute, ContractData, Error as VMError, Session, VM}; +use dusk_vm::{ + execute, ContractData, Error as VMError, ExecutionConfig, Session, VM, +}; use rand::rngs::StdRng; use rand::SeedableRng; use wallet_core::transaction::{ @@ -26,6 +28,8 @@ const GENESIS_VALUE: u64 = dusk(1_000_000.0); const STAKE_VALUE: u64 = GENESIS_VALUE / 2; const GENESIS_NONCE: u64 = 0; +const NO_CONFIG: ExecutionConfig = ExecutionConfig::DEFAULT; + #[test] fn stake() -> Result<(), VMError> { // ------ @@ -59,7 +63,7 @@ fn stake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 1st stake transaction let gas_spent_1 = receipt.gas_spent; @@ -87,7 +91,7 @@ fn stake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 2nd stake transaction let gas_spent_2 = receipt.gas_spent; @@ -121,7 +125,7 @@ fn stake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 3rd stake transaction let gas_spent_3 = receipt.gas_spent; @@ -156,7 +160,7 @@ fn stake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - assert!(execute(&mut session, &tx, 0, 0, 0).is_err()); + assert!(execute(&mut session, &tx, &NO_CONFIG).is_err()); Ok(()) } @@ -190,7 +194,7 @@ fn unstake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; let mut moonlight_balance = GENESIS_VALUE - STAKE_VALUE - receipt.gas_spent; assert_moonlight(&mut session, &moonlight_pk, moonlight_balance, nonce); @@ -212,7 +216,7 @@ fn unstake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 1st unstake transaction let gas_spent_1 = receipt.gas_spent; @@ -242,7 +246,7 @@ fn unstake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; total_stake = STAKE_VALUE; let mut locked = unstake_1 / 10; assert_stake(&mut session, &stake_pk, total_stake, locked, 0); @@ -268,7 +272,7 @@ fn unstake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 2nd unstake transaction let gas_spent_2 = receipt.gas_spent; @@ -306,7 +310,7 @@ fn unstake() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 3rd unstake transaction let gas_spent_3 = receipt.gas_spent; @@ -349,7 +353,7 @@ fn withdraw_reward() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; let mut moonlight_balance = GENESIS_VALUE - STAKE_VALUE - receipt.gas_spent; assert_moonlight(&mut session, &moonlight_pk, moonlight_balance, nonce); // add a reward to the staked key @@ -374,7 +378,7 @@ fn withdraw_reward() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 1st reward withdrawal let gas_spent_1 = receipt.gas_spent; @@ -409,7 +413,7 @@ fn withdraw_reward() -> Result<(), VMError> { CHAIN_ID, ) .expect("tx creation should pass"); - let receipt = execute(&mut session, &tx, 0, 0, 0)?; + let receipt = execute(&mut session, &tx, &NO_CONFIG)?; // verify 1st reward withdrawal let gas_spent_2 = receipt.gas_spent; diff --git a/contracts/stake/tests/stake.rs b/contracts/stake/tests/stake.rs index 18ba44bc02..2e5798be1e 100644 --- a/contracts/stake/tests/stake.rs +++ b/contracts/stake/tests/stake.rs @@ -19,7 +19,7 @@ use dusk_core::transfer::withdraw::{ Withdraw, WithdrawReceiver, WithdrawReplayToken, }; use dusk_core::{dusk, JubJubScalar}; -use dusk_vm::{execute, VM}; +use dusk_vm::{execute, ExecutionConfig, VM}; use ff::Field; use rand::rngs::StdRng; use rand::SeedableRng; @@ -34,6 +34,8 @@ use crate::common::utils::*; const GENESIS_VALUE: u64 = dusk(1_000_000.0); const INITIAL_STAKE: u64 = GENESIS_VALUE / 2; +const NO_CONFIG: ExecutionConfig = ExecutionConfig::DEFAULT; + #[test] fn stake_withdraw_unstake() { // ------ @@ -85,7 +87,7 @@ fn stake_withdraw_unstake() { contract_call, ); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing TX should succeed"); let gas_spent = receipt.gas_spent; @@ -181,7 +183,7 @@ fn stake_withdraw_unstake() { .session(base, CHAIN_ID, 2) .expect("Instantiating new session should succeed"); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing TX should succeed"); let gas_spent = receipt.gas_spent; @@ -278,7 +280,7 @@ fn stake_withdraw_unstake() { .session(base, CHAIN_ID, 3) .expect("Instantiating new session should succeed"); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing TX should succeed"); update_root(&mut session).expect("Updating the root should succeed"); diff --git a/contracts/transfer/tests/moonlight.rs b/contracts/transfer/tests/moonlight.rs index b2ab55c4fa..6398913541 100644 --- a/contracts/transfer/tests/moonlight.rs +++ b/contracts/transfer/tests/moonlight.rs @@ -21,7 +21,7 @@ use dusk_core::transfer::{ ContractToAccount, ContractToContract, Transaction, TRANSFER_CONTRACT, }; use dusk_core::{dusk, JubJubScalar, LUX}; -use dusk_vm::{execute, ContractData, Session, VM}; +use dusk_vm::{execute, ContractData, ExecutionConfig, Session, VM}; use ff::Field; use rand::rngs::StdRng; use rand::SeedableRng; @@ -52,6 +52,8 @@ const BOB_ID: ContractId = { const OWNER: [u8; 32] = [0; 32]; const CHAIN_ID: u8 = 0xFA; +const NO_CONFIG: ExecutionConfig = ExecutionConfig::DEFAULT; + /// Instantiate the virtual machine with the transfer contract deployed, with a /// moonlight account owning the `MOONLIGHT_GENESIS_VALUE` and alice and bob /// contracts deployed with alice contract owning `ALICE_GENESIS_VALUE`. @@ -183,7 +185,7 @@ fn transfer() { ) .expect("Creating moonlight transaction should succeed"); - let gas_spent = execute(session, &transaction, 0, 0, 0) + let gas_spent = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed") .gas_spent; @@ -248,7 +250,7 @@ fn transfer_with_refund() { .into(); let max_gas = GAS_LIMIT * LUX; - let gas_spent = execute(session, &transaction, 0, 0, 0) + let gas_spent = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed") .gas_spent; let gas_refund = max_gas - gas_spent; @@ -313,7 +315,7 @@ fn transfer_gas_fails() { ) .expect("Creating moonlight transaction should succeed"); - let result = execute(session, &transaction, 0, 0, 0); + let result = execute(session, &transaction, &NO_CONFIG); assert!( result.is_err(), @@ -365,7 +367,7 @@ fn alice_ping() { ) .expect("Creating moonlight transaction should succeed"); - let gas_spent = execute(session, &transaction, 0, 0, 0) + let gas_spent = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed") .gas_spent; @@ -446,7 +448,7 @@ fn convert_to_phoenix() { ) .expect("Creating moonlight transaction should succeed"); - let gas_spent = execute(&mut session, &tx, 0, 0, 0) + let gas_spent = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing transaction should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -566,7 +568,7 @@ fn convert_to_moonlight_fails() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing TX should succeed"); // check that the transaction execution panicked with the correct message @@ -672,7 +674,7 @@ fn convert_wrong_contract_targeted() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing transaction should succeed"); update_root(session).expect("Updating the root should succeed"); @@ -744,7 +746,7 @@ fn contract_to_contract() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(session, &transaction, 0, 0, 0) + let receipt = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; @@ -811,7 +813,7 @@ fn contract_to_account() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(session, &transaction, 0, 0, 0) + let receipt = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; @@ -875,7 +877,7 @@ fn contract_to_account_insufficient_funds() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(session, &transaction, 0, 0, 0) + let receipt = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; @@ -946,7 +948,7 @@ fn contract_to_account_direct_call() { ) .expect("Creating moonlight transaction should succeed"); - let receipt = execute(session, &transaction, 0, 0, 0) + let receipt = execute(session, &transaction, &NO_CONFIG) .expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; diff --git a/contracts/transfer/tests/phoenix.rs b/contracts/transfer/tests/phoenix.rs index e481c57164..3e2b187f88 100644 --- a/contracts/transfer/tests/phoenix.rs +++ b/contracts/transfer/tests/phoenix.rs @@ -27,7 +27,9 @@ use dusk_core::transfer::{ ContractToAccount, ContractToContract, Transaction, TRANSFER_CONTRACT, }; use dusk_core::{BlsScalar, JubJubScalar, LUX}; -use dusk_vm::{execute, ContractData, Error as VMError, Session, VM}; +use dusk_vm::{ + execute, ContractData, Error as VMError, ExecutionConfig, Session, VM, +}; use ff::Field; use rand::rngs::StdRng; use rand::{CryptoRng, RngCore, SeedableRng}; @@ -59,6 +61,8 @@ const BOB_ID: ContractId = { const OWNER: [u8; 32] = [0; 32]; const CHAIN_ID: u8 = 0xFA; +const NO_CONFIG: ExecutionConfig = ExecutionConfig::DEFAULT; + /// Instantiate the virtual machine with the transfer contract deployed, and the /// notes tree populated with `N` notes, each carrying `PHOENIX_GENESIS_VALUE / /// N`, all owned by the given public key, and alice and bob contracts deployed @@ -252,7 +256,7 @@ fn transfer_1_2() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -359,7 +363,7 @@ fn transfer_2_2() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -467,7 +471,7 @@ fn transfer_3_2() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -575,7 +579,7 @@ fn transfer_4_2() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -679,7 +683,7 @@ fn transfer_gas_fails() { let total_num_notes_before_tx = num_notes(session).expect("Getting num_notes should succeed"); - let result = execute(session, &tx, 0, 0, 0); + let result = execute(session, &tx, &NO_CONFIG); assert!( result.is_err(), @@ -750,7 +754,7 @@ fn alice_ping() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -820,7 +824,7 @@ fn contract_deposit() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -928,7 +932,7 @@ fn contract_withdraw() { contract_call, ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -1055,7 +1059,7 @@ fn convert_to_phoenix_fails() { ); let receipt = - execute(session, &tx, 0, 0, 0).expect("Executing TX should succeed"); + execute(session, &tx, &NO_CONFIG).expect("Executing TX should succeed"); // check that the transaction execution panicked with the correct message assert!(receipt.data.is_err()); @@ -1175,7 +1179,7 @@ fn convert_to_moonlight() { Some(contract_call), ); - let gas_spent = execute(session, &tx, 0, 0, 0) + let gas_spent = execute(session, &tx, &NO_CONFIG) .expect("Executing TX should succeed") .gas_spent; update_root(session).expect("Updating the root should succeed"); @@ -1285,7 +1289,7 @@ fn convert_wrong_contract_targeted() { Some(contract_call), ); - let receipt = execute(&mut session, &tx, 0, 0, 0) + let receipt = execute(&mut session, &tx, &NO_CONFIG) .expect("Executing transaction should succeed"); update_root(session).expect("Updating the root should succeed"); @@ -1377,7 +1381,7 @@ fn contract_to_contract() { ); let receipt = - execute(session, &tx, 0, 0, 0).expect("Transaction should succeed"); + execute(session, &tx, &NO_CONFIG).expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; println!("CONTRACT TO CONTRACT: {gas_spent} gas"); @@ -1471,7 +1475,7 @@ fn contract_to_account() { ); let receipt = - execute(session, &tx, 0, 0, 0).expect("Transaction should succeed"); + execute(session, &tx, &NO_CONFIG).expect("Transaction should succeed"); let gas_spent = receipt.gas_spent; println!("CONTRACT TO ACCOUNT: {gas_spent} gas"); diff --git a/rusk/benches/block_ingestion.rs b/rusk/benches/block_ingestion.rs index 0afabed639..683a10cf7c 100644 --- a/rusk/benches/block_ingestion.rs +++ b/rusk/benches/block_ingestion.rs @@ -23,13 +23,15 @@ use node_data::ledger::Transaction; use rand::prelude::StdRng; use rand::seq::SliceRandom; use rand::SeedableRng; -use rusk::Rusk; -use rusk::DUSK_CONSENSUS_KEY; +use rusk::node::RuskVmConfig; +use rusk::{Rusk, DUSK_CONSENSUS_KEY}; use tempfile::tempdir; use common::state::new_state; const BLOCK_GAS_LIMIT: u64 = 1_000_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); fn load_phoenix_txs() -> Vec { // The file "phoenix-txs" can be generated using @@ -158,7 +160,7 @@ pub fn accept_benchmark(c: &mut Criterion) { let snapshot = toml::from_str(include_str!("../tests/config/bench.toml")) .expect("Cannot deserialize config"); - let rusk = new_state(&tmp, &snapshot, BLOCK_GAS_LIMIT) + let rusk = new_state(&tmp, &snapshot, VM_CONFIG) .expect("Creating state should work"); let phoenix_txs = load_phoenix_txs(); diff --git a/rusk/src/bin/config/chain.rs b/rusk/src/bin/config/chain.rs index 1e69ac6175..4195793451 100644 --- a/rusk/src/bin/config/chain.rs +++ b/rusk/src/bin/config/chain.rs @@ -12,8 +12,6 @@ use std::{ use node::database::DatabaseOptions; use serde::{Deserialize, Serialize}; -pub const DEFAULT_BLOCK_GAS_LIMIT: u64 = 5 * 1_000_000_000; - use crate::args::Args; #[derive(Serialize, Deserialize, Clone, Default)] @@ -106,8 +104,8 @@ impl ChainConfig { self.max_queue_size.unwrap_or(10_000) } - pub(crate) fn block_gas_limit(&self) -> u64 { - self.block_gas_limit.unwrap_or(DEFAULT_BLOCK_GAS_LIMIT) + pub(crate) fn block_gas_limit(&self) -> Option { + self.block_gas_limit } pub(crate) fn genesis_timestamp(&self) -> u64 { diff --git a/rusk/src/lib/builder/node.rs b/rusk/src/lib/builder/node.rs index 31e2e47ac6..6612cb52c6 100644 --- a/rusk/src/lib/builder/node.rs +++ b/rusk/src/lib/builder/node.rs @@ -25,7 +25,7 @@ use tracing::info; use {node::archive::Archive, node::archive::ArchivistSrv}; use crate::http::{DataSources, HttpServer, HttpServerConfig}; -use crate::node::{ChainEventStreamer, RuskNode, Services}; +use crate::node::{ChainEventStreamer, RuskNode, RuskVmConfig, Services}; use crate::{Rusk, VERSION}; #[derive(Default)] @@ -39,13 +39,8 @@ pub struct RuskNodeBuilder { db_options: DatabaseOptions, max_chain_queue_size: usize, genesis_timestamp: u64, - - generation_timeout: Option, - gas_per_deploy_byte: Option, - min_deployment_gas_price: Option, + vm_config: RuskVmConfig, min_gas_limit: Option, - min_deploy_points: Option, - block_gas_limit: u64, feeder_call_gas: u64, state_dir: PathBuf, @@ -54,11 +49,7 @@ pub struct RuskNodeBuilder { command_revert: bool, } -const DEFAULT_GAS_PER_DEPLOY_BYTE: u64 = 100; -const DEFAULT_MIN_DEPLOYMENT_GAS_PRICE: u64 = 2000; const DEFAULT_MIN_GAS_LIMIT: u64 = 75000; -const DEFAULT_MIN_DEPLOY_POINTS: u64 = 5_000_000; - impl RuskNodeBuilder { pub fn with_consensus_keys(mut self, consensus_keys_path: String) -> Self { self.consensus_keys_path = consensus_keys_path; @@ -119,7 +110,7 @@ impl RuskNodeBuilder { mut self, generation_timeout: Option, ) -> Self { - self.generation_timeout = generation_timeout; + self.vm_config.generation_timeout = generation_timeout; self } @@ -127,7 +118,9 @@ impl RuskNodeBuilder { mut self, gas_per_deploy_byte: Option, ) -> Self { - self.gas_per_deploy_byte = gas_per_deploy_byte; + if let Some(gas_per_deploy_byte) = gas_per_deploy_byte { + self.vm_config.gas_per_deploy_byte = gas_per_deploy_byte; + } self } @@ -135,7 +128,9 @@ impl RuskNodeBuilder { mut self, min_deployment_gas_price: Option, ) -> Self { - self.min_deployment_gas_price = min_deployment_gas_price; + if let Some(min_deploy_gas_price) = min_deployment_gas_price { + self.vm_config.min_deploy_gas_price = min_deploy_gas_price; + } self } @@ -148,12 +143,19 @@ impl RuskNodeBuilder { mut self, min_deploy_points: Option, ) -> Self { - self.min_deploy_points = min_deploy_points; + if let Some(min_deploy_points) = min_deploy_points { + self.vm_config.min_deploy_points = min_deploy_points; + } self } - pub fn with_block_gas_limit(mut self, block_gas_limit: u64) -> Self { - self.block_gas_limit = block_gas_limit; + pub fn with_block_gas_limit( + mut self, + block_gas_limit: Option, + ) -> Self { + if let Some(block_gas_limit) = block_gas_limit { + self.vm_config.block_gas_limit = block_gas_limit; + } self } @@ -190,25 +192,13 @@ impl RuskNodeBuilder { #[cfg(feature = "archive")] let (archive_sender, archive_receiver) = mpsc::channel(10000); - let gas_per_deploy_byte = self - .gas_per_deploy_byte - .unwrap_or(DEFAULT_GAS_PER_DEPLOY_BYTE); - let min_deployment_gas_price = self - .min_deployment_gas_price - .unwrap_or(DEFAULT_MIN_DEPLOYMENT_GAS_PRICE); let min_gas_limit = self.min_gas_limit.unwrap_or(DEFAULT_MIN_GAS_LIMIT); - let min_deploy_points = - self.min_deploy_points.unwrap_or(DEFAULT_MIN_DEPLOY_POINTS); let rusk = Rusk::new( self.state_dir, self.kadcast.kadcast_id.unwrap_or_default(), - self.generation_timeout, - gas_per_deploy_byte, - min_deployment_gas_price, + self.vm_config, min_gas_limit, - min_deploy_points, - self.block_gas_limit, self.feeder_call_gas, rues_sender.clone(), #[cfg(feature = "archive")] diff --git a/rusk/src/lib/node.rs b/rusk/src/lib/node.rs index 2cf27a4bb7..1dc636a2e0 100644 --- a/rusk/src/lib/node.rs +++ b/rusk/src/lib/node.rs @@ -10,7 +10,6 @@ mod vm; use std::path::PathBuf; use std::sync::Arc; -use std::time::Duration; use dusk_core::{dusk, Dusk}; @@ -20,6 +19,7 @@ use node::network::Kadcast; use node::LongLivedService; use parking_lot::RwLock; use tokio::sync::broadcast; +pub use vm::RuskVmConfig; use crate::http::RuesEvent; pub(crate) use events::ChainEventStreamer; @@ -40,13 +40,9 @@ pub struct Rusk { pub(crate) vm: Arc, dir: PathBuf, pub(crate) chain_id: u8, - pub(crate) generation_timeout: Option, - pub(crate) gas_per_deploy_byte: u64, - pub(crate) min_deployment_gas_price: u64, + pub(crate) vm_config: RuskVmConfig, pub(crate) min_gas_limit: u64, - pub(crate) min_deploy_points: u64, pub(crate) feeder_gas_limit: u64, - pub(crate) block_gas_limit: u64, pub(crate) event_sender: broadcast::Sender, #[cfg(feature = "archive")] pub(crate) archive_sender: mpsc::Sender, diff --git a/rusk/src/lib/node/rusk.rs b/rusk/src/lib/node/rusk.rs index 17041d80ca..44e5b128c8 100644 --- a/rusk/src/lib/node/rusk.rs +++ b/rusk/src/lib/node/rusk.rs @@ -6,7 +6,7 @@ use std::path::Path; use std::sync::{mpsc, Arc}; -use std::time::{Duration, Instant}; +use std::time::Instant; use std::{fs, io}; use dusk_bytes::Serializable; @@ -25,16 +25,20 @@ use dusk_core::transfer::{ moonlight::AccountData, PANIC_NONCE_NOT_READY, TRANSFER_CONTRACT, }; use dusk_core::{BlsScalar, Dusk}; -use dusk_vm::{execute, CallReceipt, Error as VMError, Session, VM}; +use dusk_vm::{ + execute, CallReceipt, Error as VMError, ExecutionConfig, Session, VM, +}; use node_data::events::contract::{ContractEvent, ContractTxEvent}; use node_data::ledger::{Hash, Slash, SpentTransaction, Transaction}; use parking_lot::RwLock; use rusk_profile::to_rusk_state_id_path; use tokio::sync::broadcast; use tracing::info; + #[cfg(feature = "archive")] use {node_data::archive::ArchivalData, tokio::sync::mpsc::Sender}; +use super::RuskVmConfig; use crate::bloom::Bloom; use crate::http::RuesEvent; use crate::node::{coinbase_value, Rusk, RuskTip}; @@ -42,16 +46,11 @@ use crate::Error::InvalidCreditsCount; use crate::{Error, Result, DUSK_CONSENSUS_KEY}; impl Rusk { - #[allow(clippy::too_many_arguments)] pub fn new>( dir: P, chain_id: u8, - generation_timeout: Option, - gas_per_deploy_byte: u64, - min_deployment_gas_price: u64, + vm_config: RuskVmConfig, min_gas_limit: u64, - min_deploy_points: u64, - block_gas_limit: u64, feeder_gas_limit: u64, event_sender: broadcast::Sender, #[cfg(feature = "archive")] archive_sender: Sender, @@ -87,16 +86,12 @@ impl Rusk { vm, dir: dir.into(), chain_id, - generation_timeout, - gas_per_deploy_byte, - min_deployment_gas_price, + vm_config, min_gas_limit, - min_deploy_points, feeder_gas_limit, event_sender, #[cfg(feature = "archive")] archive_sender, - block_gas_limit, }) } @@ -109,7 +104,7 @@ impl Rusk { let started = Instant::now(); let block_height = params.round; - let block_gas_limit = self.block_gas_limit; + let block_gas_limit = self.vm_config.block_gas_limit; let generator = params.generator_pubkey.inner(); let to_slash = params.to_slash.clone(); let prev_state_root = params.prev_state_root; @@ -128,11 +123,13 @@ impl Rusk { let mut event_bloom = Bloom::new(); + let execution_config = self.vm_config.to_execution_config(); + // We always write the faults len in a u32 let mut size_left = params.max_txs_bytes - u32::SIZE; for unspent_tx in txs { - if let Some(timeout) = self.generation_timeout { + if let Some(timeout) = self.vm_config.generation_timeout { if started.elapsed() > timeout { info!("execute_transactions timeout triggered {timeout:?}"); break; @@ -158,13 +155,7 @@ impl Rusk { continue; } - match execute( - &mut session, - &unspent_tx.inner, - self.gas_per_deploy_byte, - self.min_deploy_points, - self.min_deployment_gas_price, - ) { + match execute(&mut session, &unspent_tx.inner, &execution_config) { Ok(receipt) => { let gas_spent = receipt.gas_spent; @@ -182,9 +173,7 @@ impl Rusk { let _ = execute( &mut session, &spent_tx.inner.inner, - self.gas_per_deploy_byte, - self.min_deploy_points, - self.min_deployment_gas_price, + &execution_config, ); } @@ -263,6 +252,7 @@ impl Rusk { voters: &[Voter], ) -> Result<(Vec, VerificationOutput)> { let session = self.new_block_session(block_height, prev_commit)?; + let execution_config = self.vm_config.to_execution_config(); accept( session, @@ -273,9 +263,7 @@ impl Rusk { txs, slashing, voters, - self.gas_per_deploy_byte, - self.min_deploy_points, - self.min_deployment_gas_price, + &execution_config, ) .map(|(a, b, _, _)| (a, b)) } @@ -304,6 +292,8 @@ impl Rusk { )> { let session = self.new_block_session(block_height, prev_commit)?; + let execution_config = self.vm_config.to_execution_config(); + let (spent_txs, verification_output, session, events) = accept( session, block_height, @@ -313,9 +303,7 @@ impl Rusk { &txs[..], slashing, voters, - self.gas_per_deploy_byte, - self.min_deploy_points, - self.min_deployment_gas_price, + &execution_config, )?; if let Some(expected_verification) = consistency_check { @@ -551,10 +539,6 @@ impl Rusk { } Ok(()) } - - pub(crate) fn block_gas_limit(&self) -> u64 { - self.block_gas_limit - } } #[allow(clippy::too_many_arguments)] @@ -567,9 +551,7 @@ fn accept( txs: &[Transaction], slashing: Vec, voters: &[Voter], - gas_per_deploy_byte: u64, - min_deploy_points: u64, - min_deployment_gas_price: u64, + execution_config: &ExecutionConfig, ) -> Result<( Vec, VerificationOutput, @@ -589,13 +571,7 @@ fn accept( for unspent_tx in txs { let tx = &unspent_tx.inner; let tx_id = unspent_tx.id(); - let receipt = execute( - &mut session, - tx, - gas_per_deploy_byte, - min_deploy_points, - min_deployment_gas_price, - )?; + let receipt = execute(&mut session, tx, execution_config)?; event_bloom.add_events(&receipt.events); diff --git a/rusk/src/lib/node/vm.rs b/rusk/src/lib/node/vm.rs index a15ddd8142..c64c83435c 100644 --- a/rusk/src/lib/node/vm.rs +++ b/rusk/src/lib/node/vm.rs @@ -4,6 +4,7 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +mod config; mod query; use dusk_consensus::errors::VstError; @@ -23,6 +24,7 @@ use node_data::bls::PublicKey; use node_data::ledger::{Block, Slash, SpentTransaction, Transaction}; use super::Rusk; +pub use config::Config as RuskVmConfig; impl VMExecution for Rusk { fn execute_state_transition>( @@ -265,15 +267,15 @@ impl VMExecution for Rusk { } fn get_block_gas_limit(&self) -> u64 { - self.block_gas_limit() + self.vm_config.block_gas_limit } fn gas_per_deploy_byte(&self) -> u64 { - self.gas_per_deploy_byte + self.vm_config.gas_per_deploy_byte } fn min_deployment_gas_price(&self) -> u64 { - self.min_deployment_gas_price + self.vm_config.min_deploy_gas_price } fn min_gas_limit(&self) -> u64 { @@ -281,7 +283,7 @@ impl VMExecution for Rusk { } fn min_deploy_points(&self) -> u64 { - self.min_deploy_points + self.vm_config.min_deploy_points } } diff --git a/rusk/src/lib/node/vm/config.rs b/rusk/src/lib/node/vm/config.rs new file mode 100644 index 0000000000..70012a6605 --- /dev/null +++ b/rusk/src/lib/node/vm/config.rs @@ -0,0 +1,100 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +use std::time::Duration; + +use dusk_vm::ExecutionConfig; + +const DEFAULT_GAS_PER_DEPLOY_BYTE: u64 = 100; +const DEFAULT_MIN_DEPLOYMENT_GAS_PRICE: u64 = 2000; +const DEFAULT_MIN_DEPLOY_POINTS: u64 = 5_000_000; +const DEFAULT_BLOCK_GAS_LIMIT: u64 = 3 * 1_000_000_000; + +/// Configuration for the execution of a transaction. +#[derive(Debug, Clone)] +pub struct Config { + /// The amount of gas points charged for each byte in a contract-deployment + /// bytecode. + pub gas_per_deploy_byte: u64, + /// The minimum gas points charged for a contract deployment. + pub min_deploy_points: u64, + /// The minimum gas price set for a contract deployment + pub min_deploy_gas_price: u64, + /// The maximum amount of gas points that can be used in a block. + pub block_gas_limit: u64, + /// The timeout for a candidate block generation. + pub generation_timeout: Option, +} + +impl Default for Config { + fn default() -> Self { + Self::new() + } +} + +impl Config { + pub const fn new() -> Self { + Self { + gas_per_deploy_byte: DEFAULT_GAS_PER_DEPLOY_BYTE, + min_deploy_gas_price: DEFAULT_MIN_DEPLOYMENT_GAS_PRICE, + min_deploy_points: DEFAULT_MIN_DEPLOY_POINTS, + block_gas_limit: DEFAULT_BLOCK_GAS_LIMIT, + generation_timeout: None, + } + } + + /// Set the maximum amount of gas points that can be used in a block. + pub const fn with_block_gas_limit(mut self, block_gas_limit: u64) -> Self { + self.block_gas_limit = block_gas_limit; + self + } + + /// Set the amount of gas points charged for each byte in a + /// contract-deployment + pub const fn with_gas_per_deploy_byte( + mut self, + gas_per_deploy_byte: u64, + ) -> Self { + self.gas_per_deploy_byte = gas_per_deploy_byte; + self + } + + /// Set the minimum amount of gas points charged for a contract deployment. + pub const fn with_min_deploy_points( + mut self, + min_deploy_points: u64, + ) -> Self { + self.min_deploy_points = min_deploy_points; + self + } + + /// Set the minimum gas price set for a contract deployment. + pub const fn with_min_deploy_gas_price( + mut self, + min_deploy_gas_price: u64, + ) -> Self { + self.min_deploy_gas_price = min_deploy_gas_price; + self + } + + /// Set the timeout for a candidate block generation. + pub const fn with_generation_timeout( + mut self, + generation_timeout: Option, + ) -> Self { + self.generation_timeout = generation_timeout; + self + } + + /// Create a new `Config` with the given parameters. + pub fn to_execution_config(&self) -> ExecutionConfig { + ExecutionConfig { + gas_per_deploy_byte: self.gas_per_deploy_byte, + min_deploy_points: self.min_deploy_points, + min_deploy_gas_price: self.min_deploy_gas_price, + } + } +} diff --git a/rusk/tests/common/state.rs b/rusk/tests/common/state.rs index fd5826fa94..aaab1526a5 100644 --- a/rusk/tests/common/state.rs +++ b/rusk/tests/common/state.rs @@ -8,6 +8,7 @@ use std::{path::Path, usize}; use dusk_bytes::Serializable; use node::vm::VMExecution; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk, DUSK_CONSENSUS_KEY}; use rusk_recovery_tools::state::{self, Snapshot}; @@ -30,25 +31,23 @@ use tokio::sync::broadcast; use tracing::info; const CHAIN_ID: u8 = 0xFA; -pub const DEFAULT_GAS_PER_DEPLOY_BYTE: u64 = 100; -pub const DEFAULT_MIN_DEPLOYMENT_GAS_PRICE: u64 = 2000; +pub const DEFAULT_VM_CONFIG: RuskVmConfig = RuskVmConfig::new(); pub const DEFAULT_MIN_GAS_LIMIT: u64 = 75000; -pub const DEFAULT_MIN_DEPLOY_POINTS: u64 = 5000000; // Creates a Rusk initial state in the given directory pub fn new_state>( dir: P, snapshot: &Snapshot, - block_gas_limit: u64, + vm_config: RuskVmConfig, ) -> Result { - new_state_with_chainid(dir, snapshot, block_gas_limit, CHAIN_ID) + new_state_with_chainid(dir, snapshot, vm_config, CHAIN_ID) } // Creates a Rusk initial state in the given directory pub fn new_state_with_chainid>( dir: P, snapshot: &Snapshot, - block_gas_limit: u64, + vm_config: RuskVmConfig, chain_id: u8, ) -> Result { let dir = dir.as_ref(); @@ -62,12 +61,8 @@ pub fn new_state_with_chainid>( let rusk = Rusk::new( dir, chain_id, - None, - DEFAULT_GAS_PER_DEPLOY_BYTE, - DEFAULT_MIN_DEPLOYMENT_GAS_PRICE, + vm_config, DEFAULT_MIN_GAS_LIMIT, - DEFAULT_MIN_DEPLOY_POINTS, - block_gas_limit, u64::MAX, sender, ) diff --git a/rusk/tests/rusk-state.rs b/rusk/tests/rusk-state.rs index 93b72e9406..e6447e4718 100644 --- a/rusk/tests/rusk-state.rs +++ b/rusk/tests/rusk-state.rs @@ -27,7 +27,7 @@ use ff::Field; use parking_lot::RwLockWriteGuard; use rand::prelude::*; use rand::rngs::StdRng; -use rusk::node::{Rusk, RuskTip}; +use rusk::node::{Rusk, RuskTip, RuskVmConfig}; use rusk::Result; use tempfile::tempdir; use tracing::info; @@ -39,12 +39,15 @@ const CHAIN_ID: u8 = 0xFA; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; const INITIAL_BALANCE: u64 = 10_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); + // Creates the Rusk initial state for the tests below fn initial_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("./config/rusk-state.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } fn leaves_from_height(rusk: &Rusk, height: u64) -> Result> { @@ -185,7 +188,8 @@ async fn generate_phoenix_txs() -> Result<(), Box> { let snapshot = toml::from_str(include_str!("./config/bench.toml")) .expect("Cannot deserialize config"); - let rusk = new_state(&tmp, &snapshot, 100_000_000_000)?; + let vm_config = RuskVmConfig::new().with_block_gas_limit(100_000_000_000); + let rusk = new_state(&tmp, &snapshot, vm_config)?; let cache = Arc::new(std::sync::RwLock::new(std::collections::HashMap::new())); @@ -247,7 +251,8 @@ async fn generate_moonlight_txs() -> Result<(), Box> { let snapshot = toml::from_str(include_str!("./config/bench.toml")) .expect("Cannot deserialize config"); - let rusk = new_state(&tmp, &snapshot, 100_000_000_000)?; + let vm_config = RuskVmConfig::new().with_block_gas_limit(100_000_000_000); + let rusk = new_state(&tmp, &snapshot, vm_config)?; let cache = Arc::new(std::sync::RwLock::new(std::collections::HashMap::new())); diff --git a/rusk/tests/services/contract_deployment.rs b/rusk/tests/services/contract_deployment.rs index 2a4a510e75..7f2d76ecb2 100644 --- a/rusk/tests/services/contract_deployment.rs +++ b/rusk/tests/services/contract_deployment.rs @@ -15,6 +15,7 @@ use dusk_core::transfer::data::{ use dusk_vm::{gen_contract_id, ContractData, Error as VMError, VM}; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk, DUSK_CONSENSUS_KEY}; use rusk_recovery_tools::state; use tempfile::tempdir; @@ -22,11 +23,9 @@ use tokio::sync::broadcast; use tracing::info; use crate::common::logger; -use crate::common::state::DEFAULT_MIN_DEPLOYMENT_GAS_PRICE; -use crate::common::state::DEFAULT_MIN_DEPLOY_POINTS; -use crate::common::state::{generator_procedure, ExecuteResult}; use crate::common::state::{ - DEFAULT_GAS_PER_DEPLOY_BYTE, DEFAULT_MIN_GAS_LIMIT, + generator_procedure, ExecuteResult, DEFAULT_MIN_GAS_LIMIT, + DEFAULT_VM_CONFIG, }; use crate::common::wallet::{ test_wallet as wallet, TestStateClient, TestStore, Wallet, @@ -106,12 +105,8 @@ fn initial_state>(dir: P, deploy_bob: bool) -> Result { let rusk = Rusk::new( dir, CHAIN_ID, - None, - DEFAULT_GAS_PER_DEPLOY_BYTE, - DEFAULT_MIN_DEPLOYMENT_GAS_PRICE, + DEFAULT_VM_CONFIG, DEFAULT_MIN_GAS_LIMIT, - DEFAULT_MIN_DEPLOY_POINTS, - BLOCK_GAS_LIMIT, u64::MAX, sender, ) diff --git a/rusk/tests/services/contract_stake.rs b/rusk/tests/services/contract_stake.rs index 2f137fdf56..f5bde81239 100644 --- a/rusk/tests/services/contract_stake.rs +++ b/rusk/tests/services/contract_stake.rs @@ -17,6 +17,7 @@ use dusk_vm::gen_contract_id; use node_data::ledger::SpentTransaction; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use std::collections::HashMap; use tempfile::tempdir; @@ -30,6 +31,9 @@ use crate::common::*; const BLOCK_HEIGHT: u64 = 1; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); + const GAS_LIMIT: u64 = 10_000_000_000; const GAS_PRICE: u64 = 1; @@ -39,7 +43,7 @@ fn stake_state>(dir: P) -> Result { toml::from_str(include_str!("../config/stake_from_contract.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, u64::MAX) + new_state(dir, &snapshot, VM_CONFIG) } #[tokio::test(flavor = "multi_thread")] diff --git a/rusk/tests/services/conversion.rs b/rusk/tests/services/conversion.rs index b038cc9400..28c6783ede 100644 --- a/rusk/tests/services/conversion.rs +++ b/rusk/tests/services/conversion.rs @@ -11,6 +11,7 @@ use std::sync::{Arc, RwLock}; use node_data::ledger::SpentTransaction; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; @@ -21,6 +22,8 @@ use crate::common::wallet::{ }; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const INITIAL_PHOENIX_BALANCE: u64 = 10_000_000_000; const INITIAL_MOONLIGHT_BALANCE: u64 = 10_000_000_000; @@ -30,7 +33,7 @@ fn initial_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/convert.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } /// Makes a transaction that converts Dusk from Phoenix to Moonlight, and diff --git a/rusk/tests/services/finalization.rs b/rusk/tests/services/finalization.rs index b8d6550921..c83a6fc44a 100644 --- a/rusk/tests/services/finalization.rs +++ b/rusk/tests/services/finalization.rs @@ -6,12 +6,14 @@ use std::path::Path; -use rusk::{Result, Rusk}; +use rusk::{node::RuskVmConfig, Result, Rusk}; use tempfile::tempdir; use crate::common::state::{generator_procedure2, new_state}; const BLOCK_GAS_LIMIT: u64 = 24_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const BLOCKS_NUM: u64 = 10; // Creates the Rusk initial state for the tests below @@ -20,7 +22,7 @@ fn initial_state>(dir: P) -> Result { toml::from_str(include_str!("../config/multi_transfer.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } #[tokio::test(flavor = "multi_thread")] diff --git a/rusk/tests/services/gas_behavior.rs b/rusk/tests/services/gas_behavior.rs index e552f3d983..5596bcc0b6 100644 --- a/rusk/tests/services/gas_behavior.rs +++ b/rusk/tests/services/gas_behavior.rs @@ -14,6 +14,7 @@ use dusk_core::transfer::{ }; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; use tracing::info; @@ -26,6 +27,9 @@ use crate::common::wallet::{ const BLOCK_HEIGHT: u64 = 1; const BLOCK_GAS_LIMIT: u64 = 1_000_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); + const INITIAL_BALANCE: u64 = 10_000_000_000; const GAS_LIMIT_0: u64 = 100_000_000; @@ -38,7 +42,7 @@ fn initial_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/gas-behavior.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } const SENDER_INDEX_0: u8 = 0; diff --git a/rusk/tests/services/mainnet.rs b/rusk/tests/services/mainnet.rs index 77fdcd8fed..99386b9b79 100644 --- a/rusk/tests/services/mainnet.rs +++ b/rusk/tests/services/mainnet.rs @@ -12,6 +12,7 @@ use dusk_core::stake::{StakeData, StakeKeys, STAKE_CONTRACT}; use dusk_core::transfer::moonlight::AccountData; use dusk_core::transfer::phoenix::NoteLeaf; use dusk_core::transfer::TRANSFER_CONTRACT; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; @@ -27,7 +28,7 @@ fn initial_state>(dir: P) -> Result { )) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, u64::MAX) + new_state(dir, &snapshot, RuskVmConfig::default()) } #[tokio::test(flavor = "multi_thread")] diff --git a/rusk/tests/services/moonlight_stake.rs b/rusk/tests/services/moonlight_stake.rs index a4fee5b358..e48a04a756 100644 --- a/rusk/tests/services/moonlight_stake.rs +++ b/rusk/tests/services/moonlight_stake.rs @@ -11,6 +11,7 @@ use dusk_core::stake::DEFAULT_MINIMUM_STAKE; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use std::collections::HashMap; use tempfile::tempdir; @@ -24,6 +25,8 @@ use crate::common::*; const BLOCK_HEIGHT: u64 = 1; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const GAS_LIMIT: u64 = 10_000_000_000; const GAS_PRICE: u64 = 1; @@ -32,7 +35,7 @@ fn stake_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/stake.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } /// Stakes an amount Dusk and produces a block with this single transaction, diff --git a/rusk/tests/services/multi_transfer.rs b/rusk/tests/services/multi_transfer.rs index 689a290a7f..2532738d70 100644 --- a/rusk/tests/services/multi_transfer.rs +++ b/rusk/tests/services/multi_transfer.rs @@ -10,6 +10,7 @@ use std::sync::{Arc, RwLock}; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; use tracing::info; @@ -24,6 +25,9 @@ const BLOCK_HEIGHT: u64 = 1; // This is purposefully chosen to be low to trigger the discarding of a // perfectly good transaction. const BLOCK_GAS_LIMIT: u64 = 24_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); + const GAS_LIMIT: u64 = 12_000_000; // Lowest value for a transfer const INITIAL_BALANCE: u64 = 10_000_000_000; const INITIAL_BALANCE_DEPLOY: u64 = 1_000_000_000_000; @@ -38,7 +42,7 @@ fn initial_state>(dir: P) -> Result { toml::from_str(include_str!("../config/multi_transfer.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } // Creates the Rusk initial state for the tests below @@ -47,7 +51,7 @@ fn initial_state_deploy>(dir: P) -> Result { toml::from_str(include_str!("../config/multi_transfer_deploy.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } /// Executes three different transactions in the same block, expecting only two diff --git a/rusk/tests/services/owner_calls.rs b/rusk/tests/services/owner_calls.rs index adaac088bb..44e7e91f1e 100644 --- a/rusk/tests/services/owner_calls.rs +++ b/rusk/tests/services/owner_calls.rs @@ -27,11 +27,7 @@ use tokio::sync::broadcast; use tracing::info; use crate::common::logger; -use crate::common::state::DEFAULT_MIN_DEPLOYMENT_GAS_PRICE; -use crate::common::state::DEFAULT_MIN_DEPLOY_POINTS; -use crate::common::state::{ - DEFAULT_GAS_PER_DEPLOY_BYTE, DEFAULT_MIN_GAS_LIMIT, -}; +use crate::common::state::{DEFAULT_MIN_GAS_LIMIT, DEFAULT_VM_CONFIG}; use crate::common::wallet::{ test_wallet as wallet, test_wallet::Wallet, TestStateClient, TestStore, }; @@ -83,12 +79,8 @@ fn initial_state>( let rusk = Rusk::new( dir, CHAIN_ID, - None, - DEFAULT_GAS_PER_DEPLOY_BYTE, - DEFAULT_MIN_DEPLOYMENT_GAS_PRICE, + DEFAULT_VM_CONFIG, DEFAULT_MIN_GAS_LIMIT, - DEFAULT_MIN_DEPLOY_POINTS, - BLOCK_GAS_LIMIT, u64::MAX, sender, ) diff --git a/rusk/tests/services/phoenix_stake.rs b/rusk/tests/services/phoenix_stake.rs index f0c3318e4a..c3c5396912 100644 --- a/rusk/tests/services/phoenix_stake.rs +++ b/rusk/tests/services/phoenix_stake.rs @@ -17,6 +17,7 @@ use dusk_core::{ use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use std::collections::HashMap; use tempfile::tempdir; @@ -30,6 +31,8 @@ use crate::common::*; const BLOCK_HEIGHT: u64 = 1; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const GAS_LIMIT: u64 = 10_000_000_000; const GAS_PRICE: u64 = 1; const DEPOSIT: u64 = 0; @@ -39,7 +42,7 @@ fn stake_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/stake.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } // Creates the Rusk initial state for the tests below @@ -47,7 +50,7 @@ fn slash_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/slash.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } /// Stakes an amount Dusk and produces a block with this single transaction, diff --git a/rusk/tests/services/transfer.rs b/rusk/tests/services/transfer.rs index 8655407301..08ebcd8ac3 100644 --- a/rusk/tests/services/transfer.rs +++ b/rusk/tests/services/transfer.rs @@ -11,6 +11,7 @@ use std::sync::{Arc, RwLock}; use node_data::ledger::SpentTransaction; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; use tracing::info; @@ -22,6 +23,8 @@ use crate::common::wallet::{ }; const BLOCK_GAS_LIMIT: u64 = 100_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const INITIAL_BALANCE: u64 = 10_000_000_000; const MAX_NOTES: u64 = 10; @@ -30,7 +33,7 @@ fn initial_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/transfer.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } /// Transacts between two accounts on the in the same wallet and produces a diff --git a/rusk/tests/services/unspendable.rs b/rusk/tests/services/unspendable.rs index 0d425c2697..1ef140c489 100644 --- a/rusk/tests/services/unspendable.rs +++ b/rusk/tests/services/unspendable.rs @@ -14,6 +14,7 @@ use dusk_core::transfer::{ }; use rand::prelude::*; use rand::rngs::StdRng; +use rusk::node::RuskVmConfig; use rusk::{Result, Rusk}; use tempfile::tempdir; use tracing::info; @@ -26,6 +27,8 @@ use crate::common::wallet::{ const BLOCK_HEIGHT: u64 = 1; const BLOCK_GAS_LIMIT: u64 = 1_000_000_000_000; +const VM_CONFIG: RuskVmConfig = + RuskVmConfig::new().with_block_gas_limit(BLOCK_GAS_LIMIT); const INITIAL_BALANCE: u64 = 10_000_000_000; const GAS_LIMIT_0: u64 = 20_000_000; // Enough to spend, but OOG during ICC @@ -39,7 +42,7 @@ fn initial_state>(dir: P) -> Result { let snapshot = toml::from_str(include_str!("../config/unspendable.toml")) .expect("Cannot deserialize config"); - new_state(dir, &snapshot, BLOCK_GAS_LIMIT) + new_state(dir, &snapshot, VM_CONFIG) } const SENDER_INDEX_0: u8 = 0; diff --git a/vm/CHANGELOG.md b/vm/CHANGELOG.md index 5339786846..15e884156a 100644 --- a/vm/CHANGELOG.md +++ b/vm/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Change `execution` module to use `execution::Config` [#3437] + [1.0.0] - 2025-01-23 ### Changed @@ -22,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#3235]: https://github.com/dusk-network/rusk/issues/3235 [#3405]: https://github.com/dusk-network/rusk/issues/3405 +[#3437]: https://github.com/dusk-network/rusk/issues/3437 [Unreleased]: https://github.com/dusk-network/rusk/compare/dusk-vm-1.0.0...HEAD [1.0.0]: https://github.com/dusk-network/rusk/compare/dusk-vm-0.1.0...dusk-vm-1.0.0 diff --git a/vm/src/execute.rs b/vm/src/execute.rs index 0ea09ee9f1..09659a9c5d 100644 --- a/vm/src/execute.rs +++ b/vm/src/execute.rs @@ -4,6 +4,8 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +mod config; + use blake2b_simd::Params; use dusk_core::abi::{ContractError, ContractId, CONTRACT_ID_BYTES}; use dusk_core::transfer::{ @@ -11,6 +13,8 @@ use dusk_core::transfer::{ }; use piecrust::{CallReceipt, Error, Session}; +pub use config::Config; + /// Executes a transaction in the provided session. /// /// This function processes the transaction, invoking smart contracts or @@ -53,25 +57,18 @@ use piecrust::{CallReceipt, Error, Session}; /// # Arguments /// * `session` - A mutable reference to the session executing the transaction. /// * `tx` - The transaction to execute. -/// * `gas_per_deploy_byte` - The amount of gas points charged for each byte in -/// a contract-deployment bytecode. -/// * `min_deploy_points` - The minimum gas points charged for a contract -/// deployment. -/// * `min_deploy_gas_price` - The minimum gas price set for a contract -/// deployment +/// * `config` - The configuration for the execution of the transaction. /// /// # Returns /// A result indicating success or failure. pub fn execute( session: &mut Session, tx: &Transaction, - gas_per_deploy_byte: u64, - min_deploy_points: u64, - min_deploy_gas_price: u64, + config: &Config, ) -> Result, ContractError>>, Error> { // Transaction will be discarded if it is a deployment transaction // with gas limit smaller than deploy charge. - deploy_check(tx, gas_per_deploy_byte, min_deploy_gas_price)?; + deploy_check(tx, config)?; // Spend the inputs and execute the call. If this errors the transaction is // unspendable. @@ -83,13 +80,7 @@ pub fn execute( )?; // Deploy if this is a deployment transaction and spend part is successful. - contract_deploy( - session, - tx, - gas_per_deploy_byte, - min_deploy_points, - &mut receipt, - ); + contract_deploy(session, tx, config, &mut receipt); // Ensure all gas is consumed if there's an error in the contract call if receipt.data.is_err() { @@ -113,12 +104,10 @@ pub fn execute( Ok(receipt) } -fn deploy_check( - tx: &Transaction, - gas_per_deploy_byte: u64, - min_deploy_gas_price: u64, -) -> Result<(), Error> { +fn deploy_check(tx: &Transaction, config: &Config) -> Result<(), Error> { if tx.deploy().is_some() { + let gas_per_deploy_byte = config.gas_per_deploy_byte; + let min_deploy_gas_price = config.min_deploy_gas_price; let deploy_charge = tx.deploy_charge(gas_per_deploy_byte, min_deploy_gas_price); @@ -145,11 +134,13 @@ fn deploy_check( fn contract_deploy( session: &mut Session, tx: &Transaction, - gas_per_deploy_byte: u64, - min_deploy_points: u64, + config: &Config, receipt: &mut CallReceipt, ContractError>>, ) { if let Some(deploy) = tx.deploy() { + let gas_per_deploy_byte = config.gas_per_deploy_byte; + let min_deploy_points = config.min_deploy_points; + let gas_left = tx.gas_limit() - receipt.gas_spent; if receipt.data.is_ok() { let deploy_charge = diff --git a/vm/src/execute/config.rs b/vm/src/execute/config.rs new file mode 100644 index 0000000000..2c48fcd9ea --- /dev/null +++ b/vm/src/execute/config.rs @@ -0,0 +1,32 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) DUSK NETWORK. All rights reserved. + +/// Configuration for the execution of a transaction. +#[derive(Debug, Clone)] +pub struct Config { + /// The amount of gas points charged for each byte in a contract-deployment + /// bytecode. + pub gas_per_deploy_byte: u64, + /// The minimum gas points charged for a contract deployment. + pub min_deploy_points: u64, + /// The minimum gas price set for a contract deployment + pub min_deploy_gas_price: u64, +} + +impl Default for Config { + fn default() -> Self { + Self::DEFAULT + } +} + +impl Config { + /// Create a config with all values to default + pub const DEFAULT: Config = Config { + gas_per_deploy_byte: 0, + min_deploy_points: 0, + min_deploy_gas_price: 0, + }; +} diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 85594729a3..ae4f9ccf46 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -13,7 +13,7 @@ extern crate alloc; -pub use self::execute::{execute, gen_contract_id}; +pub use self::execute::{execute, gen_contract_id, Config as ExecutionConfig}; pub use piecrust::{ CallReceipt, CallTree, CallTreeElem, ContractData, Error, PageOpening, Session,