From 8df83c302d5ed3fa3a579e65e2b808f895798ccb Mon Sep 17 00:00:00 2001 From: Turner Date: Wed, 25 Oct 2023 15:32:39 -0700 Subject: [PATCH 01/36] WIP add infra for contract testing --- Cargo.lock | 1 + benches/Cargo.toml | 1 + benches/benches/block_target_gas.rs | 52 +++++++++++++++++-- .../benches/block_target_gas_set/contract.rs | 48 +++++++++++++++++ crates/fuel-core/src/query/contract.rs | 29 +++++++++++ 5 files changed, 128 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8ce7e757ed..673c5804387 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2768,6 +2768,7 @@ dependencies = [ "ed25519-dalek 1.0.1", "ethnum", "fuel-core", + "fuel-core-chain-config", "fuel-core-services", "fuel-core-storage", "fuel-core-sync", diff --git a/benches/Cargo.toml b/benches/Cargo.toml index 5b926ef478c..b24c861ea1d 100644 --- a/benches/Cargo.toml +++ b/benches/Cargo.toml @@ -15,6 +15,7 @@ ed25519-dalek = "1.0" # TODO: upgrade to 2.0 when it's released, and remove rand ed25519-dalek_old_rand = { package = "rand", version = "0.7.3" } ethnum = "1.3" fuel-core = { path = "../crates/fuel-core", default-features = false, features = ["rocksdb-production"] } +fuel-core-chain-config = { workspace = true } fuel-core-services = { path = "./../crates/services" } fuel-core-storage = { path = "./../crates/storage" } fuel-core-sync = { path = "./../crates/services/sync", features = ["benchmarking"] } diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 22fac802426..7193029d22c 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -22,6 +22,7 @@ use rand::SeedableRng; use ethnum::U256; use fuel_core_benches::*; +use fuel_core_chain_config::ContractConfig; use fuel_core_types::{ fuel_asm::{ op, @@ -41,8 +42,15 @@ use fuel_core_types::{ secp256r1, *, }, - fuel_tx::UniqueIdentifier, - fuel_types::AssetId, + fuel_tx::{ + ContractIdExt, + UniqueIdentifier, + }, + fuel_types::{ + AssetId, + Bytes32, + ContractId, + }, }; mod utils; @@ -65,6 +73,9 @@ fn run( script_data: Vec, ) { group.bench_function(id, |b| { + + const STATE_SIZE: u64 = 10_000_000; + let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() @@ -73,9 +84,44 @@ fn run( const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; const BASE: u64 = 10_000; - let database = Database::rocksdb(); + let mut database = Database::rocksdb(); let mut config = Config::local_node(); config.chain_conf.consensus_parameters.tx_params.max_gas_per_tx = TARGET_BLOCK_GAS_LIMIT; + let contract_id = ContractId::zeroed(); + config.chain_conf.initial_state.as_mut().unwrap().contracts = Some(vec![ContractConfig { + contract_id: contract_id.clone(), + code: vec![], + salt: Default::default(), + state: None, + balances: None, + tx_id: None, + output_index: None, + tx_pointer_block_height: None, + tx_pointer_tx_idx: None, + }]); + database.init_contract_state( + &contract_id, + (0..STATE_SIZE).map(|k| { + let mut key = Bytes32::zeroed(); + key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); + (key, key) + }), + ).unwrap(); + database.init_contract_balances( + &contract_id, + (0..STATE_SIZE).map(|k| { + let key = k / 2; + let mut sub_id = Bytes32::zeroed(); + sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); + + let asset = if k % 2 == 0 { + VmBench::CONTRACT.asset_id(&sub_id) + } else { + AssetId::new(*sub_id) + }; + (asset, key + 1_000) + }), + ).unwrap(); config .chain_conf .consensus_parameters diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 2f84f85fb94..de7ad9ee2d7 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,7 +1,55 @@ use crate::*; // use crate::utils::arb_dependent_cost_values; +// BAL: Balance of contract ID +// BHEI: Block height +// BHSH: Block hash +// BURN: Burn existing coins +// CALL: Call contract +// CB: Coinbase address +// CCP: Code copy +// CROO: Code Merkle root +// CSIZ: Code size +// LDC: Load code from an external contract +// LOG: Log event +// LOGD: Log data event +// MINT: Mint new coins +// RETD: Return from context with data +// RVRT: Revert +// SMO: Send message to output +// SCWQ: State clear sequential 32 byte slots +// SRW: State read word +// SRWQ: State read sequential 32 byte slots +// SWW: State write word +// SWWQ: State write sequential 32 byte slots +// TIME: Timestamp at height +// TR: Transfer coins to contract +// TRO: Transfer coins to output pub fn run_contract(_group: &mut BenchmarkGroup) { + // run_group_ref( + // &mut c.benchmark_group("bal"), + // "bal", + // VmBench::new(op::bal(0x10, 0x10, 0x11)) + // .with_data(asset.iter().chain(contract.iter()).copied().collect()) + // .with_prepare_script(vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, asset.len().try_into().unwrap()), + // ]) + // .with_dummy_contract(contract), + // ); + // run( + // "contract/bal opcode", + // group, + // [ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, asset.len().try_into().unwrap()), + // op::bal(0x10, 0x10, 0x11), + // op::jmpb(RegId::ZERO, 0), + // ] + // .to_vec(), + // vec![], + // ); + // This breaks the benchmarking // for i in arb_dependent_cost_values() { // let id = format!("flow/retd_contract opcode {:?}", i); diff --git a/crates/fuel-core/src/query/contract.rs b/crates/fuel-core/src/query/contract.rs index d05d90999bb..2568b9fdc44 100644 --- a/crates/fuel-core/src/query/contract.rs +++ b/crates/fuel-core/src/query/contract.rs @@ -11,7 +11,9 @@ use fuel_core_storage::{ ContractsRawCode, }, Result as StorageResult, + StorageAsMut, StorageAsRef, + StorageMutate, }; use fuel_core_types::{ fuel_types::{ @@ -43,6 +45,15 @@ pub trait ContractQueryData: Send + Sync { ) -> BoxedIter>; } +#[cfg(feature = "test-helpers")] +pub trait ContractMutateData { + fn insert_contract_bytecode( + &mut self, + id: ContractId, + bytecode: &[u8], + ) -> StorageResult<()>; +} + impl ContractQueryData for D { fn contract_id(&self, id: ContractId) -> StorageResult { let contract_exists = self.storage::().contains_key(&id)?; @@ -100,3 +111,21 @@ impl ContractQueryData for D { self.contract_balances(contract_id, start_asset, direction) } } + +#[cfg(feature = "test-helpers")] +impl ContractMutateData for D +where + D: StorageMutate, +{ + fn insert_contract_bytecode( + &mut self, + id: ContractId, + bytecode: &[u8], + ) -> StorageResult<()> { + let _ = self + .storage_as_mut::() + .insert(&id, &bytecode); + + Ok(()) + } +} From 333e74a5ea5cf7ec8e97383efa85486f5d410a18 Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 26 Oct 2023 15:03:33 -0700 Subject: [PATCH 02/36] Restructure new bench infra, add stalling `call` bench --- benches/benches/block_target_gas.rs | 148 +++++++++++++++--- .../benches/block_target_gas_set/contract.rs | 86 +++++++++- benches/benches/vm_set/blockchain.rs | 6 +- crates/fuel-core/src/database.rs | 17 +- crates/fuel-core/src/query/contract.rs | 29 ---- 5 files changed, 231 insertions(+), 55 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 7193029d22c..cd00dd22775 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -84,11 +84,91 @@ fn run( const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; const BASE: u64 = 10_000; - let mut database = Database::rocksdb(); + let database = Database::rocksdb(); let mut config = Config::local_node(); config.chain_conf.consensus_parameters.tx_params.max_gas_per_tx = TARGET_BLOCK_GAS_LIMIT; - let contract_id = ContractId::zeroed(); - config.chain_conf.initial_state.as_mut().unwrap().contracts = Some(vec![ContractConfig { + config + .chain_conf + .consensus_parameters + .predicate_params + .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; + config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; + config.utxo_validation = false; + config.block_production = Trigger::Instant; + + let service = fuel_core::service::FuelService::new(database, config.clone()) + .expect("Unable to start a FuelService"); + service.start().expect("Unable to start the service"); + let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); + + b.to_async(&rt).iter(|| { + let shared = service.shared.clone(); + + let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( + // Infinite loop + script.clone().into_iter().collect(), + script_data.clone(), + ) + .gas_limit(TARGET_BLOCK_GAS_LIMIT - BASE) + .gas_price(1) + .add_unsigned_coin_input( + SecretKey::random(&mut rng), + rng.gen(), + u64::MAX, + AssetId::BASE, + Default::default(), + Default::default(), + ) + .finalize_as_transaction(); + async move { + let tx_id = tx.id(&config.chain_conf.consensus_parameters.chain_id); + + let mut sub = shared.block_importer.block_importer.subscribe(); + shared + .txpool + .insert(vec![std::sync::Arc::new(tx)]) + .await + .into_iter() + .next() + .expect("Should be at least 1 element") + .expect("Should include transaction successfully"); + let res = sub.recv().await.expect("Should produce a block"); + assert_eq!(res.tx_status.len(), 2); + assert_eq!(res.sealed_block.entity.transactions().len(), 2); + assert_eq!(res.tx_status[0].id, tx_id); + + let fuel_core_types::services::executor::TransactionExecutionResult::Failed { + reason, + .. + } = &res.tx_status[0].result + else { + panic!("The execution should fails with out of gas") + }; + assert!(reason.contains("OutOfGas")); + } + }) + }); +} + +fn service_with_contract_id(contract_id: ContractId) -> fuel_core::service::FuelService { + const STATE_SIZE: u64 = 10_000_000; + + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + let _drop = rt.enter(); + const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; + const BASE: u64 = 10_000; + let mut database = Database::rocksdb(); + let mut config = Config::local_node(); + config + .chain_conf + .consensus_parameters + .tx_params + .max_gas_per_tx = TARGET_BLOCK_GAS_LIMIT; + config.chain_conf.initial_state.as_mut().unwrap().contracts = + Some(vec![ContractConfig { contract_id: contract_id.clone(), code: vec![], salt: Default::default(), @@ -99,15 +179,28 @@ fn run( tx_pointer_block_height: None, tx_pointer_tx_idx: None, }]); - database.init_contract_state( + + config + .chain_conf + .consensus_parameters + .predicate_params + .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; + config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; + config.utxo_validation = false; + config.block_production = Trigger::Instant; + + database + .init_contract_state( &contract_id, (0..STATE_SIZE).map(|k| { let mut key = Bytes32::zeroed(); key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); (key, key) }), - ).unwrap(); - database.init_contract_balances( + ) + .unwrap(); + database + .init_contract_balances( &contract_id, (0..STATE_SIZE).map(|k| { let key = k / 2; @@ -121,23 +214,40 @@ fn run( }; (asset, key + 1_000) }), - ).unwrap(); - config - .chain_conf - .consensus_parameters - .predicate_params - .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; - config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; - config.utxo_validation = false; - config.block_production = Trigger::Instant; + ) + .unwrap(); + + let service = fuel_core::service::FuelService::new(database, config.clone()) + .expect("Unable to start a FuelService"); + service.start().expect("Unable to start the service"); + service +} + +fn run_with_service( + id: &str, + group: &mut BenchmarkGroup, + script: Vec, + script_data: Vec, + service: fuel_core::service::FuelService, +) { + group.bench_function(id, |b| { + + const STATE_SIZE: u64 = 10_000_000; + + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + let _drop = rt.enter(); + const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; + const BASE: u64 = 10_000; + - let service = fuel_core::service::FuelService::new(database, config.clone()) - .expect("Unable to start a FuelService"); - service.start().expect("Unable to start the service"); let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); b.to_async(&rt).iter(|| { let shared = service.shared.clone(); + let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( // Infinite loop script.clone().into_iter().collect(), @@ -155,7 +265,7 @@ fn run( ) .finalize_as_transaction(); async move { - let tx_id = tx.id(&config.chain_conf.consensus_parameters.chain_id); + let tx_id = tx.id(&service.shared.config.chain_conf.consensus_parameters.chain_id); let mut sub = shared.block_importer.block_importer.subscribe(); shared diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index de7ad9ee2d7..936f21327e5 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,4 +1,8 @@ use crate::*; +use fuel_core_types::{ + fuel_types::Word, + fuel_vm::consts::WORD_SIZE, +}; // use crate::utils::arb_dependent_cost_values; // BAL: Balance of contract ID @@ -25,7 +29,7 @@ use crate::*; // TIME: Timestamp at height // TR: Transfer coins to contract // TRO: Transfer coins to output -pub fn run_contract(_group: &mut BenchmarkGroup) { +pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref( // &mut c.benchmark_group("bal"), // "bal", @@ -37,17 +41,23 @@ pub fn run_contract(_group: &mut BenchmarkGroup) { // ]) // .with_dummy_contract(contract), // ); + + // let contract_id = ContractId::zeroed(); + // let asset_id = AssetId::zeroed(); // run( // "contract/bal opcode", // group, // [ // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, asset.len().try_into().unwrap()), + // op::addi(0x11, 0x10, asset_id.len().try_into().unwrap()), // op::bal(0x10, 0x10, 0x11), // op::jmpb(RegId::ZERO, 0), // ] // .to_vec(), - // vec![], + // asset_id + // .into_iter() + // .chain(contract_id.into_iter()) + // .collect(), // ); // This breaks the benchmarking @@ -65,4 +75,74 @@ pub fn run_contract(_group: &mut BenchmarkGroup) { // vec![], // ); // } + + // let mut call = c.benchmark_group("call"); + // + // for i in linear.clone() { + // let mut code = vec![0u8; i as usize]; + // + // rng.fill_bytes(&mut code); + // + // let code = ContractCode::from(code); + // let id = code.id; + // + // let data = id + // .iter() + // .copied() + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain(AssetId::default().iter().copied()) + // .collect(); + // + // let prepare_script = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, 100_000), + // ]; + // + // call.throughput(Throughput::Bytes(i)); + // + // run_group_ref( + // &mut call, + // format!("{i}"), + // VmBench::new(op::call(0x10, RegId::ZERO, 0x11, 0x12)) + // .with_db(db.checkpoint()) + // .with_contract_code(code) + // .with_data(data) + // .with_prepare_script(prepare_script), + // ); + // } + + let contract = vec![op::noop(), op::ret(0x10)]; + + let instructions = vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]; + let contract_id = ContractId::zeroed(); + let mut service = service_with_contract_id(contract_id); + let contract_bytecode: Vec<_> = + contract.iter().map(|x| x.to_bytes()).flatten().collect(); + service + .shared + .database + .insert_contract_bytecode(contract_id, &contract_bytecode) + .unwrap(); + + let script_data = contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(AssetId::default().iter().copied()) + .collect(); + + run_with_service("contract/call", group, instructions, script_data, service); } diff --git a/benches/benches/vm_set/blockchain.rs b/benches/benches/vm_set/blockchain.rs index f0cb9d63658..a845eb59360 100644 --- a/benches/benches/vm_set/blockchain.rs +++ b/benches/benches/vm_set/blockchain.rs @@ -67,14 +67,14 @@ pub struct BenchDb { impl BenchDb { const STATE_SIZE: u64 = 10_000_000; - fn new(contract: &ContractId) -> anyhow::Result { + fn new(contract_id: &ContractId) -> anyhow::Result { let tmp_dir = ShallowTempDir::new(); let db = Arc::new(RocksDb::default_open(&tmp_dir.path, None).unwrap()); let mut database = Database::new(db.clone()); database.init_contract_state( - contract, + contract_id, (0..Self::STATE_SIZE).map(|k| { let mut key = Bytes32::zeroed(); key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); @@ -82,7 +82,7 @@ impl BenchDb { }), )?; database.init_contract_balances( - &ContractId::zeroed(), + contract_id, (0..Self::STATE_SIZE).map(|k| { let key = k / 2; let mut sub_id = Bytes32::zeroed(); diff --git a/crates/fuel-core/src/database.rs b/crates/fuel-core/src/database.rs index 5f70bd7ab38..784a6ba7100 100644 --- a/crates/fuel-core/src/database.rs +++ b/crates/fuel-core/src/database.rs @@ -20,7 +20,10 @@ use fuel_core_storage::{ }, Result as StorageResult, }; -use fuel_core_types::fuel_types::BlockHeight; +use fuel_core_types::fuel_types::{ + BlockHeight, + ContractId, +}; use itertools::Itertools; use serde::{ de::DeserializeOwned, @@ -420,6 +423,18 @@ impl Database { }) }) } + + #[cfg(feature = "test-helpers")] + pub fn insert_contract_bytecode( + &mut self, + id: ContractId, + bytecode: &[u8], + ) -> DatabaseResult<()> { + let column = Column::ContractsRawCode; + let _: Option> = self.insert(&id, column, &bytecode)?; + + Ok(()) + } } impl Transactional for Database { diff --git a/crates/fuel-core/src/query/contract.rs b/crates/fuel-core/src/query/contract.rs index 2568b9fdc44..d05d90999bb 100644 --- a/crates/fuel-core/src/query/contract.rs +++ b/crates/fuel-core/src/query/contract.rs @@ -11,9 +11,7 @@ use fuel_core_storage::{ ContractsRawCode, }, Result as StorageResult, - StorageAsMut, StorageAsRef, - StorageMutate, }; use fuel_core_types::{ fuel_types::{ @@ -45,15 +43,6 @@ pub trait ContractQueryData: Send + Sync { ) -> BoxedIter>; } -#[cfg(feature = "test-helpers")] -pub trait ContractMutateData { - fn insert_contract_bytecode( - &mut self, - id: ContractId, - bytecode: &[u8], - ) -> StorageResult<()>; -} - impl ContractQueryData for D { fn contract_id(&self, id: ContractId) -> StorageResult { let contract_exists = self.storage::().contains_key(&id)?; @@ -111,21 +100,3 @@ impl ContractQueryData for D { self.contract_balances(contract_id, start_asset, direction) } } - -#[cfg(feature = "test-helpers")] -impl ContractMutateData for D -where - D: StorageMutate, -{ - fn insert_contract_bytecode( - &mut self, - id: ContractId, - bytecode: &[u8], - ) -> StorageResult<()> { - let _ = self - .storage_as_mut::() - .insert(&id, &bytecode); - - Ok(()) - } -} From 864fe3b79028c9b060ab1cda8a6363b8fc57b9b0 Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 26 Oct 2023 17:41:02 -0700 Subject: [PATCH 03/36] Fix insert --- benches/benches/block_target_gas.rs | 3 --- benches/benches/block_target_gas_set/contract.rs | 9 +++++++-- crates/fuel-core/src/database.rs | 11 +++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index cd00dd22775..69bb1d2d4de 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -73,9 +73,6 @@ fn run( script_data: Vec, ) { group.bench_function(id, |b| { - - const STATE_SIZE: u64 = 10_000_000; - let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 936f21327e5..8e6f6a5f73c 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,4 +1,8 @@ use crate::*; +use fuel_core_storage::{ + tables::ContractsRawCode, + StorageAsMut, +}; use fuel_core_types::{ fuel_types::Word, fuel_vm::consts::WORD_SIZE, @@ -124,7 +128,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::movi(0x12, 100_000), op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), + // op::jmpb(RegId::ZERO, 0), ]; let contract_id = ContractId::zeroed(); let mut service = service_with_contract_id(contract_id); @@ -133,7 +137,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { service .shared .database - .insert_contract_bytecode(contract_id, &contract_bytecode) + .storage_as_mut::() + .insert(&contract_id, &contract_bytecode) .unwrap(); let script_data = contract_id diff --git a/crates/fuel-core/src/database.rs b/crates/fuel-core/src/database.rs index 784a6ba7100..3ae8cd4a636 100644 --- a/crates/fuel-core/src/database.rs +++ b/crates/fuel-core/src/database.rs @@ -20,9 +20,12 @@ use fuel_core_storage::{ }, Result as StorageResult, }; -use fuel_core_types::fuel_types::{ - BlockHeight, - ContractId, +use fuel_core_types::{ + fuel_tx::Contract, + fuel_types::{ + BlockHeight, + ContractId, + }, }; use itertools::Itertools; use serde::{ @@ -431,7 +434,7 @@ impl Database { bytecode: &[u8], ) -> DatabaseResult<()> { let column = Column::ContractsRawCode; - let _: Option> = self.insert(&id, column, &bytecode)?; + let _: Option = self.insert(&id, column, &bytecode)?; Ok(()) } From 1fe61c6c3ed4de0553d1aab87a5b3ceec0ec1a72 Mon Sep 17 00:00:00 2001 From: Turner Date: Fri, 27 Oct 2023 14:12:43 -0700 Subject: [PATCH 04/36] WIP debugging stalling benchmark --- benches/benches/block_target_gas.rs | 83 ++++++++++--------- .../benches/block_target_gas_set/contract.rs | 54 +++++++----- 2 files changed, 76 insertions(+), 61 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 69bb1d2d4de..ec1d2b51014 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -147,7 +147,9 @@ fn run( }); } -fn service_with_contract_id(contract_id: ContractId) -> fuel_core::service::FuelService { +fn service_with_contract_id( + contract_id: ContractId, +) -> (fuel_core::service::FuelService, tokio::runtime::Runtime) { const STATE_SIZE: u64 = 10_000_000; let rt = tokio::runtime::Builder::new_current_thread() @@ -186,38 +188,38 @@ fn service_with_contract_id(contract_id: ContractId) -> fuel_core::service::Fuel config.utxo_validation = false; config.block_production = Trigger::Instant; - database - .init_contract_state( - &contract_id, - (0..STATE_SIZE).map(|k| { - let mut key = Bytes32::zeroed(); - key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); - (key, key) - }), - ) - .unwrap(); - database - .init_contract_balances( - &contract_id, - (0..STATE_SIZE).map(|k| { - let key = k / 2; - let mut sub_id = Bytes32::zeroed(); - sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); - - let asset = if k % 2 == 0 { - VmBench::CONTRACT.asset_id(&sub_id) - } else { - AssetId::new(*sub_id) - }; - (asset, key + 1_000) - }), - ) - .unwrap(); + // database + // .init_contract_state( + // &contract_id, + // (0..STATE_SIZE).map(|k| { + // let mut key = Bytes32::zeroed(); + // key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); + // (key, key) + // }), + // ) + // .unwrap(); + // database + // .init_contract_balances( + // &contract_id, + // (0..STATE_SIZE).map(|k| { + // let key = k / 2; + // let mut sub_id = Bytes32::zeroed(); + // sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); + // + // let asset = if k % 2 == 0 { + // VmBench::CONTRACT.asset_id(&sub_id) + // } else { + // AssetId::new(*sub_id) + // }; + // (asset, key + 1_000) + // }), + // ) + // .unwrap(); let service = fuel_core::service::FuelService::new(database, config.clone()) .expect("Unable to start a FuelService"); service.start().expect("Unable to start the service"); - service + (service, rt) } fn run_with_service( @@ -226,23 +228,24 @@ fn run_with_service( script: Vec, script_data: Vec, service: fuel_core::service::FuelService, + rt: tokio::runtime::Runtime, ) { + dbg!("beep"); group.bench_function(id, |b| { - - const STATE_SIZE: u64 = 10_000_000; - - let rt = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap(); - let _drop = rt.enter(); + dbg!("boop"); + // let rt = tokio::runtime::Builder::new_current_thread() + // .enable_all() + // .build() + // .unwrap(); + // let _drop = rt.enter(); const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; const BASE: u64 = 10_000; - let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); b.to_async(&rt).iter(|| { + dbg!(&script); + dbg!(&script_data); let shared = service.shared.clone(); let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( @@ -262,9 +265,10 @@ fn run_with_service( ) .finalize_as_transaction(); async move { - let tx_id = tx.id(&service.shared.config.chain_conf.consensus_parameters.chain_id); + let tx_id = tx.id(&shared.config.chain_conf.consensus_parameters.chain_id); let mut sub = shared.block_importer.block_importer.subscribe(); + dbg!(&tx); shared .txpool .insert(vec![std::sync::Arc::new(tx)]) @@ -274,6 +278,7 @@ fn run_with_service( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); + dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 8e6f6a5f73c..ba42d0aa5ad 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -122,32 +122,42 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let contract = vec![op::noop(), op::ret(0x10)]; let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - // op::jmpb(RegId::ZERO, 0), + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, 100_000), + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::noop(), + op::jmpb(RegId::ZERO, 0), ]; let contract_id = ContractId::zeroed(); - let mut service = service_with_contract_id(contract_id); + let (mut service, rt) = service_with_contract_id(contract_id); let contract_bytecode: Vec<_> = contract.iter().map(|x| x.to_bytes()).flatten().collect(); - service - .shared - .database - .storage_as_mut::() - .insert(&contract_id, &contract_bytecode) - .unwrap(); + // service + // .shared + // .database + // .storage_as_mut::() + // .insert(&contract_id, &contract_bytecode) + // .unwrap(); - let script_data = contract_id - .iter() - .copied() - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain(AssetId::default().iter().copied()) - .collect(); + // let script_data = contract_id + // .iter() + // .copied() + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain(AssetId::default().iter().copied()) + // .collect(); - run_with_service("contract/call", group, instructions, script_data, service); + let script_data = vec![]; + + run_with_service( + "contract/call", + group, + instructions, + script_data, + service, + rt, + ); } From 39be18e6366dc35dd75a9d465703291798cb1eea Mon Sep 17 00:00:00 2001 From: Turner Date: Fri, 27 Oct 2023 15:04:12 -0700 Subject: [PATCH 05/36] Get simple bench working --- benches/benches/block_target_gas.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index ec1d2b51014..5a4b23dc6b7 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -230,22 +230,12 @@ fn run_with_service( service: fuel_core::service::FuelService, rt: tokio::runtime::Runtime, ) { - dbg!("beep"); + let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); group.bench_function(id, |b| { - dbg!("boop"); - // let rt = tokio::runtime::Builder::new_current_thread() - // .enable_all() - // .build() - // .unwrap(); - // let _drop = rt.enter(); const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; const BASE: u64 = 10_000; - let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); - b.to_async(&rt).iter(|| { - dbg!(&script); - dbg!(&script_data); let shared = service.shared.clone(); let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( @@ -268,7 +258,6 @@ fn run_with_service( let tx_id = tx.id(&shared.config.chain_conf.consensus_parameters.chain_id); let mut sub = shared.block_importer.block_importer.subscribe(); - dbg!(&tx); shared .txpool .insert(vec![std::sync::Arc::new(tx)]) @@ -278,7 +267,6 @@ fn run_with_service( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); From b79b577e0e60961fc4e5b996838cea68e07f8864 Mon Sep 17 00:00:00 2001 From: Turner Date: Fri, 27 Oct 2023 17:13:02 -0700 Subject: [PATCH 06/36] Get call bench actually working! --- benches/benches/block_target_gas.rs | 83 ++++++++++++------- .../benches/block_target_gas_set/contract.rs | 55 ++++++------ benches/src/lib.rs | 4 +- 3 files changed, 84 insertions(+), 58 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 5a4b23dc6b7..9d87abbbcdf 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -44,7 +44,11 @@ use fuel_core_types::{ }, fuel_tx::{ ContractIdExt, + Input, + Output, + TxPointer, UniqueIdentifier, + UtxoId, }, fuel_types::{ AssetId, @@ -188,33 +192,33 @@ fn service_with_contract_id( config.utxo_validation = false; config.block_production = Trigger::Instant; - // database - // .init_contract_state( - // &contract_id, - // (0..STATE_SIZE).map(|k| { - // let mut key = Bytes32::zeroed(); - // key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); - // (key, key) - // }), - // ) - // .unwrap(); - // database - // .init_contract_balances( - // &contract_id, - // (0..STATE_SIZE).map(|k| { - // let key = k / 2; - // let mut sub_id = Bytes32::zeroed(); - // sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); - // - // let asset = if k % 2 == 0 { - // VmBench::CONTRACT.asset_id(&sub_id) - // } else { - // AssetId::new(*sub_id) - // }; - // (asset, key + 1_000) - // }), - // ) - // .unwrap(); + database + .init_contract_state( + &contract_id, + (0..STATE_SIZE).map(|k| { + let mut key = Bytes32::zeroed(); + key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); + (key, key) + }), + ) + .unwrap(); + database + .init_contract_balances( + &contract_id, + (0..STATE_SIZE).map(|k| { + let key = k / 2; + let mut sub_id = Bytes32::zeroed(); + sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); + + let asset = if k % 2 == 0 { + VmBench::CONTRACT.asset_id(&sub_id) + } else { + AssetId::new(*sub_id) + }; + (asset, key + 1_000) + }), + ) + .unwrap(); let service = fuel_core::service::FuelService::new(database, config.clone()) .expect("Unable to start a FuelService"); @@ -228,6 +232,7 @@ fn run_with_service( script: Vec, script_data: Vec, service: fuel_core::service::FuelService, + contract_id: ContractId, rt: tokio::runtime::Runtime, ) { let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); @@ -238,11 +243,13 @@ fn run_with_service( b.to_async(&rt).iter(|| { let shared = service.shared.clone(); - let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( + + let mut tx_builder = fuel_core_types::fuel_tx::TransactionBuilder::script( // Infinite loop script.clone().into_iter().collect(), script_data.clone(), - ) + ); + tx_builder .gas_limit(TARGET_BLOCK_GAS_LIMIT - BASE) .gas_price(1) .add_unsigned_coin_input( @@ -252,8 +259,22 @@ fn run_with_service( AssetId::BASE, Default::default(), Default::default(), - ) - .finalize_as_transaction(); + ); + let input_count = tx_builder.inputs().len(); + + let contract_input = Input::contract( + UtxoId::default(), + Bytes32::zeroed(), + Bytes32::zeroed(), + TxPointer::default(), + contract_id, + ); + let contract_output = Output::contract(input_count as u8, Bytes32::zeroed(), Bytes32::zeroed()); + + tx_builder + .add_input(contract_input) + .add_output(contract_output); + let tx = tx_builder.finalize_as_transaction(); async move { let tx_id = tx.id(&shared.config.chain_conf.consensus_parameters.chain_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index ba42d0aa5ad..73cf5a5b7f6 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -4,6 +4,10 @@ use fuel_core_storage::{ StorageAsMut, }; use fuel_core_types::{ + fuel_tx::{ + TxPointer, + UtxoId, + }, fuel_types::Word, fuel_vm::consts::WORD_SIZE, }; @@ -119,38 +123,38 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // } - let contract = vec![op::noop(), op::ret(0x10)]; + let contract_instructions = vec![op::noop(), op::ret(0x10)]; let instructions = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, 100_000), - // op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::noop(), + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]; let contract_id = ContractId::zeroed(); let (mut service, rt) = service_with_contract_id(contract_id); - let contract_bytecode: Vec<_> = - contract.iter().map(|x| x.to_bytes()).flatten().collect(); - // service - // .shared - // .database - // .storage_as_mut::() - // .insert(&contract_id, &contract_bytecode) - // .unwrap(); + let contract_bytecode: Vec<_> = contract_instructions + .iter() + .map(|x| x.to_bytes()) + .flatten() + .collect(); + service + .shared + .database + .storage_as_mut::() + .insert(&contract_id, &contract_bytecode) + .unwrap(); - // let script_data = contract_id - // .iter() - // .copied() - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain(AssetId::default().iter().copied()) - // .collect(); - - let script_data = vec![]; + let script_data = contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(AssetId::default().iter().copied()) + .collect(); run_with_service( "contract/call", @@ -158,6 +162,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { instructions, script_data, service, + contract_id, rt, ); } diff --git a/benches/src/lib.rs b/benches/src/lib.rs index 38b7c9c0382..dd6c457c0c3 100644 --- a/benches/src/lib.rs +++ b/benches/src/lib.rs @@ -377,9 +377,9 @@ impl TryFrom for VmBenchPrepared { storage_root, }) = contract_code { - let input = tx.inputs().len(); + let input_count = tx.inputs().len(); let output = - Output::contract(input as u8, Bytes32::zeroed(), Bytes32::zeroed()); + Output::contract(input_count as u8, Bytes32::zeroed(), Bytes32::zeroed()); let input = Input::contract( UtxoId::default(), Bytes32::zeroed(), From 0def296862dc9f7d182b8bc736c7e13461aea748 Mon Sep 17 00:00:00 2001 From: Turner Date: Mon, 30 Oct 2023 13:22:38 -0700 Subject: [PATCH 07/36] Add range of contract sizes for `call` benches --- benches/benches/block_target_gas.rs | 12 +-- .../benches/block_target_gas_set/contract.rs | 92 ++++++++++--------- 2 files changed, 57 insertions(+), 47 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 9d87abbbcdf..7491663f9e8 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -231,16 +231,16 @@ fn run_with_service( group: &mut BenchmarkGroup, script: Vec, script_data: Vec, - service: fuel_core::service::FuelService, + service: &fuel_core::service::FuelService, contract_id: ContractId, - rt: tokio::runtime::Runtime, + rt: &tokio::runtime::Runtime, + rng: &mut rand::rngs::StdRng, ) { - let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); group.bench_function(id, |b| { const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; const BASE: u64 = 10_000; - b.to_async(&rt).iter(|| { + b.to_async(rt).iter(|| { let shared = service.shared.clone(); @@ -253,7 +253,7 @@ fn run_with_service( .gas_limit(TARGET_BLOCK_GAS_LIMIT - BASE) .gas_price(1) .add_unsigned_coin_input( - SecretKey::random(&mut rng), + SecretKey::random(rng), rng.gen(), u64::MAX, AssetId::BASE, @@ -288,7 +288,7 @@ fn run_with_service( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - assert_eq!(res.tx_status.len(), 2); + assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 73cf5a5b7f6..de860a1bded 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,4 +1,7 @@ -use crate::*; +use crate::{ + utils::arb_dependent_cost_values, + *, +}; use fuel_core_storage::{ tables::ContractsRawCode, StorageAsMut, @@ -11,7 +14,6 @@ use fuel_core_types::{ fuel_types::Word, fuel_vm::consts::WORD_SIZE, }; -// use crate::utils::arb_dependent_cost_values; // BAL: Balance of contract ID // BHEI: Block height @@ -122,47 +124,55 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .with_prepare_script(prepare_script), // ); // } - - let contract_instructions = vec![op::noop(), op::ret(0x10)]; - - let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), - ]; let contract_id = ContractId::zeroed(); let (mut service, rt) = service_with_contract_id(contract_id); - let contract_bytecode: Vec<_> = contract_instructions - .iter() - .map(|x| x.to_bytes()) - .flatten() - .collect(); - service - .shared - .database - .storage_as_mut::() - .insert(&contract_id, &contract_bytecode) - .unwrap(); + let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); + + for size in arb_dependent_cost_values() { + let mut contract_instructions = std::iter::repeat(op::noop()) + .take(size as usize) + .collect::>(); + contract_instructions.push(op::ret(0x10)); + + let instructions = vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]; + let contract_bytecode: Vec<_> = contract_instructions + .iter() + .map(|x| x.to_bytes()) + .flatten() + .collect(); + service + .shared + .database + .storage_as_mut::() + .insert(&contract_id, &contract_bytecode) + .unwrap(); - let script_data = contract_id - .iter() - .copied() - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain(AssetId::default().iter().copied()) - .collect(); + let script_data = contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(AssetId::default().iter().copied()) + .collect(); - run_with_service( - "contract/call", - group, - instructions, - script_data, - service, - contract_id, - rt, - ); + let id = format!("contract/call {:?}", size); + run_with_service( + &id, + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + } } From 773b8e1ee79f763577cc08ec7799c3ce9ebc1bb4 Mon Sep 17 00:00:00 2001 From: Turner Date: Mon, 30 Oct 2023 14:49:52 -0700 Subject: [PATCH 08/36] Add `bal` benches --- .../benches/block_target_gas_set/contract.rs | 164 +++++++++--------- 1 file changed, 80 insertions(+), 84 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index de860a1bded..f754f5a2410 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -2,6 +2,7 @@ use crate::{ utils::arb_dependent_cost_values, *, }; +use fuel_core::service::FuelService; use fuel_core_storage::{ tables::ContractsRawCode, StorageAsMut, @@ -40,6 +41,10 @@ use fuel_core_types::{ // TR: Transfer coins to contract // TRO: Transfer coins to output pub fn run_contract(group: &mut BenchmarkGroup) { + let contract_id = ContractId::zeroed(); + let (mut service, rt) = service_with_contract_id(contract_id); + let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); + // run_group_ref( // &mut c.benchmark_group("bal"), // "bal", @@ -51,82 +56,64 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ]) // .with_dummy_contract(contract), // ); + let asset_id = AssetId::zeroed(); + let contract_id = ContractId::zeroed(); + let contract_instructions = vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; - // let contract_id = ContractId::zeroed(); - // let asset_id = AssetId::zeroed(); - // run( - // "contract/bal opcode", - // group, - // [ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, asset_id.len().try_into().unwrap()), - // op::bal(0x10, 0x10, 0x11), - // op::jmpb(RegId::ZERO, 0), - // ] - // .to_vec(), - // asset_id - // .into_iter() - // .chain(contract_id.into_iter()) - // .collect(), - // ); + let instructions = vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + ]; - // This breaks the benchmarking - // for i in arb_dependent_cost_values() { - // let id = format!("flow/retd_contract opcode {:?}", i); - // run( - // &id, - // group, - // vec![ - // op::movi(0x10, i), - // op::retd(RegId::ONE, 0x10), - // op::jmpb(RegId::ZERO, 0), - // ] - // .to_vec(), - // vec![], - // ); - // } + replace_contract_in_service(&mut service, &contract_id, contract_instructions); - // let mut call = c.benchmark_group("call"); - // - // for i in linear.clone() { - // let mut code = vec![0u8; i as usize]; - // - // rng.fill_bytes(&mut code); - // - // let code = ContractCode::from(code); - // let id = code.id; - // - // let data = id - // .iter() - // .copied() - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain(AssetId::default().iter().copied()) - // .collect(); - // - // let prepare_script = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, 100_000), - // ]; - // - // call.throughput(Throughput::Bytes(i)); - // - // run_group_ref( - // &mut call, - // format!("{i}"), - // VmBench::new(op::call(0x10, RegId::ZERO, 0x11, 0x12)) - // .with_db(db.checkpoint()) - // .with_contract_code(code) - // .with_data(data) - // .with_prepare_script(prepare_script), - // ); - // } - let contract_id = ContractId::zeroed(); - let (mut service, rt) = service_with_contract_id(contract_id); - let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); + let script_data: Vec<_> = contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(AssetId::default().iter().copied()) + .collect(); + + let id = "contract/bal contract"; + run_with_service( + id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + + let instructions = vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::bal(0x13, 0x11, 0x10), + op::jmpb(RegId::ZERO, 0), + ]; + + let id = "contract/bal script"; + run_with_service( + id, + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + + // Call for size in arb_dependent_cost_values() { let mut contract_instructions = std::iter::repeat(op::noop()) @@ -143,17 +130,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]; - let contract_bytecode: Vec<_> = contract_instructions - .iter() - .map(|x| x.to_bytes()) - .flatten() - .collect(); - service - .shared - .database - .storage_as_mut::() - .insert(&contract_id, &contract_bytecode) - .unwrap(); + + replace_contract_in_service(&mut service, &contract_id, contract_instructions); let script_data = contract_id .iter() @@ -176,3 +154,21 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } } + +fn replace_contract_in_service( + service: &mut FuelService, + contract_id: &ContractId, + contract_instructions: Vec, +) { + let contract_bytecode: Vec<_> = contract_instructions + .iter() + .map(|x| x.to_bytes()) + .flatten() + .collect(); + service + .shared + .database + .storage_as_mut::() + .insert(contract_id, &contract_bytecode) + .unwrap(); +} From dc2aa9db978d799d1ee5d78a1195cf66596414d4 Mon Sep 17 00:00:00 2001 From: Turner Date: Mon, 30 Oct 2023 15:40:26 -0700 Subject: [PATCH 09/36] Finish simple benches, bring over example code for complex ones --- .../benches/block_target_gas_set/contract.rs | 429 ++++++++++++++++++ 1 file changed, 429 insertions(+) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index f754f5a2410..07851997229 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -113,6 +113,57 @@ pub fn run_contract(group: &mut BenchmarkGroup) { &mut rng, ); + // run_group_ref( + // &mut c.benchmark_group("bhei"), + // "bhei", + // VmBench::new(op::bhei(0x10)), + // ); + run( + "contract/bhei", + group, + vec![op::bhei(0x10), + op::jmpb(RegId::ZERO, 0)], + vec![], + ) + + // run_group_ref( + // &mut c.benchmark_group("bhsh"), + // "bhsh", + // VmBench::new(op::bhsh(0x10, RegId::ZERO)).with_prepare_script(vec![ + // op::movi(0x10, Bytes32::LEN.try_into().unwrap()), + // op::aloc(0x10), + // op::move_(0x10, RegId::HP), + // ]), + // ); + run( + "contract/bhsh", + group, + vec![ + op::movi(0x10, Bytes32::LEN.try_into().unwrap()), + op::aloc(0x10), + op::move_(0x10, RegId::HP), + op::bhsh(0x10, RegId::ZERO), + op::jmpb(RegId::ZERO, 0)], + vec![], + ) + + // run_group_ref( + // &mut c.benchmark_group("burn"), + // "burn", + // VmBench::contract_using_db(rng, db.checkpoint(), op::burn(RegId::ONE, RegId::HP)) + // .expect("failed to prepare contract") + // .prepend_prepare_script(vec![op::movi(0x10, 32), op::aloc(0x10)]), + // ); + + // run( + // "contract/burn", + // group, + // vec![op::movi(0x10, 32), op::aloc(0x10), + // op::burn(RegId::ONE, RegId::HP), + // op::jmpb(RegId::ZERO, 0)], + // vec![], + // ); + // Call for size in arb_dependent_cost_values() { @@ -153,6 +204,384 @@ pub fn run_contract(group: &mut BenchmarkGroup) { &mut rng, ); } + + // run_group_ref( + // &mut c.benchmark_group("cb"), + // "cb", + // VmBench::new(op::cb(0x10)).with_prepare_script(vec![ + // op::movi(0x10, Bytes32::LEN.try_into().unwrap()), + // op::aloc(0x10), + // op::move_(0x10, RegId::HP), + // ]), + // ); + run( + "contract/cb", + group, + vec![ + op::movi(0x10, Bytes32::LEN.try_into().unwrap()), + op::aloc(0x10), + op::move_(0x10, RegId::HP), + op::cb(0x10), + op::jmpb(RegId::ZERO, 0)], + vec![], + ); + + // let mut ccp = c.benchmark_group("ccp"); + // + // for i in linear.clone() { + // let mut code = vec![0u8; i as usize]; + // + // rng.fill_bytes(&mut code); + // + // let code = ContractCode::from(code); + // let id = code.id; + // + // let data = id + // .iter() + // .copied() + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain(AssetId::default().iter().copied()) + // .collect(); + // + // let prepare_script = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, 100_000), + // op::movi(0x13, i.try_into().unwrap()), + // op::movi(0x14, i.try_into().unwrap()), + // op::movi(0x15, i.try_into().unwrap()), + // op::add(0x15, 0x15, 0x15), + // op::addi(0x15, 0x15, 32), + // op::aloc(0x15), + // op::move_(0x15, RegId::HP), + // ]; + // + // ccp.throughput(Throughput::Bytes(i)); + // + // run_group_ref( + // &mut ccp, + // format!("{i}"), + // VmBench::new(op::ccp(0x15, 0x10, RegId::ZERO, 0x13)) + // .with_contract_code(code) + // .with_data(data) + // .with_prepare_script(prepare_script), + // ); + // } + // + // ccp.finish(); + + // { + // let mut input = VmBench::contract(rng, op::croo(0x14, 0x16)) + // .expect("failed to prepare contract"); + // input.post_call.extend(vec![ + // op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), + // op::movi(0x15, 2000), + // op::aloc(0x15), + // op::move_(0x14, RegId::HP), + // ]); + // run_group_ref(&mut c.benchmark_group("croo"), "croo", input); + // } + + // let mut csiz = c.benchmark_group("csiz"); + // + // for i in linear.clone() { + // let mut code = vec![0u8; i as usize]; + // + // rng.fill_bytes(&mut code); + // + // let code = ContractCode::from(code); + // let id = code.id; + // + // let data = id.iter().copied().collect(); + // + // let prepare_script = vec![op::gtf_args(0x10, 0x00, GTFArgs::ScriptData)]; + // + // csiz.throughput(Throughput::Bytes(i)); + // + // run_group_ref( + // &mut csiz, + // format!("{i}"), + // VmBench::new(op::csiz(0x11, 0x10)) + // .with_contract_code(code) + // .with_data(data) + // .with_prepare_script(prepare_script), + // ); + // } + // + // csiz.finish(); + + // let mut ldc = c.benchmark_group("ldc"); + // + // for i in linear.clone() { + // let mut code = vec![0u8; i as usize]; + // + // rng.fill_bytes(&mut code); + // + // let code = ContractCode::from(code); + // let id = code.id; + // + // let data = id + // .iter() + // .copied() + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain((0 as Word).to_be_bytes().iter().copied()) + // .chain(AssetId::default().iter().copied()) + // .collect(); + // + // let prepare_script = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, 100_000), + // op::movi(0x13, i.try_into().unwrap()), + // ]; + // + // ldc.throughput(Throughput::Bytes(i)); + // + // run_group_ref( + // &mut ldc, + // format!("{i}"), + // VmBench::new(op::ldc(0x10, RegId::ZERO, 0x13)) + // .with_contract_code(code) + // .with_data(data) + // .with_prepare_script(prepare_script), + // ); + // } + // + // ldc.finish(); + + // log + + // logd + + // run_group_ref( + // &mut c.benchmark_group("mint"), + // "mint", + // VmBench::contract_using_db( + // rng, + // db.checkpoint(), + // op::mint(RegId::ONE, RegId::ZERO), + // ) + // .expect("failed to prepare contract"), + // ); + + // retd + + // rvrt + + // let mut smo = c.benchmark_group("smo"); + // + // for i in linear.clone() { + // let mut input = VmBench::contract_using_db( + // rng, + // db.checkpoint(), + // op::smo(0x15, 0x16, 0x17, 0x18), + // ) + // .expect("failed to prepare contract"); + // input.post_call.extend(vec![ + // op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), + // // Offset 32 + 8 + 8 + 32 + // op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer + // op::addi(0x16, 0x15, 32), // data ppinter + // op::movi(0x17, i.try_into().unwrap()), // data length + // op::movi(0x18, 10), // coins to send + // ]); + // input.data.extend( + // Address::new([1u8; 32]) + // .iter() + // .copied() + // .chain(vec![2u8; i as usize]), + // ); + // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + // let owner = Input::predicate_owner(&predicate); + // let coin_input = Input::coin_predicate( + // Default::default(), + // owner, + // Word::MAX, + // AssetId::zeroed(), + // Default::default(), + // Default::default(), + // Default::default(), + // predicate, + // vec![], + // ); + // input.inputs.push(coin_input); + // smo.throughput(Throughput::Bytes(i)); + // run_group_ref(&mut smo, format!("{i}"), input); + // } + // + // smo.finish(); + + // let mut scwq = c.benchmark_group("scwq"); + // + // for i in linear.clone() { + // let start_key = Bytes32::zeroed(); + // let data = start_key.iter().copied().collect::>(); + // + // let post_call = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, i as u32), + // ]; + // let mut bench = + // VmBench::contract_using_db(rng, db.checkpoint(), op::scwq(0x11, 0x29, 0x12)) + // .expect("failed to prepare contract") + // .with_post_call(post_call); + // bench.data.extend(data); + // + // scwq.throughput(Throughput::Bytes(i)); + // + // run_group_ref(&mut scwq, format!("{i}"), bench); + // } + // + // scwq.finish(); + + // let mut srwq = c.benchmark_group("srwq"); + // + // for i in linear.clone() { + // let start_key = Bytes32::zeroed(); + // let data = start_key.iter().copied().collect::>(); + // + // let post_call = vec![ + // op::movi(0x16, i as u32), + // op::movi(0x17, 2000), + // op::move_(0x15, 0x16), + // op::muli(0x15, 0x15, 32), + // op::addi(0x15, 0x15, 1), + // op::aloc(0x15), + // op::move_(0x14, RegId::HP), + // ]; + // let mut bench = VmBench::contract(rng, op::srwq(0x14, 0x11, 0x27, 0x16)) + // .expect("failed to prepare contract") + // .with_post_call(post_call) + // .with_prepare_db(move |mut db| { + // let slots = (0u64..i).map(|key_number| { + // let mut key = Bytes32::zeroed(); + // key.as_mut()[..8].copy_from_slice(&key_number.to_be_bytes()); + // (key, key) + // }); + // db.database_mut() + // .init_contract_state(&contract, slots) + // .unwrap(); + // + // Ok(db) + // }); + // bench.data.extend(data); + // srwq.throughput(Throughput::Bytes(i)); + // run_group_ref(&mut srwq, format!("{i}"), bench); + // } + // + // srwq.finish(); + + // run_group_ref( + // &mut c.benchmark_group("sww"), + // "sww", + // VmBench::contract_using_db( + // rng, + // db.checkpoint(), + // op::sww(RegId::ZERO, 0x29, RegId::ONE), + // ) + // .expect("failed to prepare contract"), + // ); + + // let mut swwq = c.benchmark_group("swwq"); + // + // for i in linear.clone() { + // let start_key = Bytes32::zeroed(); + // let data = start_key.iter().copied().collect::>(); + // + // let post_call = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, i as u32), + // ]; + // let mut bench = VmBench::contract_using_db( + // rng, + // db.checkpoint(), + // op::swwq(0x10, 0x11, 0x20, 0x12), + // ) + // .expect("failed to prepare contract") + // .with_post_call(post_call); + // bench.data.extend(data); + // + // swwq.throughput(Throughput::Bytes(i)); + // + // run_group_ref(&mut swwq, format!("{i}"), bench); + // } + // + // swwq.finish(); + + // run_group_ref( + // &mut c.benchmark_group("time"), + // "time", + // VmBench::new(op::time(0x11, 0x10)).with_prepare_script(vec![op::movi(0x10, 0)]), + // ); + + run( + "contract/time", + group, + vec![op::movi(0x10, 0), + op::time(0x11, 0x10), + op::jmpb(RegId::ZERO, 0)], + vec![], + ) + + // { + // let mut input = + // VmBench::contract_using_db(rng, db.checkpoint(), op::tr(0x15, 0x14, 0x15)) + // .expect("failed to prepare contract"); + // input + // .prepare_script + // .extend(vec![op::movi(0x15, 2000), op::movi(0x14, 100)]); + // run_group_ref(&mut c.benchmark_group("tr"), "tr", input); + // } + + // { + // let mut input = VmBench::contract_using_db( + // rng, + // db.checkpoint(), + // op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), + // ) + // .expect("failed to prepare contract"); + // let coin_output = Output::variable(Address::zeroed(), 100, AssetId::zeroed()); + // input.outputs.push(coin_output); + // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + // let owner = Input::predicate_owner(&predicate); + // let coin_input = Input::coin_predicate( + // Default::default(), + // owner, + // 1000, + // AssetId::zeroed(), + // Default::default(), + // Default::default(), + // Default::default(), + // predicate, + // vec![], + // ); + // input.inputs.push(coin_input); + // + // let index = input.outputs.len() - 1; + // input.prepare_script.extend(vec![ + // op::movi(0x14, 100), + // op::movi(0x15, index.try_into().unwrap()), + // op::movi(0x20, 32), + // op::aloc(0x20), + // ]); + // for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { + // input.prepare_script.push(op::movi(0x20, v as u32)); + // input.prepare_script.push(op::sb(RegId::HP, 0x20, i as u16)); + // } + // + // run_group_ref(&mut c.benchmark_group("tro"), "tro", input); + // } } fn replace_contract_in_service( From 7e4c311d03963ae2eca65f113ea27d2095c71af1 Mon Sep 17 00:00:00 2001 From: mitchell Date: Tue, 31 Oct 2023 13:09:16 -0700 Subject: [PATCH 10/36] WIP add new methods without verification --- .../benches/block_target_gas_set/contract.rs | 242 +++++++++++++----- 1 file changed, 177 insertions(+), 65 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 07851997229..a49371070d4 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,17 +1,8 @@ -use crate::{ - utils::arb_dependent_cost_values, - *, -}; +use crate::{utils::arb_dependent_cost_values, *}; use fuel_core::service::FuelService; -use fuel_core_storage::{ - tables::ContractsRawCode, - StorageAsMut, -}; +use fuel_core_storage::{tables::ContractsRawCode, StorageAsMut}; use fuel_core_types::{ - fuel_tx::{ - TxPointer, - UtxoId, - }, + fuel_tx::{TxPointer, UtxoId}, fuel_types::Word, fuel_vm::consts::WORD_SIZE, }; @@ -44,6 +35,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let contract_id = ContractId::zeroed(); let (mut service, rt) = service_with_contract_id(contract_id); let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); + let asset_id = AssetId::zeroed(); + let contract_id = ContractId::zeroed(); + let script_data = script_data(&contract_id, &asset_id); // run_group_ref( // &mut c.benchmark_group("bal"), @@ -56,29 +50,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ]) // .with_dummy_contract(contract), // ); - let asset_id = AssetId::zeroed(); - let contract_id = ContractId::zeroed(); let contract_instructions = vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; - let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - ]; + let mut instructions = setup_instructions(); + instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); replace_contract_in_service(&mut service, &contract_id, contract_instructions); - let script_data: Vec<_> = contract_id - .iter() - .copied() - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain(AssetId::default().iter().copied()) - .collect(); - let id = "contract/bal contract"; run_with_service( id, @@ -91,15 +69,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { &mut rng, ); - let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), - op::bal(0x13, 0x11, 0x10), - op::jmpb(RegId::ZERO, 0), - ]; + let mut instructions = setup_instructions(); + instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); let id = "contract/bal script"; run_with_service( @@ -121,10 +92,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { run( "contract/bhei", group, - vec![op::bhei(0x10), - op::jmpb(RegId::ZERO, 0)], + vec![op::bhei(0x10), op::jmpb(RegId::ZERO, 0)], vec![], - ) + ); // run_group_ref( // &mut c.benchmark_group("bhsh"), @@ -143,9 +113,10 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::aloc(0x10), op::move_(0x10, RegId::HP), op::bhsh(0x10, RegId::ZERO), - op::jmpb(RegId::ZERO, 0)], + op::jmpb(RegId::ZERO, 0), + ], vec![], - ) + ); // run_group_ref( // &mut c.benchmark_group("burn"), @@ -154,15 +125,18 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .expect("failed to prepare contract") // .prepend_prepare_script(vec![op::movi(0x10, 32), op::aloc(0x10)]), // ); - - // run( - // "contract/burn", - // group, - // vec![op::movi(0x10, 32), op::aloc(0x10), - // op::burn(RegId::ONE, RegId::HP), - // op::jmpb(RegId::ZERO, 0)], - // vec![], - // ); + let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/burn", + group, + call_contract_once(), + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); // Call @@ -184,20 +158,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { replace_contract_in_service(&mut service, &contract_id, contract_instructions); - let script_data = contract_id - .iter() - .copied() - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain(AssetId::default().iter().copied()) - .collect(); - let id = format!("contract/call {:?}", size); run_with_service( &id, group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -222,7 +188,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::aloc(0x10), op::move_(0x10, RegId::HP), op::cb(0x10), - op::jmpb(RegId::ZERO, 0)], + op::jmpb(RegId::ZERO, 0), + ], vec![], ); @@ -272,6 +239,36 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // } // // ccp.finish(); + for i in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(i as usize) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x13, i.try_into().unwrap()), + op::movi(0x14, i.try_into().unwrap()), + op::movi(0x15, i.try_into().unwrap()), + op::add(0x15, 0x15, 0x15), + op::addi(0x15, 0x15, 32), + op::aloc(0x15), + op::move_(0x15, RegId::HP), + op::ccp(0x15, 0x10, RegId::ZERO, 0x13), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract_instructions); + run_with_service( + id, + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + } // { // let mut input = VmBench::contract(rng, op::croo(0x14, 0x16)) @@ -285,6 +282,35 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref(&mut c.benchmark_group("croo"), "croo", input); // } + // TODO: What is the post_call stuff doing here? + let contract = vec![ + op::croo(0x14, 0x16), + // op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), + // op::movi(0x15, 2000), + // op::aloc(0x15), + // op::move_(0x14, RegId::HP), + op::ret(RegId::ZERO), + ]; + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), + op::movi(0x15, 2000), + op::aloc(0x15), + op::move_(0x14, RegId::HP), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + ]); + replace_contract_in_service(&mut service, &contract_id, contract_instructions); + run_with_service( + "contract/croo", + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + // let mut csiz = c.benchmark_group("csiz"); // // for i in linear.clone() { @@ -313,6 +339,30 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // csiz.finish(); + for size in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(size as usize) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::csiz(0x11, 0x10), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract_instructions); + run_with_service( + id, + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + } + // let mut ldc = c.benchmark_group("ldc"); // // for i in linear.clone() { @@ -354,6 +404,35 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // ldc.finish(); + for size in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(size as usize) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + op::movi(0x13, size.try_into().unwrap()), + op::ldc(0x10, RegId::ZERO, 0x13), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract_instructions); + run_with_service( + id, + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + } + // log // logd @@ -528,9 +607,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { run( "contract/time", group, - vec![op::movi(0x10, 0), + vec![ + op::movi(0x10, 0), op::time(0x11, 0x10), - op::jmpb(RegId::ZERO, 0)], + op::jmpb(RegId::ZERO, 0), + ], vec![], ) @@ -601,3 +682,34 @@ fn replace_contract_in_service( .insert(contract_id, &contract_bytecode) .unwrap(); } + +fn script_data(contract_id: &ContractId, asset_id: &AssetId) -> Vec { + contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(asset_id.iter().copied()) + .collect() +} + +fn setup_instructions() -> Vec { + vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, 100_000), + ] +} + +fn call_contract_repeat() -> Vec { + setup_instructions().extend(vec![ + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]) +} + +fn call_contract_once() -> Vec { + setup_instructions().extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]) +} From 31fa1215f3be8008a9f33bc791ed93aea84f1e62 Mon Sep 17 00:00:00 2001 From: mitchell Date: Tue, 31 Oct 2023 13:17:54 -0700 Subject: [PATCH 11/36] WIP Fix some compelation --- .../benches/block_target_gas_set/contract.rs | 56 +++++++++++++++---- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index a49371070d4..273a82e954b 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -257,7 +257,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::ccp(0x15, 0x10, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract_instructions); + replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( id, group, @@ -299,7 +299,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::move_(0x14, RegId::HP), op::call(0x10, RegId::ZERO, 0x11, 0x12), ]); - replace_contract_in_service(&mut service, &contract_id, contract_instructions); + replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( "contract/croo", group, @@ -350,7 +350,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::csiz(0x11, 0x10), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract_instructions); + replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( id, group, @@ -411,16 +411,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { .collect(); let mut instructions = setup_instructions(); instructions.extend(vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), op::movi(0x13, size.try_into().unwrap()), op::ldc(0x10, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract_instructions); + replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( id, group, @@ -448,6 +443,20 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .expect("failed to prepare contract"), // ); + let contract = vec![op::mint(RegId::ONE, RegId::ZERO)]; + let instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/mint", + group, + instructions, + script_data, + &service, + contract_id, + &rt, + &mut rng, + ); + // retd // rvrt @@ -495,6 +504,25 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // smo.finish(); + for size in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(size as usize) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), + // Offset 32 + 8 + 8 + 32 + op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer + op::addi(0x16, 0x15, 32), // data ppinter + op::movi(0x17, size.try_into().unwrap()), // data length + op::movi(0x18, 10), // coins to send + op::smo(0x15, 0x16, 0x17, 0x18), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract); + } + // let mut scwq = c.benchmark_group("scwq"); // // for i in linear.clone() { @@ -704,12 +732,16 @@ fn setup_instructions() -> Vec { } fn call_contract_repeat() -> Vec { - setup_instructions().extend(vec![ + let mut instructions = setup_instructions(); + instructions.extend(vec![ op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), - ]) + ]); + instructions } fn call_contract_once() -> Vec { - setup_instructions().extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]) + let mut instructions = setup_instructions(); + instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); + instructions } From 919127fa6d3ef7d0b38351f75cbe94e19d3979c6 Mon Sep 17 00:00:00 2001 From: Turner Date: Tue, 31 Oct 2023 17:04:26 -0700 Subject: [PATCH 12/36] WIP Fix some benches, add more --- .../benches/block_target_gas_set/contract.rs | 212 +++++++++++++----- 1 file changed, 151 insertions(+), 61 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 273a82e954b..4c0ced80954 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,8 +1,17 @@ -use crate::{utils::arb_dependent_cost_values, *}; +use crate::{ + utils::arb_dependent_cost_values, + *, +}; use fuel_core::service::FuelService; -use fuel_core_storage::{tables::ContractsRawCode, StorageAsMut}; +use fuel_core_storage::{ + tables::ContractsRawCode, + StorageAsMut, +}; use fuel_core_types::{ - fuel_tx::{TxPointer, UtxoId}, + fuel_tx::{ + TxPointer, + UtxoId, + }, fuel_types::Word, fuel_vm::consts::WORD_SIZE, }; @@ -50,39 +59,43 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ]) // .with_dummy_contract(contract), // ); - let contract_instructions = vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; - - let mut instructions = setup_instructions(); - instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); + { + let contract_instructions = + vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; - replace_contract_in_service(&mut service, &contract_id, contract_instructions); + let mut instructions = setup_instructions(); + instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); - let id = "contract/bal contract"; - run_with_service( - id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + replace_contract_in_service(&mut service, &contract_id, contract_instructions); - let mut instructions = setup_instructions(); - instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); + let id = "contract/bal contract"; + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } + { + let mut instructions = setup_instructions(); + instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); - let id = "contract/bal script"; - run_with_service( - id, - group, - instructions, - script_data, - &service, - contract_id, - &rt, - &mut rng, - ); + let id = "contract/bal script"; + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } // run_group_ref( // &mut c.benchmark_group("bhei"), @@ -125,18 +138,27 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .expect("failed to prepare contract") // .prepend_prepare_script(vec![op::movi(0x10, 32), op::aloc(0x10)]), // ); - let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/burn", - group, - call_contract_once(), - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + { + let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; + let mut instructions = setup_instructions(); + // TODO: I don't know why we need these extra ops + instructions.extend(vec![ + op::movi(0x10, 32), + op::aloc(0x10), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + ]); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/burn", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } // Call @@ -258,11 +280,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/ccp {:?}", i); run_with_service( - id, + &id, group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -282,29 +305,23 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref(&mut c.benchmark_group("croo"), "croo", input); // } - // TODO: What is the post_call stuff doing here? - let contract = vec![ - op::croo(0x14, 0x16), - // op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), - // op::movi(0x15, 2000), - // op::aloc(0x15), - // op::move_(0x14, RegId::HP), - op::ret(RegId::ZERO), - ]; + let contract = vec![op::croo(0x14, 0x16), op::ret(RegId::ZERO)]; let mut instructions = setup_instructions(); + // TODO: What is the "post_call" stuff doing? instructions.extend(vec![ op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), op::movi(0x15, 2000), op::aloc(0x15), op::move_(0x14, RegId::HP), op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), ]); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( "contract/croo", group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -351,11 +368,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/csiz {:?}", size); run_with_service( - id, + &id, group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -416,11 +434,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/ldc {:?}", size); run_with_service( - id, + &id, group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -450,7 +469,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { "contract/mint", group, instructions, - script_data, + script_data.clone(), &service, contract_id, &rt, @@ -521,6 +540,17 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/smo {:?}", size); + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); } // let mut scwq = c.benchmark_group("scwq"); @@ -549,6 +579,37 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // scwq.finish(); + // TODO: Is this going to mess up other benchmarks? + for size in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(size as usize) + .chain(vec![op::scwq(0x11, 0x29, 0x12)]) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, size.try_into().unwrap()), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/scwq {:?}", size); + // run_with_service( + // &id, + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); + } + // let mut srwq = c.benchmark_group("srwq"); // // for i in linear.clone() { @@ -653,6 +714,27 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref(&mut c.benchmark_group("tr"), "tr", input); // } + { + let contract = vec![op::tr(0x15, 0x14, 0x15), op::ret(RegId::ZERO)]; + let instructions = vec![ + op::movi(0x15, 2000), + op::movi(0x14, 100), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]; + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/tr", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } + // { // let mut input = VmBench::contract_using_db( // rng, @@ -691,6 +773,14 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // run_group_ref(&mut c.benchmark_group("tro"), "tro", input); // } + + { + let contract = vec![ + op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), + op::ret(RegId::ZERO), + ]; + + } } fn replace_contract_in_service( From e58abf76bb79c438e6108f386edbc18d8cd3d509 Mon Sep 17 00:00:00 2001 From: Turner Date: Wed, 1 Nov 2023 17:03:34 -0700 Subject: [PATCH 13/36] Add `scwq` bench, but comment out because undercosted --- .../benches/block_target_gas_set/contract.rs | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 4c0ced80954..5413c16173b 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -579,36 +579,33 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // scwq.finish(); - // TODO: Is this going to mess up other benchmarks? - for size in arb_dependent_cost_values() { - let contract = std::iter::repeat(op::noop()) - .take(size as usize) - .chain(vec![op::scwq(0x11, 0x29, 0x12)]) - .chain(vec![op::ret(RegId::ZERO)]) - .collect(); - let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, size.try_into().unwrap()), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), - ]); - replace_contract_in_service(&mut service, &contract_id, contract); - let id = format!("contract/scwq {:?}", size); - // run_with_service( - // &id, - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // ); - } + // TODO: This is way too under-costed, so it runs forever + // let size = 2620_u32; // 18bit integer maxes at 262144 + // let contract: Vec<_> = (0..100_u32) + // .map(|x| x * size) + // .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC + // .flatten() + // .collect(); + // let instructions = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, 10_000), + // op::movi(0x14, size), + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // ]; + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service( + // "contract/scwq", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); // let mut srwq = c.benchmark_group("srwq"); // @@ -702,7 +699,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ], vec![], - ) + ); // { // let mut input = @@ -779,7 +776,6 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), op::ret(RegId::ZERO), ]; - } } From e43b05b0fae53950578445c9dafa5873857793b6 Mon Sep 17 00:00:00 2001 From: Turner Date: Wed, 1 Nov 2023 17:40:02 -0700 Subject: [PATCH 14/36] Add all but tro and other sequential --- .../benches/block_target_gas_set/contract.rs | 268 ++++++++++++++---- 1 file changed, 213 insertions(+), 55 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 5413c16173b..4a41f76a5d9 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -447,9 +447,52 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // log + // run_group_ref( + // &mut c.benchmark_group("log"), + // "log", + // VmBench::new(op::log(0x10, 0x11, 0x12, 0x13)), + // ); + { + run( + "contract/log", + group, + vec![op::log(0x10, 0x11, 0x12, 0x13), op::jmpb(RegId::ZERO, 0)], + vec![], + ); + } - // logd + // let mut logd = c.benchmark_group("logd"); + // for i in &linear { + // logd.throughput(Throughput::Bytes(*i as u64)); + // run_group_ref( + // &mut logd, + // format!("{i}"), + // VmBench::new(op::logd(0x10, 0x11, RegId::ZERO, 0x13)) + // .with_prepare_script(vec![op::movi(0x13, *i)]), + // ); + // } + // logd.finish(); + { + for i in arb_dependent_cost_values() { + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x13, i.try_into().unwrap()), + op::logd(0x10, 0x11, RegId::ZERO, 0x13), + op::jmpb(RegId::ZERO, 0), + ]); + let id = format!("contract/logd {:?}", i); + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } + } // run_group_ref( // &mut c.benchmark_group("mint"), @@ -461,24 +504,97 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ) // .expect("failed to prepare contract"), // ); + { + let contract = vec![op::mint(RegId::ONE, RegId::ZERO)]; + let instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/mint", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } - let contract = vec![op::mint(RegId::ONE, RegId::ZERO)]; - let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/mint", - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + // run_group_ref( + // &mut c.benchmark_group("ret_contract"), + // "ret_contract", + // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), + // );" + { + let contract = vec![op::ret(RegId::ONE)]; + let instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/ret contract", + group, + call_contract_repeat(), + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } - // retd + // let mut retd_contract = c.benchmark_group("retd_contract"); + // for i in &linear { + // retd_contract.throughput(Throughput::Bytes(*i as u64)); + // run_group_ref( + // &mut retd_contract, + // format!("{i}"), + // VmBench::contract(rng, op::retd(RegId::ONE, 0x10)) + // .unwrap() + // .with_post_call(vec![op::movi(0x10, *i)]), + // ); + // } + // retd_contract.finish(); + { + for i in arb_dependent_cost_values() { + let contract = vec![ + op::movi(0x14, i.try_into().unwrap()), + op::retd(RegId::ONE, 0x14), + ]; + let mut instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/retd contract {:?}", i); + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } + } - // rvrt + // run_group_ref( + // &mut c.benchmark_group("rvrt_contract"), + // "rvrt_contract", + // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), + // ); + { + let contract = vec![op::rvrt(RegId::ONE)]; + let instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/rvrt contract", + group, + call_contract_repeat(), + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } // let mut smo = c.benchmark_group("smo"); // @@ -523,34 +639,36 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // smo.finish(); - for size in arb_dependent_cost_values() { - let contract = std::iter::repeat(op::noop()) - .take(size as usize) - .chain(vec![op::ret(RegId::ZERO)]) - .collect(); - let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), - // Offset 32 + 8 + 8 + 32 - op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer - op::addi(0x16, 0x15, 32), // data ppinter - op::movi(0x17, size.try_into().unwrap()), // data length - op::movi(0x18, 10), // coins to send - op::smo(0x15, 0x16, 0x17, 0x18), - op::jmpb(RegId::ZERO, 0), - ]); - replace_contract_in_service(&mut service, &contract_id, contract); - let id = format!("contract/smo {:?}", size); - run_with_service( - &id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + { + for size in arb_dependent_cost_values() { + let contract = std::iter::repeat(op::noop()) + .take(size as usize) + .chain(vec![op::ret(RegId::ZERO)]) + .collect(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), + // Offset 32 + 8 + 8 + 32 + op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer + op::addi(0x16, 0x15, 32), // data ppinter + op::movi(0x17, size.try_into().unwrap()), // data length + op::movi(0x18, 10), // coins to send + op::smo(0x15, 0x16, 0x17, 0x18), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract); + let id = format!("contract/smo {:?}", size); + run_with_service( + &id, + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } } // let mut scwq = c.benchmark_group("scwq"); @@ -607,6 +725,24 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // &mut rng, // ); + // { + // let mut input = + // VmBench::contract_using_db(rng, db.checkpoint(), op::srw(0x13, 0x14, 0x15)) + // .expect("failed to prepare contract"); + // input.prepare_script.extend(vec![op::movi(0x15, 2000)]); + // run_group_ref(&mut c.benchmark_group("srw"), "srw", input); + // } + + { + let contract = vec![op::srw(0x13, 0x14, 0x15), op::ret(RegId::ZERO)]; + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x15, 2000), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]); + } + // let mut srwq = c.benchmark_group("srwq"); // // for i in linear.clone() { @@ -644,6 +780,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // srwq.finish(); + // TODO: Add `srwq` benchmark + // run_group_ref( // &mut c.benchmark_group("sww"), // "sww", @@ -655,6 +793,22 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .expect("failed to prepare contract"), // ); + { + let contract = vec![op::sww(RegId::ZERO, 0x29, RegId::ONE), op::ret(RegId::ZERO)]; + let instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/sww", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } + // let mut swwq = c.benchmark_group("swwq"); // // for i in linear.clone() { @@ -684,22 +838,26 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // swwq.finish(); + // TODO: Add `swwq` benchmark + // run_group_ref( // &mut c.benchmark_group("time"), // "time", // VmBench::new(op::time(0x11, 0x10)).with_prepare_script(vec![op::movi(0x10, 0)]), // ); - run( - "contract/time", - group, - vec![ - op::movi(0x10, 0), - op::time(0x11, 0x10), - op::jmpb(RegId::ZERO, 0), - ], - vec![], - ); + { + run( + "contract/time", + group, + vec![ + op::movi(0x10, 0), + op::time(0x11, 0x10), + op::jmpb(RegId::ZERO, 0), + ], + vec![], + ); + } // { // let mut input = From 1b89fb7931bd254b5243d58bb4bcbe0e5994c3c5 Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 2 Nov 2023 12:26:52 -0700 Subject: [PATCH 15/36] Fix all but smo and tro --- benches/benches/block_target_gas.rs | 16 ++- .../benches/block_target_gas_set/contract.rs | 97 ++++++++++++------- 2 files changed, 78 insertions(+), 35 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 7491663f9e8..5eb8a26d452 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -192,10 +192,21 @@ fn service_with_contract_id( config.utxo_validation = false; config.block_production = Trigger::Instant; + // Override state size if the env var is set + let state_size_env_var = "STATE_SIZE"; + let state_size = if let Some(value) = std::env::var_os(state_size_env_var) { + let value = value.to_str().unwrap(); + let value = value.parse::().unwrap(); + println!("Overriding state size with {}", value); + value + } else { + STATE_SIZE + }; + database .init_contract_state( &contract_id, - (0..STATE_SIZE).map(|k| { + (0..state_size).map(|k| { let mut key = Bytes32::zeroed(); key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); (key, key) @@ -205,7 +216,7 @@ fn service_with_contract_id( database .init_contract_balances( &contract_id, - (0..STATE_SIZE).map(|k| { + (0..state_size).map(|k| { let key = k / 2; let mut sub_id = Bytes32::zeroed(); sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); @@ -288,6 +299,7 @@ fn run_with_service( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); + dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 4a41f76a5d9..ecd58dab206 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -305,17 +305,16 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref(&mut c.benchmark_group("croo"), "croo", input); // } - let contract = vec![op::croo(0x14, 0x16), op::ret(RegId::ZERO)]; - let mut instructions = setup_instructions(); // TODO: What is the "post_call" stuff doing? - instructions.extend(vec![ + let contract = vec![ op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), op::movi(0x15, 2000), op::aloc(0x15), op::move_(0x14, RegId::HP), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), - ]); + op::croo(0x14, 0x16), + op::ret(RegId::ZERO), + ]; + let mut instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( "contract/croo", @@ -505,7 +504,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .expect("failed to prepare contract"), // ); { - let contract = vec![op::mint(RegId::ONE, RegId::ZERO)]; + let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( @@ -526,7 +525,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), // );" { - let contract = vec![op::ret(RegId::ONE)]; + let contract = vec![op::ret(RegId::ONE), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( @@ -580,21 +579,23 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // "rvrt_contract", // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), // ); - { - let contract = vec![op::rvrt(RegId::ONE)]; - let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/rvrt contract", - group, - call_contract_repeat(), - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); - } + + // TODO: Is `rvrt` even possible to test? + // { + // let contract = vec![op::rvrt(RegId::ONE), op::ret(RegId::ZERO)]; + // let instructions = call_contract_repeat(); + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service( + // "contract/rvrt contract", + // group, + // call_contract_repeat(), + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); + // } // let mut smo = c.benchmark_group("smo"); // @@ -639,14 +640,10 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // smo.finish(); + // TODO: Figure out the input stuff? { for size in arb_dependent_cost_values() { - let contract = std::iter::repeat(op::noop()) - .take(size as usize) - .chain(vec![op::ret(RegId::ZERO)]) - .collect(); - let mut instructions = setup_instructions(); - instructions.extend(vec![ + let contract = vec![ op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), // Offset 32 + 8 + 8 + 32 op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer @@ -654,8 +651,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::movi(0x17, size.try_into().unwrap()), // data length op::movi(0x18, 10), // coins to send op::smo(0x15, 0x16, 0x17, 0x18), - op::jmpb(RegId::ZERO, 0), - ]); + op::ret(RegId::ZERO), + ]; + let mut instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/smo {:?}", size); run_with_service( @@ -741,6 +739,17 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/srw", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); } // let mut srwq = c.benchmark_group("srwq"); @@ -871,12 +880,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![op::tr(0x15, 0x14, 0x15), op::ret(RegId::ZERO)]; - let instructions = vec![ + let mut instructions = setup_instructions(); + instructions.extend(vec![ op::movi(0x15, 2000), op::movi(0x14, 100), op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), - ]; + ]); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( "contract/tr", @@ -929,11 +939,32 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // run_group_ref(&mut c.benchmark_group("tro"), "tro", input); // } + // TODO: Fix "OutputNotFound" error { let contract = vec![ op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), op::ret(RegId::ZERO), ]; + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x14, 100), + op::movi(0x15, 0), + op::movi(0x20, 32), + op::aloc(0x20), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/tro", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); } } From 0769262536a14dcbbccd20caecac36a707fd2553 Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 2 Nov 2023 14:14:10 -0700 Subject: [PATCH 16/36] Cleanup comments, update CHANGELOG --- CHANGELOG.md | 6 +- .../benches/block_target_gas_set/contract.rs | 267 ++---------------- 2 files changed, 22 insertions(+), 251 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 908294ad1d3..1bffb7ee41a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Description of the upcoming release here. ### Added +- [#1453](https://github.com/FuelLabs/fuel-core/pull/1453): Add the majority of the "sanity" benchmarks for contract opcodes. - [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Added support of bloom filter for RocksDB tables and increased the block cache. - [#1642](https://github.com/FuelLabs/fuel-core/pull/1462): Added benchmark to measure the performance of contract state and contract ID calculation; use for gas costing. - [#1465](https://github.com/FuelLabs/fuel-core/pull/1465): Improvements for keygen cli and crates @@ -46,10 +47,6 @@ Description of the upcoming release here. ### Changed -- [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Replaced usage of `MemoryTransactionView` by `Checkpoint` database in the benchmarks. -- [#1466](https://github.com/FuelLabs/fuel-core/pull/1466): Handling overflows during arithmetic operations. -- [#1468](https://github.com/FuelLabs/fuel-core/pull/1468): Bumped version of the `fuel-vm` to `v0.40.0`. It brings some breaking changes into consensus parameters API because of changes in the underlying types. -- [#1460](https://github.com/FuelLabs/fuel-core/pull/1460): Change tracking branch from main to master for releasy tests. - [#1440](https://github.com/FuelLabs/fuel-core/pull/1440): Don't report reserved nodes that send invalid transactions. - [#1439](https://github.com/FuelLabs/fuel-core/pull/1439): Reduced memory BMT consumption during creation of the header. - [#1434](https://github.com/FuelLabs/fuel-core/pull/1434): Continue gossiping transactions to reserved peers regardless of gossiping reputation score. @@ -75,7 +72,6 @@ Description of the upcoming release here. - [#1408](https://github.com/FuelLabs/fuel-core/pull/1408): Update gas benchmarks for storage opcodes to use a pre-populated database to get more accurate worst-case costs. #### Breaking -- [#1464](https://github.com/FuelLabs/fuel-core/pull/1464): Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems. The change affects some endpoints that now require lesser integers. - [#1432](https://github.com/FuelLabs/fuel-core/pull/1432): All subscriptions and requests have a TTL now. So each subscription lifecycle is limited in time. If the subscription is closed because of TTL, it means that you subscribed after your transaction had been dropped by the network. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The recipient is a `ContractId` instead of `Address`. The block producer should deploy its contract to receive the transaction fee. The collected fee is zero until the recipient contract is set. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The `Mint` transaction is reworked with new fields to support the account-base model. It affects serialization and deserialization of the transaction and also affects GraphQL schema. diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index ecd58dab206..2d46532ba02 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -48,17 +48,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let contract_id = ContractId::zeroed(); let script_data = script_data(&contract_id, &asset_id); - // run_group_ref( - // &mut c.benchmark_group("bal"), - // "bal", - // VmBench::new(op::bal(0x10, 0x10, 0x11)) - // .with_data(asset.iter().chain(contract.iter()).copied().collect()) - // .with_prepare_script(vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, asset.len().try_into().unwrap()), - // ]) - // .with_dummy_contract(contract), - // ); + // bal contract { let contract_instructions = vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; @@ -97,11 +87,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // run_group_ref( - // &mut c.benchmark_group("bhei"), - // "bhei", - // VmBench::new(op::bhei(0x10)), - // ); + // bhei run( "contract/bhei", group, @@ -109,15 +95,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { vec![], ); - // run_group_ref( - // &mut c.benchmark_group("bhsh"), - // "bhsh", - // VmBench::new(op::bhsh(0x10, RegId::ZERO)).with_prepare_script(vec![ - // op::movi(0x10, Bytes32::LEN.try_into().unwrap()), - // op::aloc(0x10), - // op::move_(0x10, RegId::HP), - // ]), - // ); + // bhsh run( "contract/bhsh", group, @@ -131,13 +109,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { vec![], ); - // run_group_ref( - // &mut c.benchmark_group("burn"), - // "burn", - // VmBench::contract_using_db(rng, db.checkpoint(), op::burn(RegId::ONE, RegId::HP)) - // .expect("failed to prepare contract") - // .prepend_prepare_script(vec![op::movi(0x10, 32), op::aloc(0x10)]), - // ); + // burn { let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; let mut instructions = setup_instructions(); @@ -160,8 +132,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // Call - + // call for size in arb_dependent_cost_values() { let mut contract_instructions = std::iter::repeat(op::noop()) .take(size as usize) @@ -193,15 +164,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // run_group_ref( - // &mut c.benchmark_group("cb"), - // "cb", - // VmBench::new(op::cb(0x10)).with_prepare_script(vec![ - // op::movi(0x10, Bytes32::LEN.try_into().unwrap()), - // op::aloc(0x10), - // op::move_(0x10, RegId::HP), - // ]), - // ); + // cb run( "contract/cb", group, @@ -215,52 +178,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { vec![], ); - // let mut ccp = c.benchmark_group("ccp"); - // - // for i in linear.clone() { - // let mut code = vec![0u8; i as usize]; - // - // rng.fill_bytes(&mut code); - // - // let code = ContractCode::from(code); - // let id = code.id; - // - // let data = id - // .iter() - // .copied() - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain(AssetId::default().iter().copied()) - // .collect(); - // - // let prepare_script = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, 100_000), - // op::movi(0x13, i.try_into().unwrap()), - // op::movi(0x14, i.try_into().unwrap()), - // op::movi(0x15, i.try_into().unwrap()), - // op::add(0x15, 0x15, 0x15), - // op::addi(0x15, 0x15, 32), - // op::aloc(0x15), - // op::move_(0x15, RegId::HP), - // ]; - // - // ccp.throughput(Throughput::Bytes(i)); - // - // run_group_ref( - // &mut ccp, - // format!("{i}"), - // VmBench::new(op::ccp(0x15, 0x10, RegId::ZERO, 0x13)) - // .with_contract_code(code) - // .with_data(data) - // .with_prepare_script(prepare_script), - // ); - // } - // - // ccp.finish(); + // ccp for i in arb_dependent_cost_values() { let contract = std::iter::repeat(op::noop()) .take(i as usize) @@ -293,19 +211,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // { - // let mut input = VmBench::contract(rng, op::croo(0x14, 0x16)) - // .expect("failed to prepare contract"); - // input.post_call.extend(vec![ - // op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), - // op::movi(0x15, 2000), - // op::aloc(0x15), - // op::move_(0x14, RegId::HP), - // ]); - // run_group_ref(&mut c.benchmark_group("croo"), "croo", input); - // } - - // TODO: What is the "post_call" stuff doing? + // croo let contract = vec![ op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), op::movi(0x15, 2000), @@ -327,34 +233,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { &mut rng, ); - // let mut csiz = c.benchmark_group("csiz"); - // - // for i in linear.clone() { - // let mut code = vec![0u8; i as usize]; - // - // rng.fill_bytes(&mut code); - // - // let code = ContractCode::from(code); - // let id = code.id; - // - // let data = id.iter().copied().collect(); - // - // let prepare_script = vec![op::gtf_args(0x10, 0x00, GTFArgs::ScriptData)]; - // - // csiz.throughput(Throughput::Bytes(i)); - // - // run_group_ref( - // &mut csiz, - // format!("{i}"), - // VmBench::new(op::csiz(0x11, 0x10)) - // .with_contract_code(code) - // .with_data(data) - // .with_prepare_script(prepare_script), - // ); - // } - // - // csiz.finish(); - + // csiz for size in arb_dependent_cost_values() { let contract = std::iter::repeat(op::noop()) .take(size as usize) @@ -380,47 +259,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // let mut ldc = c.benchmark_group("ldc"); - // - // for i in linear.clone() { - // let mut code = vec![0u8; i as usize]; - // - // rng.fill_bytes(&mut code); - // - // let code = ContractCode::from(code); - // let id = code.id; - // - // let data = id - // .iter() - // .copied() - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain((0 as Word).to_be_bytes().iter().copied()) - // .chain(AssetId::default().iter().copied()) - // .collect(); - // - // let prepare_script = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, 100_000), - // op::movi(0x13, i.try_into().unwrap()), - // ]; - // - // ldc.throughput(Throughput::Bytes(i)); - // - // run_group_ref( - // &mut ldc, - // format!("{i}"), - // VmBench::new(op::ldc(0x10, RegId::ZERO, 0x13)) - // .with_contract_code(code) - // .with_data(data) - // .with_prepare_script(prepare_script), - // ); - // } - // - // ldc.finish(); - + // ldc for size in arb_dependent_cost_values() { let contract = std::iter::repeat(op::noop()) .take(size as usize) @@ -446,11 +285,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // run_group_ref( - // &mut c.benchmark_group("log"), - // "log", - // VmBench::new(op::log(0x10, 0x11, 0x12, 0x13)), - // ); + // log { run( "contract/log", @@ -460,17 +295,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // let mut logd = c.benchmark_group("logd"); - // for i in &linear { - // logd.throughput(Throughput::Bytes(*i as u64)); - // run_group_ref( - // &mut logd, - // format!("{i}"), - // VmBench::new(op::logd(0x10, 0x11, RegId::ZERO, 0x13)) - // .with_prepare_script(vec![op::movi(0x13, *i)]), - // ); - // } - // logd.finish(); + // logd { for i in arb_dependent_cost_values() { let mut instructions = setup_instructions(); @@ -493,16 +318,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } } - // run_group_ref( - // &mut c.benchmark_group("mint"), - // "mint", - // VmBench::contract_using_db( - // rng, - // db.checkpoint(), - // op::mint(RegId::ONE, RegId::ZERO), - // ) - // .expect("failed to prepare contract"), - // ); + // mint { let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); @@ -519,11 +335,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // run_group_ref( - // &mut c.benchmark_group("ret_contract"), - // "ret_contract", - // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), - // );" + // ret contract { let contract = vec![op::ret(RegId::ONE), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); @@ -540,18 +352,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // let mut retd_contract = c.benchmark_group("retd_contract"); - // for i in &linear { - // retd_contract.throughput(Throughput::Bytes(*i as u64)); - // run_group_ref( - // &mut retd_contract, - // format!("{i}"), - // VmBench::contract(rng, op::retd(RegId::ONE, 0x10)) - // .unwrap() - // .with_post_call(vec![op::movi(0x10, *i)]), - // ); - // } - // retd_contract.finish(); + // retd contract { for i in arb_dependent_cost_values() { let contract = vec![ @@ -695,7 +496,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // // scwq.finish(); - // TODO: This is way too under-costed, so it runs forever + // TODO: This is way too under-costed, so it runs too long and will complete before running out + // of gas at 100_000. // let size = 2620_u32; // 18bit integer maxes at 262144 // let contract: Vec<_> = (0..100_u32) // .map(|x| x * size) @@ -723,13 +525,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // &mut rng, // ); - // { - // let mut input = - // VmBench::contract_using_db(rng, db.checkpoint(), op::srw(0x13, 0x14, 0x15)) - // .expect("failed to prepare contract"); - // input.prepare_script.extend(vec![op::movi(0x15, 2000)]); - // run_group_ref(&mut c.benchmark_group("srw"), "srw", input); - // } + // srw { let contract = vec![op::srw(0x13, 0x14, 0x15), op::ret(RegId::ZERO)]; @@ -791,16 +587,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // TODO: Add `srwq` benchmark - // run_group_ref( - // &mut c.benchmark_group("sww"), - // "sww", - // VmBench::contract_using_db( - // rng, - // db.checkpoint(), - // op::sww(RegId::ZERO, 0x29, RegId::ONE), - // ) - // .expect("failed to prepare contract"), - // ); + // sww { let contract = vec![op::sww(RegId::ZERO, 0x29, RegId::ONE), op::ret(RegId::ZERO)]; @@ -849,11 +636,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // TODO: Add `swwq` benchmark - // run_group_ref( - // &mut c.benchmark_group("time"), - // "time", - // VmBench::new(op::time(0x11, 0x10)).with_prepare_script(vec![op::movi(0x10, 0)]), - // ); + // time { run( @@ -868,15 +651,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // { - // let mut input = - // VmBench::contract_using_db(rng, db.checkpoint(), op::tr(0x15, 0x14, 0x15)) - // .expect("failed to prepare contract"); - // input - // .prepare_script - // .extend(vec![op::movi(0x15, 2000), op::movi(0x14, 100)]); - // run_group_ref(&mut c.benchmark_group("tr"), "tr", input); - // } + // tr { let contract = vec![op::tr(0x15, 0x14, 0x15), op::ret(RegId::ZERO)]; From 7cc042840221248751c02369ab51822ce461cbe6 Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 2 Nov 2023 16:28:27 -0700 Subject: [PATCH 17/36] Fix smo --- benches/benches/block_target_gas.rs | 40 +++++- .../benches/block_target_gas_set/contract.rs | 115 +++++++++++------- 2 files changed, 109 insertions(+), 46 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 5eb8a26d452..434fe366c34 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -55,6 +55,7 @@ use fuel_core_types::{ Bytes32, ContractId, }, + fuel_vm::checked_transaction::EstimatePredicates, }; mod utils; @@ -115,7 +116,7 @@ fn run( .add_unsigned_coin_input( SecretKey::random(&mut rng), rng.gen(), - u64::MAX, + u64::MAX / 2, AssetId::BASE, Default::default(), Default::default(), @@ -246,6 +247,30 @@ fn run_with_service( contract_id: ContractId, rt: &tokio::runtime::Runtime, rng: &mut rand::rngs::StdRng, +) { + run_with_service_with_extra_inputs( + id, + group, + script, + script_data, + service, + contract_id, + rt, + rng, + vec![], + ); +} + +fn run_with_service_with_extra_inputs( + id: &str, + group: &mut BenchmarkGroup, + script: Vec, + script_data: Vec, + service: &fuel_core::service::FuelService, + contract_id: ContractId, + rt: &tokio::runtime::Runtime, + rng: &mut rand::rngs::StdRng, + extra_inputs: Vec, ) { group.bench_function(id, |b| { const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; @@ -266,12 +291,12 @@ fn run_with_service( .add_unsigned_coin_input( SecretKey::random(rng), rng.gen(), - u64::MAX, + u32::MAX as u64, AssetId::BASE, Default::default(), Default::default(), ); - let input_count = tx_builder.inputs().len(); + let mut input_count = tx_builder.inputs().len(); let contract_input = Input::contract( UtxoId::default(), @@ -285,7 +310,12 @@ fn run_with_service( tx_builder .add_input(contract_input) .add_output(contract_output); - let tx = tx_builder.finalize_as_transaction(); + + for input in &extra_inputs { + tx_builder.add_input(input.clone()); + } + let mut tx = tx_builder.finalize_as_transaction(); + tx.estimate_predicates(&shared.config.chain_conf.consensus_parameters.clone().into()).unwrap(); async move { let tx_id = tx.id(&shared.config.chain_conf.consensus_parameters.chain_id); @@ -299,7 +329,7 @@ fn run_with_service( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - dbg!(&res.tx_status); + // dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 2d46532ba02..c4939b6eee5 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -12,7 +12,10 @@ use fuel_core_types::{ TxPointer, UtxoId, }, - fuel_types::Word, + fuel_types::{ + Address, + Word, + }, fuel_vm::consts::WORD_SIZE, }; @@ -165,18 +168,20 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } // cb - run( - "contract/cb", - group, - vec![ - op::movi(0x10, Bytes32::LEN.try_into().unwrap()), - op::aloc(0x10), - op::move_(0x10, RegId::HP), - op::cb(0x10), - op::jmpb(RegId::ZERO, 0), - ], - vec![], - ); + { + run( + "contract/cb", + group, + vec![ + op::movi(0x10, Bytes32::LEN.try_into().unwrap()), + op::aloc(0x10), + op::move_(0x10, RegId::HP), + op::cb(0x10), + op::jmpb(RegId::ZERO, 0), + ], + vec![], + ); + } // ccp for i in arb_dependent_cost_values() { @@ -212,26 +217,28 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } // croo - let contract = vec![ - op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), - op::movi(0x15, 2000), - op::aloc(0x15), - op::move_(0x14, RegId::HP), - op::croo(0x14, 0x16), - op::ret(RegId::ZERO), - ]; - let mut instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/croo", - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + { + let contract = vec![ + op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), + op::movi(0x15, 2000), + op::aloc(0x15), + op::move_(0x14, RegId::HP), + op::croo(0x14, 0x16), + op::ret(RegId::ZERO), + ]; + let mut instructions = call_contract_repeat(); + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/croo", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); + } // csiz for size in arb_dependent_cost_values() { @@ -381,9 +388,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // VmBench::contract(rng, op::ret(RegId::ONE)).unwrap(), // ); - // TODO: Is `rvrt` even possible to test? + // TODO: Is `rvrt` even possible to bench? // { - // let contract = vec![op::rvrt(RegId::ONE), op::ret(RegId::ZERO)]; + // let contract = vec![op::rvrt(RegId::ONE)]; // let instructions = call_contract_repeat(); // replace_contract_in_service(&mut service, &contract_id, contract); // run_with_service( @@ -443,21 +450,46 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // TODO: Figure out the input stuff? { - for size in arb_dependent_cost_values() { + let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + let owner = Input::predicate_owner(&predicate); + let coin_input = Input::coin_predicate( + Default::default(), + owner, + u32::MAX as Word, + AssetId::zeroed(), + Default::default(), + Default::default(), + Default::default(), + predicate, + vec![], + ); + let extra_inputs = vec![coin_input]; + for i in arb_dependent_cost_values() { let contract = vec![ op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), // Offset 32 + 8 + 8 + 32 op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer op::addi(0x16, 0x15, 32), // data ppinter - op::movi(0x17, size.try_into().unwrap()), // data length - op::movi(0x18, 10), // coins to send + op::movi(0x17, i.try_into().unwrap()), // data length op::smo(0x15, 0x16, 0x17, 0x18), op::ret(RegId::ZERO), ]; - let mut instructions = call_contract_repeat(); + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x18, 10), // coins to send + op::call(0x10, 0x18, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]); replace_contract_in_service(&mut service, &contract_id, contract); - let id = format!("contract/smo {:?}", size); - run_with_service( + let mut data = script_data.clone(); + data.extend( + Address::new([1u8; 32]) + .iter() + .copied() + .chain(vec![2u8; i as usize]), + ); + let id = format!("contract/smo {:?}", i); + run_with_service_with_extra_inputs( &id, group, instructions, @@ -466,6 +498,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { contract_id, &rt, &mut rng, + extra_inputs.clone(), ); } } From c51a09216925152a859b39c749fb369450204a9e Mon Sep 17 00:00:00 2001 From: Turner Date: Thu, 2 Nov 2023 17:15:34 -0700 Subject: [PATCH 18/36] Comment out `tro` --- benches/benches/block_target_gas.rs | 9 +- .../benches/block_target_gas_set/contract.rs | 122 +++++++++--------- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 434fe366c34..ec2d468e859 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -258,6 +258,7 @@ fn run_with_service( rt, rng, vec![], + vec![], ); } @@ -271,6 +272,7 @@ fn run_with_service_with_extra_inputs( rt: &tokio::runtime::Runtime, rng: &mut rand::rngs::StdRng, extra_inputs: Vec, + extra_outputs: Vec, ) { group.bench_function(id, |b| { const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; @@ -314,6 +316,11 @@ fn run_with_service_with_extra_inputs( for input in &extra_inputs { tx_builder.add_input(input.clone()); } + + for output in &extra_outputs { + tx_builder.add_output(output.clone()); + } + dbg!(&tx_builder.outputs().len()); let mut tx = tx_builder.finalize_as_transaction(); tx.estimate_predicates(&shared.config.chain_conf.consensus_parameters.clone().into()).unwrap(); async move { @@ -329,7 +336,7 @@ fn run_with_service_with_extra_inputs( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - // dbg!(&res.tx_status); + dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index c4939b6eee5..326cce3d9bf 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -499,6 +499,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { &rt, &mut rng, extra_inputs.clone(), + vec![], ); } } @@ -708,72 +709,67 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // { - // let mut input = VmBench::contract_using_db( - // rng, - // db.checkpoint(), - // op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), - // ) - // .expect("failed to prepare contract"); - // let coin_output = Output::variable(Address::zeroed(), 100, AssetId::zeroed()); - // input.outputs.push(coin_output); - // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); - // let owner = Input::predicate_owner(&predicate); - // let coin_input = Input::coin_predicate( - // Default::default(), - // owner, - // 1000, - // AssetId::zeroed(), - // Default::default(), - // Default::default(), - // Default::default(), - // predicate, - // vec![], - // ); - // input.inputs.push(coin_input); + // tro + + // The `tro` benchmark is disabled because it would require many, many outputs, because each + // would get spent. But it's okay because that is putting a limit of 255 outputs per transaction + // and that protects us from an attacker exploiting a poorly priced `tro` instruction. + // { + // let amount = 100; // - // let index = input.outputs.len() - 1; - // input.prepare_script.extend(vec![ - // op::movi(0x14, 100), - // op::movi(0x15, index.try_into().unwrap()), - // op::movi(0x20, 32), - // op::aloc(0x20), - // ]); - // for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { - // input.prepare_script.push(op::movi(0x20, v as u32)); - // input.prepare_script.push(op::sb(RegId::HP, 0x20, i as u16)); - // } + // let contract = vec![ + // op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), + // op::ret(RegId::ZERO), + // ]; + // let mut instructions = setup_instructions(); + // instructions.extend(vec![ + // op::movi(0x14, amount), + // op::movi(0x15, 1), + // op::movi(0x20, 32), + // op::aloc(0x20), + // ]); // - // run_group_ref(&mut c.benchmark_group("tro"), "tro", input); + // for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { + // instructions.push(op::movi(0x20, v as u32)); + // instructions.push(op::sb(RegId::HP, 0x20, i as u16)); // } - - // TODO: Fix "OutputNotFound" error - { - let contract = vec![ - op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), - op::ret(RegId::ZERO), - ]; - let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::movi(0x14, 100), - op::movi(0x15, 0), - op::movi(0x20, 32), - op::aloc(0x20), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), - ]); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/tro", - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); - } + // + // instructions.extend(vec![ + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::jmpb(RegId::ZERO, 0), + // ]); + // + // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + // let owner = Input::predicate_owner(&predicate); + // let coin_input = Input::coin_predicate( + // Default::default(), + // owner, + // 1000, + // AssetId::zeroed(), + // Default::default(), + // Default::default(), + // Default::default(), + // predicate, + // vec![], + // ); + // let coin_output = Output::variable(Address::zeroed(), 0, AssetId::zeroed()); + // let extra_inputs = vec![coin_input]; + // let extra_outputs = vec![coin_output]; + // + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service_with_extra_inputs( + // "contract/tro", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // extra_inputs, + // extra_outputs, + // ); + // } } fn replace_contract_in_service( From 48ad9132956f86ef3c8c48db7d059e64c2753b30 Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 10:40:13 -0700 Subject: [PATCH 19/36] Add sequential op code benches but just comment out --- .../benches/block_target_gas_set/contract.rs | 271 ++++++------------ 1 file changed, 94 insertions(+), 177 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 326cce3d9bf..f3f229ecf5f 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,21 +1,9 @@ -use crate::{ - utils::arb_dependent_cost_values, - *, -}; +use crate::{utils::arb_dependent_cost_values, *}; use fuel_core::service::FuelService; -use fuel_core_storage::{ - tables::ContractsRawCode, - StorageAsMut, -}; +use fuel_core_storage::{tables::ContractsRawCode, StorageAsMut}; use fuel_core_types::{ - fuel_tx::{ - TxPointer, - UtxoId, - }, - fuel_types::{ - Address, - Word, - }, + fuel_tx::{TxPointer, UtxoId}, + fuel_types::{Address, Word}, fuel_vm::consts::WORD_SIZE, }; @@ -405,50 +393,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // } - // let mut smo = c.benchmark_group("smo"); - // - // for i in linear.clone() { - // let mut input = VmBench::contract_using_db( - // rng, - // db.checkpoint(), - // op::smo(0x15, 0x16, 0x17, 0x18), - // ) - // .expect("failed to prepare contract"); - // input.post_call.extend(vec![ - // op::gtf_args(0x15, 0x00, GTFArgs::ScriptData), - // // Offset 32 + 8 + 8 + 32 - // op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer - // op::addi(0x16, 0x15, 32), // data ppinter - // op::movi(0x17, i.try_into().unwrap()), // data length - // op::movi(0x18, 10), // coins to send - // ]); - // input.data.extend( - // Address::new([1u8; 32]) - // .iter() - // .copied() - // .chain(vec![2u8; i as usize]), - // ); - // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); - // let owner = Input::predicate_owner(&predicate); - // let coin_input = Input::coin_predicate( - // Default::default(), - // owner, - // Word::MAX, - // AssetId::zeroed(), - // Default::default(), - // Default::default(), - // Default::default(), - // predicate, - // vec![], - // ); - // input.inputs.push(coin_input); - // smo.throughput(Throughput::Bytes(i)); - // run_group_ref(&mut smo, format!("{i}"), input); - // } - // - // smo.finish(); + // amo - // TODO: Figure out the input stuff? { let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); let owner = Input::predicate_owner(&predicate); @@ -504,60 +450,37 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } } - // let mut scwq = c.benchmark_group("scwq"); - // - // for i in linear.clone() { - // let start_key = Bytes32::zeroed(); - // let data = start_key.iter().copied().collect::>(); - // - // let post_call = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, i as u32), - // ]; - // let mut bench = - // VmBench::contract_using_db(rng, db.checkpoint(), op::scwq(0x11, 0x29, 0x12)) - // .expect("failed to prepare contract") - // .with_post_call(post_call); - // bench.data.extend(data); - // - // scwq.throughput(Throughput::Bytes(i)); - // - // run_group_ref(&mut scwq, format!("{i}"), bench); - // } - // - // scwq.finish(); + // scwq - // TODO: This is way too under-costed, so it runs too long and will complete before running out + // TODO: This is under-costed, so it runs too long and will complete before running out // of gas at 100_000. - // let size = 2620_u32; // 18bit integer maxes at 262144 - // let contract: Vec<_> = (0..100_u32) - // .map(|x| x * size) - // .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC - // .flatten() - // .collect(); - // let instructions = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, 10_000), - // op::movi(0x14, size), - // op::call(0x10, RegId::ZERO, 0x11, 0x12), - // ]; - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service( - // "contract/scwq", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // ); + let size = 2620_u32; // 18bit integer maxes at 262144 + let contract: Vec<_> = (0..100_u32) + .map(|x| x * size) + .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC + .flatten() + .collect(); + let gas = 100_000; + let instructions = vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, gas), + op::movi(0x14, size), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + ]; + replace_contract_in_service(&mut service, &contract_id, contract); + run_with_service( + "contract/scwq", + group, + instructions, + script_data.clone(), + &service, + contract_id, + &rt, + &mut rng, + ); // srw @@ -582,44 +505,36 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // let mut srwq = c.benchmark_group("srwq"); - // - // for i in linear.clone() { - // let start_key = Bytes32::zeroed(); - // let data = start_key.iter().copied().collect::>(); - // - // let post_call = vec![ - // op::movi(0x16, i as u32), - // op::movi(0x17, 2000), - // op::move_(0x15, 0x16), - // op::muli(0x15, 0x15, 32), - // op::addi(0x15, 0x15, 1), - // op::aloc(0x15), - // op::move_(0x14, RegId::HP), - // ]; - // let mut bench = VmBench::contract(rng, op::srwq(0x14, 0x11, 0x27, 0x16)) - // .expect("failed to prepare contract") - // .with_post_call(post_call) - // .with_prepare_db(move |mut db| { - // let slots = (0u64..i).map(|key_number| { - // let mut key = Bytes32::zeroed(); - // key.as_mut()[..8].copy_from_slice(&key_number.to_be_bytes()); - // (key, key) - // }); - // db.database_mut() - // .init_contract_state(&contract, slots) - // .unwrap(); - // - // Ok(db) - // }); - // bench.data.extend(data); - // srwq.throughput(Throughput::Bytes(i)); - // run_group_ref(&mut srwq, format!("{i}"), bench); - // } - // - // srwq.finish(); + // srwq - // TODO: Add `srwq` benchmark + // TODO: This is under-costed, so it runs too long and will complete before running out of gas + // let size = 2620_u32; + // let contract = (0..2620) + // .map(|x| x * size) + // .map(|x| vec![op::movi(0x13, x), op::srwq(0x14, 0x29, 0x13, 0x15)]) + // .flatten() + // .collect(); + // let gas = 100_000; + // let instructions = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, gas), + // op::movi(0x15, size), + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // ]; + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service( + // "contract/srwq", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); // sww @@ -639,36 +554,38 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ); } - // let mut swwq = c.benchmark_group("swwq"); - // - // for i in linear.clone() { - // let start_key = Bytes32::zeroed(); - // let data = start_key.iter().copied().collect::>(); - // - // let post_call = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, i as u32), - // ]; - // let mut bench = VmBench::contract_using_db( - // rng, - // db.checkpoint(), - // op::swwq(0x10, 0x11, 0x20, 0x12), - // ) - // .expect("failed to prepare contract") - // .with_post_call(post_call); - // bench.data.extend(data); - // - // swwq.throughput(Throughput::Bytes(i)); - // - // run_group_ref(&mut swwq, format!("{i}"), bench); - // } - // - // swwq.finish(); + // swwq - // TODO: Add `swwq` benchmark + // TODO: This is under-costed, so it runs too long and will complete before running out of gas + // let size = 2620_u32; + // // Copy value stored at $rC to the state starting at 0x13 + // let contract = (0..2620) + // .map(|x| x * size) + // .map(|x| vec![op::movi(0x13, x), op::swwq(0x13, 0x29, 0x14, 0x15)]) .flatten() + // .collect(); + // let gas = 100_000; + // let value = 2000; + // let instructions = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, gas), + // op::movi(0x14, value), + // op::movi(0x15, size), + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // ]; + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service( + // "contract/swwq", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); // time From 90db502c2200313f99f3de07ab0d69fc21e1249f Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 10:59:32 -0700 Subject: [PATCH 20/36] Fix compilation warnings --- benches/benches/block_target_gas.rs | 69 ++++--------------- .../benches/block_target_gas_set/contract.rs | 17 ++--- 2 files changed, 19 insertions(+), 67 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index ec2d468e859..236bb9efeaa 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -1,23 +1,12 @@ use block_target_gas_set::{ - alu::run_alu, - contract::run_contract, - crypto::run_crypto, - flow::run_flow, + alu::run_alu, contract::run_contract, crypto::run_crypto, flow::run_flow, memory::run_memory, }; use criterion::{ - criterion_group, - criterion_main, - measurement::WallTime, - BenchmarkGroup, - Criterion, + criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, }; use ed25519_dalek::Signer; -use fuel_core::service::{ - config::Trigger, - Config, - ServiceTrait, -}; +use fuel_core::service::{config::Trigger, Config, ServiceTrait}; use rand::SeedableRng; use ethnum::U256; @@ -26,35 +15,12 @@ use fuel_core_chain_config::ContractConfig; use fuel_core_types::{ fuel_asm::{ op, - wideint::{ - CompareArgs, - CompareMode, - DivArgs, - MathArgs, - MathOp, - MulArgs, - }, - GTFArgs, - Instruction, - RegId, - }, - fuel_crypto::{ - secp256r1, - *, - }, - fuel_tx::{ - ContractIdExt, - Input, - Output, - TxPointer, - UniqueIdentifier, - UtxoId, - }, - fuel_types::{ - AssetId, - Bytes32, - ContractId, + wideint::{CompareArgs, CompareMode, DivArgs, MathArgs, MathOp, MulArgs}, + GTFArgs, Instruction, RegId, }, + fuel_crypto::{secp256r1, *}, + fuel_tx::{ContractIdExt, Input, Output, TxPointer, UniqueIdentifier, UtxoId}, + fuel_types::{AssetId, Bytes32, ContractId}, fuel_vm::checked_transaction::EstimatePredicates, }; @@ -62,15 +28,16 @@ mod utils; mod block_target_gas_set; -use utils::{ - make_u128, - make_u256, -}; +use utils::{make_u128, make_u256}; // Use Jemalloc during benchmarks #[global_allocator] static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; +const STATE_SIZE: u64 = 10_000_000; +const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; +const BASE: u64 = 10_000; + fn run( id: &str, group: &mut BenchmarkGroup, @@ -83,8 +50,6 @@ fn run( .build() .unwrap(); let _drop = rt.enter(); - const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; - const BASE: u64 = 10_000; let database = Database::rocksdb(); let mut config = Config::local_node(); @@ -155,15 +120,11 @@ fn run( fn service_with_contract_id( contract_id: ContractId, ) -> (fuel_core::service::FuelService, tokio::runtime::Runtime) { - const STATE_SIZE: u64 = 10_000_000; - let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() .unwrap(); let _drop = rt.enter(); - const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; - const BASE: u64 = 10_000; let mut database = Database::rocksdb(); let mut config = Config::local_node(); config @@ -275,8 +236,6 @@ fn run_with_service_with_extra_inputs( extra_outputs: Vec, ) { group.bench_function(id, |b| { - const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; - const BASE: u64 = 10_000; b.to_async(rt).iter(|| { let shared = service.shared.clone(); @@ -298,7 +257,7 @@ fn run_with_service_with_extra_inputs( Default::default(), Default::default(), ); - let mut input_count = tx_builder.inputs().len(); + let input_count = tx_builder.inputs().len(); let contract_input = Input::contract( UtxoId::default(), diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index f3f229ecf5f..63a0814c895 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -2,7 +2,6 @@ use crate::{utils::arb_dependent_cost_values, *}; use fuel_core::service::FuelService; use fuel_core_storage::{tables::ContractsRawCode, StorageAsMut}; use fuel_core_types::{ - fuel_tx::{TxPointer, UtxoId}, fuel_types::{Address, Word}, fuel_vm::consts::WORD_SIZE, }; @@ -135,7 +134,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), + op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]; @@ -214,7 +213,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::croo(0x14, 0x16), op::ret(RegId::ZERO), ]; - let mut instructions = call_contract_repeat(); + let instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); run_with_service( "contract/croo", @@ -338,7 +337,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { run_with_service( "contract/ret contract", group, - call_contract_repeat(), + instructions, script_data.clone(), &service, contract_id, @@ -354,7 +353,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::movi(0x14, i.try_into().unwrap()), op::retd(RegId::ONE, 0x14), ]; - let mut instructions = call_contract_repeat(); + let instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/retd contract {:?}", i); run_with_service( @@ -723,7 +722,7 @@ fn setup_instructions() -> Vec { op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, 100_000), + op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), ] } @@ -735,9 +734,3 @@ fn call_contract_repeat() -> Vec { ]); instructions } - -fn call_contract_once() -> Vec { - let mut instructions = setup_instructions(); - instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); - instructions -} From b8195ba058641079b1dfefc64641d8a07a763041 Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 11:00:37 -0700 Subject: [PATCH 21/36] Revert bad fmt --- benches/benches/block_target_gas.rs | 55 ++++++++++++++++--- .../benches/block_target_gas_set/contract.rs | 15 ++++- 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 236bb9efeaa..f0442ffc960 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -1,12 +1,23 @@ use block_target_gas_set::{ - alu::run_alu, contract::run_contract, crypto::run_crypto, flow::run_flow, + alu::run_alu, + contract::run_contract, + crypto::run_crypto, + flow::run_flow, memory::run_memory, }; use criterion::{ - criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, + criterion_group, + criterion_main, + measurement::WallTime, + BenchmarkGroup, + Criterion, }; use ed25519_dalek::Signer; -use fuel_core::service::{config::Trigger, Config, ServiceTrait}; +use fuel_core::service::{ + config::Trigger, + Config, + ServiceTrait, +}; use rand::SeedableRng; use ethnum::U256; @@ -15,12 +26,35 @@ use fuel_core_chain_config::ContractConfig; use fuel_core_types::{ fuel_asm::{ op, - wideint::{CompareArgs, CompareMode, DivArgs, MathArgs, MathOp, MulArgs}, - GTFArgs, Instruction, RegId, + wideint::{ + CompareArgs, + CompareMode, + DivArgs, + MathArgs, + MathOp, + MulArgs, + }, + GTFArgs, + Instruction, + RegId, + }, + fuel_crypto::{ + secp256r1, + *, + }, + fuel_tx::{ + ContractIdExt, + Input, + Output, + TxPointer, + UniqueIdentifier, + UtxoId, + }, + fuel_types::{ + AssetId, + Bytes32, + ContractId, }, - fuel_crypto::{secp256r1, *}, - fuel_tx::{ContractIdExt, Input, Output, TxPointer, UniqueIdentifier, UtxoId}, - fuel_types::{AssetId, Bytes32, ContractId}, fuel_vm::checked_transaction::EstimatePredicates, }; @@ -28,7 +62,10 @@ mod utils; mod block_target_gas_set; -use utils::{make_u128, make_u256}; +use utils::{ + make_u128, + make_u256, +}; // Use Jemalloc during benchmarks #[global_allocator] diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 63a0814c895..62b775adccf 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -1,8 +1,17 @@ -use crate::{utils::arb_dependent_cost_values, *}; +use crate::{ + utils::arb_dependent_cost_values, + *, +}; use fuel_core::service::FuelService; -use fuel_core_storage::{tables::ContractsRawCode, StorageAsMut}; +use fuel_core_storage::{ + tables::ContractsRawCode, + StorageAsMut, +}; use fuel_core_types::{ - fuel_types::{Address, Word}, + fuel_types::{ + Address, + Word, + }, fuel_vm::consts::WORD_SIZE, }; From ef789016aa2892bce564e7dc0e4953f44dd061ff Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 11:05:41 -0700 Subject: [PATCH 22/36] Replace removed changelog entries --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bffb7ee41a..e8566261c47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,10 @@ Description of the upcoming release here. - [#1405](https://github.com/FuelLabs/fuel-core/pull/1405): Use correct names for service metrics. ### Changed - +- [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Replaced usage of `MemoryTransactionView` by `Checkpoint` database in the benchmarks. +- [#1466](https://github.com/FuelLabs/fuel-core/pull/1466): Handling overflows during arithmetic operations. +- [#1468](https://github.com/FuelLabs/fuel-core/pull/1468): Bumped version of the `fuel-vm` to `v0.40.0`. It brings some breaking changes into consensus parameters API because of changes in the underlying types. +- [#1460](https://github.com/FuelLabs/fuel-core/pull/1460): Change tracking branch from main to master for releasy tests. - [#1440](https://github.com/FuelLabs/fuel-core/pull/1440): Don't report reserved nodes that send invalid transactions. - [#1439](https://github.com/FuelLabs/fuel-core/pull/1439): Reduced memory BMT consumption during creation of the header. - [#1434](https://github.com/FuelLabs/fuel-core/pull/1434): Continue gossiping transactions to reserved peers regardless of gossiping reputation score. @@ -72,6 +75,7 @@ Description of the upcoming release here. - [#1408](https://github.com/FuelLabs/fuel-core/pull/1408): Update gas benchmarks for storage opcodes to use a pre-populated database to get more accurate worst-case costs. #### Breaking +- [#1464](https://github.com/FuelLabs/fuel-core/pull/1464): Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems. The change affects some endpoints that now require lesser integers.: - [#1432](https://github.com/FuelLabs/fuel-core/pull/1432): All subscriptions and requests have a TTL now. So each subscription lifecycle is limited in time. If the subscription is closed because of TTL, it means that you subscribed after your transaction had been dropped by the network. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The recipient is a `ContractId` instead of `Address`. The block producer should deploy its contract to receive the transaction fee. The collected fee is zero until the recipient contract is set. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The `Mint` transaction is reworked with new fields to support the account-base model. It affects serialization and deserialization of the transaction and also affects GraphQL schema. From faa299c6607eb548a79955d665be45080a3b2f03 Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 11:07:48 -0700 Subject: [PATCH 23/36] Pick some nits --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8566261c47..8f656fb43fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ Description of the upcoming release here. - [#1405](https://github.com/FuelLabs/fuel-core/pull/1405): Use correct names for service metrics. ### Changed + - [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Replaced usage of `MemoryTransactionView` by `Checkpoint` database in the benchmarks. - [#1466](https://github.com/FuelLabs/fuel-core/pull/1466): Handling overflows during arithmetic operations. - [#1468](https://github.com/FuelLabs/fuel-core/pull/1468): Bumped version of the `fuel-vm` to `v0.40.0`. It brings some breaking changes into consensus parameters API because of changes in the underlying types. @@ -75,7 +76,8 @@ Description of the upcoming release here. - [#1408](https://github.com/FuelLabs/fuel-core/pull/1408): Update gas benchmarks for storage opcodes to use a pre-populated database to get more accurate worst-case costs. #### Breaking -- [#1464](https://github.com/FuelLabs/fuel-core/pull/1464): Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems. The change affects some endpoints that now require lesser integers.: + +- [#1464](https://github.com/FuelLabs/fuel-core/pull/1464): Avoid possible truncation of higher bits. It may invalidate the code that truncated higher bits causing different behavior on 32-bit vs. 64-bit systems. The change affects some endpoints that now require lesser integers. - [#1432](https://github.com/FuelLabs/fuel-core/pull/1432): All subscriptions and requests have a TTL now. So each subscription lifecycle is limited in time. If the subscription is closed because of TTL, it means that you subscribed after your transaction had been dropped by the network. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The recipient is a `ContractId` instead of `Address`. The block producer should deploy its contract to receive the transaction fee. The collected fee is zero until the recipient contract is set. - [#1407](https://github.com/FuelLabs/fuel-core/pull/1407): The `Mint` transaction is reworked with new fields to support the account-base model. It affects serialization and deserialization of the transaction and also affects GraphQL schema. From e8b041dbccea864e3061b2d81ef291d6db64ce28 Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 11:20:58 -0700 Subject: [PATCH 24/36] Add docs to helper functions --- benches/benches/block_target_gas.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index f0442ffc960..2053719f8f9 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -154,6 +154,8 @@ fn run( }); } +/// Sets up a service with a full database. Returns the service with the associated Runtime. +/// The size of the database can be overridden with the `STATE_SIZE` environment variable. fn service_with_contract_id( contract_id: ContractId, ) -> (fuel_core::service::FuelService, tokio::runtime::Runtime) { @@ -236,6 +238,8 @@ fn service_with_contract_id( (service, rt) } +/// Runs benchmark for `script` with prepared `service` and specified contract (by 'contract_id') which should be +/// included in service fn run_with_service( id: &str, group: &mut BenchmarkGroup, @@ -260,6 +264,9 @@ fn run_with_service( ); } +/// Runs benchmark for `script` with prepared `service` and specified contract (by `contract_id`) which should be +/// included in service. +/// Also include additional inputs and outputs in transaction fn run_with_service_with_extra_inputs( id: &str, group: &mut BenchmarkGroup, From 88bab847fcdaf583f4a3ee474c281f8f136b819c Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 3 Nov 2023 11:27:49 -0700 Subject: [PATCH 25/36] Fix name, comment out sequential op bench --- .../benches/block_target_gas_set/contract.rs | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 62b775adccf..b8a6cc0f5aa 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -401,7 +401,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // } - // amo + // smo { let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); @@ -462,33 +462,33 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // TODO: This is under-costed, so it runs too long and will complete before running out // of gas at 100_000. - let size = 2620_u32; // 18bit integer maxes at 262144 - let contract: Vec<_> = (0..100_u32) - .map(|x| x * size) - .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC - .flatten() - .collect(); - let gas = 100_000; - let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, gas), - op::movi(0x14, size), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - ]; - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/scwq", - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + // let size = 2620_u32; // 18bit integer maxes at 262144 + // let contract: Vec<_> = (0..100_u32) + // .map(|x| x * size) + // .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC + // .flatten() + // .collect(); + // let gas = 100_000; + // let instructions = vec![ + // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + // op::movi(0x12, gas), + // op::movi(0x14, size), + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // ]; + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service( + // "contract/scwq", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // ); // srw From 6d952b7f2d2a5dffc831afa7f94986bf51c57c06 Mon Sep 17 00:00:00 2001 From: Turner Date: Fri, 3 Nov 2023 13:03:55 -0700 Subject: [PATCH 26/36] Removed unused function, remove dbg --- benches/benches/block_target_gas.rs | 2 -- crates/fuel-core/src/database.rs | 21 ++------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 2053719f8f9..6619a8776dc 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -323,7 +323,6 @@ fn run_with_service_with_extra_inputs( for output in &extra_outputs { tx_builder.add_output(output.clone()); } - dbg!(&tx_builder.outputs().len()); let mut tx = tx_builder.finalize_as_transaction(); tx.estimate_predicates(&shared.config.chain_conf.consensus_parameters.clone().into()).unwrap(); async move { @@ -339,7 +338,6 @@ fn run_with_service_with_extra_inputs( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/crates/fuel-core/src/database.rs b/crates/fuel-core/src/database.rs index f8e2d4ceef9..7f00a5c2ed8 100644 --- a/crates/fuel-core/src/database.rs +++ b/crates/fuel-core/src/database.rs @@ -20,13 +20,8 @@ use fuel_core_storage::{ }, Result as StorageResult, }; -use fuel_core_types::{ - fuel_tx::Contract, - fuel_types::{ - BlockHeight, - ContractId, - }, -}; +use fuel_core_types::fuel_types::BlockHeight; + use itertools::Itertools; use serde::{ de::DeserializeOwned, @@ -434,18 +429,6 @@ impl Database { }) }) } - - #[cfg(feature = "test-helpers")] - pub fn insert_contract_bytecode( - &mut self, - id: ContractId, - bytecode: &[u8], - ) -> DatabaseResult<()> { - let column = Column::ContractsRawCode; - let _: Option = self.insert(&id, column, &bytecode)?; - - Ok(()) - } } impl Transactional for Database { From 72319ee2e41ade45e92e0045466f289a360b9902 Mon Sep 17 00:00:00 2001 From: Turner Date: Fri, 3 Nov 2023 13:21:25 -0700 Subject: [PATCH 27/36] Appease Clippy-sama --- benches/benches/block_target_gas.rs | 6 +++-- .../benches/block_target_gas_set/contract.rs | 24 ++++++++----------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 6619a8776dc..794a4cf0994 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -173,7 +173,7 @@ fn service_with_contract_id( .max_gas_per_tx = TARGET_BLOCK_GAS_LIMIT; config.chain_conf.initial_state.as_mut().unwrap().contracts = Some(vec![ContractConfig { - contract_id: contract_id.clone(), + contract_id, code: vec![], salt: Default::default(), state: None, @@ -240,6 +240,7 @@ fn service_with_contract_id( /// Runs benchmark for `script` with prepared `service` and specified contract (by 'contract_id') which should be /// included in service +#[allow(clippy::too_many_arguments)] fn run_with_service( id: &str, group: &mut BenchmarkGroup, @@ -267,6 +268,7 @@ fn run_with_service( /// Runs benchmark for `script` with prepared `service` and specified contract (by `contract_id`) which should be /// included in service. /// Also include additional inputs and outputs in transaction +#[allow(clippy::too_many_arguments)] fn run_with_service_with_extra_inputs( id: &str, group: &mut BenchmarkGroup, @@ -321,7 +323,7 @@ fn run_with_service_with_extra_inputs( } for output in &extra_outputs { - tx_builder.add_output(output.clone()); + tx_builder.add_output(*output); } let mut tx = tx_builder.finalize_as_transaction(); tx.estimate_predicates(&shared.config.chain_conf.consensus_parameters.clone().into()).unwrap(); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index b8a6cc0f5aa..e7242598687 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -59,7 +59,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let id = "contract/bal contract"; run_with_service( - &id, + id, group, instructions, script_data.clone(), @@ -75,7 +75,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let id = "contract/bal script"; run_with_service( - &id, + id, group, instructions, script_data.clone(), @@ -188,9 +188,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![ - op::movi(0x13, i.try_into().unwrap()), - op::movi(0x14, i.try_into().unwrap()), - op::movi(0x15, i.try_into().unwrap()), + op::movi(0x13, i), + op::movi(0x14, i), + op::movi(0x15, i), op::add(0x15, 0x15, 0x15), op::addi(0x15, 0x15, 32), op::aloc(0x15), @@ -270,7 +270,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { .collect(); let mut instructions = setup_instructions(); instructions.extend(vec![ - op::movi(0x13, size.try_into().unwrap()), + op::movi(0x13, size), op::ldc(0x10, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); @@ -303,7 +303,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { for i in arb_dependent_cost_values() { let mut instructions = setup_instructions(); instructions.extend(vec![ - op::movi(0x13, i.try_into().unwrap()), + op::movi(0x13, i), op::logd(0x10, 0x11, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); @@ -358,10 +358,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // retd contract { for i in arb_dependent_cost_values() { - let contract = vec![ - op::movi(0x14, i.try_into().unwrap()), - op::retd(RegId::ONE, 0x14), - ]; + let contract = vec![op::movi(0x14, i), op::retd(RegId::ONE, 0x14)]; let instructions = call_contract_repeat(); replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/retd contract {:?}", i); @@ -424,7 +421,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // Offset 32 + 8 + 8 + 32 op::addi(0x15, 0x15, 32 + 8 + 8 + 32), // target address pointer op::addi(0x16, 0x15, 32), // data ppinter - op::movi(0x17, i.try_into().unwrap()), // data length + op::movi(0x17, i), // data length op::smo(0x15, 0x16, 0x17, 0x18), op::ret(RegId::ZERO), ]; @@ -704,8 +701,7 @@ fn replace_contract_in_service( ) { let contract_bytecode: Vec<_> = contract_instructions .iter() - .map(|x| x.to_bytes()) - .flatten() + .flat_map(|x| x.to_bytes()) .collect(); service .shared From 6ee19be34ac9f668d70ea22773566d39e34ac092 Mon Sep 17 00:00:00 2001 From: Mitchell Turner Date: Wed, 8 Nov 2023 01:09:46 -0800 Subject: [PATCH 28/36] Update benches/benches/block_target_gas.rs Co-authored-by: Hannes Karppila --- benches/benches/block_target_gas.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 794a4cf0994..86b77d5f073 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -194,15 +194,12 @@ fn service_with_contract_id( config.block_production = Trigger::Instant; // Override state size if the env var is set - let state_size_env_var = "STATE_SIZE"; - let state_size = if let Some(value) = std::env::var_os(state_size_env_var) { + let state_size = std::env::var_os("STATE_SIZE").map(|value| { let value = value.to_str().unwrap(); let value = value.parse::().unwrap(); println!("Overriding state size with {}", value); value - } else { - STATE_SIZE - }; + }).unwrap_or(STATE_SIZE); database .init_contract_state( From 8fd7b89daa92e1784fa2b9aa66b5097f24801b22 Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 8 Nov 2023 01:14:35 -0800 Subject: [PATCH 29/36] remove dum comments --- benches/benches/block_target_gas.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 86b77d5f073..c9aa49523e3 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -109,7 +109,6 @@ fn run( let shared = service.shared.clone(); let tx = fuel_core_types::fuel_tx::TransactionBuilder::script( - // Infinite loop script.clone().into_iter().collect(), script_data.clone(), ) @@ -194,12 +193,14 @@ fn service_with_contract_id( config.block_production = Trigger::Instant; // Override state size if the env var is set - let state_size = std::env::var_os("STATE_SIZE").map(|value| { - let value = value.to_str().unwrap(); - let value = value.parse::().unwrap(); - println!("Overriding state size with {}", value); - value - }).unwrap_or(STATE_SIZE); + let state_size = std::env::var_os("STATE_SIZE") + .map(|value| { + let value = value.to_str().unwrap(); + let value = value.parse::().unwrap(); + println!("Overriding state size with {}", value); + value + }) + .unwrap_or(STATE_SIZE); database .init_contract_state( @@ -285,7 +286,6 @@ fn run_with_service_with_extra_inputs( let mut tx_builder = fuel_core_types::fuel_tx::TransactionBuilder::script( - // Infinite loop script.clone().into_iter().collect(), script_data.clone(), ); From b14aecb3128ab8974216413151968274095dd76b Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 8 Nov 2023 02:41:30 -0800 Subject: [PATCH 30/36] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eabbbce8a6..ea42d7d5154 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Description of the upcoming release here. ### Added +- [#1476](https://github.com/FuelLabs/fuel-core/pull/1453): Add the majority of the "other" benchmarks for contract opcodes. - [#1453](https://github.com/FuelLabs/fuel-core/pull/1453): Add the majority of the "sanity" benchmarks for contract opcodes. - [#1473](https://github.com/FuelLabs/fuel-core/pull/1473): Expose fuel-core version as a constant - [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Added support of bloom filter for RocksDB tables and increased the block cache. From f26ec0dcb1cc2dd661d0eaf4a5845e275115aa7a Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 8 Nov 2023 02:47:18 -0800 Subject: [PATCH 31/36] Remove mistake --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea42d7d5154..1eabbbce8a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ Description of the upcoming release here. ### Added -- [#1476](https://github.com/FuelLabs/fuel-core/pull/1453): Add the majority of the "other" benchmarks for contract opcodes. - [#1453](https://github.com/FuelLabs/fuel-core/pull/1453): Add the majority of the "sanity" benchmarks for contract opcodes. - [#1473](https://github.com/FuelLabs/fuel-core/pull/1473): Expose fuel-core version as a constant - [#1469](https://github.com/FuelLabs/fuel-core/pull/1469): Added support of bloom filter for RocksDB tables and increased the block cache. From f14aa0d171ebb07b5249d1ef0f44f0637fb52d0f Mon Sep 17 00:00:00 2001 From: mitchell Date: Fri, 10 Nov 2023 15:09:54 -0800 Subject: [PATCH 32/36] Refactor into factory thing, address some PR reviews --- benches/benches/block_target_gas.rs | 218 ++++++++++++---- .../benches/block_target_gas_set/contract.rs | 234 ++++-------------- 2 files changed, 216 insertions(+), 236 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index c9aa49523e3..2612f12a505 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -16,13 +16,19 @@ use ed25519_dalek::Signer; use fuel_core::service::{ config::Trigger, Config, + FuelService, ServiceTrait, }; use rand::SeedableRng; use ethnum::U256; +use fuel_core::txpool::types::Word; use fuel_core_benches::*; use fuel_core_chain_config::ContractConfig; +use fuel_core_storage::{ + tables::ContractsRawCode, + StorageAsMut, +}; use fuel_core_types::{ fuel_asm::{ op, @@ -55,7 +61,10 @@ use fuel_core_types::{ Bytes32, ContractId, }, - fuel_vm::checked_transaction::EstimatePredicates, + fuel_vm::{ + checked_transaction::EstimatePredicates, + consts::WORD_SIZE, + }, }; mod utils; @@ -72,9 +81,100 @@ use utils::{ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; const STATE_SIZE: u64 = 10_000_000; -const TARGET_BLOCK_GAS_LIMIT: u64 = 100_000; +const TARGET_BLOCK_GAS_LIMIT: u64 = 262143; const BASE: u64 = 10_000; +pub struct SanityBenchmarkFactory; + +pub struct SharedSanityBenchmarkFactory { + service: FuelService, + rt: tokio::runtime::Runtime, + contract_id: ContractId, + rng: rand::rngs::StdRng, +} + +impl SanityBenchmarkFactory { + /// Creates a factory for benchmarks that share a service with a contract, `contract_id`, pre- + /// deployed. + pub fn new_shared(contract_id: ContractId) -> SharedSanityBenchmarkFactory { + let (service, rt) = service_with_contract_id(contract_id); + let rng = rand::rngs::StdRng::seed_from_u64(2322u64); + SharedSanityBenchmarkFactory { + service, + rt, + contract_id, + rng, + } + } +} + +impl SharedSanityBenchmarkFactory { + pub fn build(&mut self) -> SanityBenchmark { + SanityBenchmark { + service: &mut self.service, + rt: &self.rt, + rng: &mut self.rng, + has_contract_input: true, + extra_inputs: vec![], + extra_outputs: vec![], + } + } + + pub fn build_with_new_contract( + &mut self, + contract_instructions: Vec, + ) -> SanityBenchmark { + replace_contract_in_service( + &mut self.service, + &self.contract_id, + contract_instructions, + ); + self.build() + } +} + +pub struct SanityBenchmark<'a> { + service: &'a mut FuelService, + rt: &'a tokio::runtime::Runtime, + rng: &'a mut rand::rngs::StdRng, + has_contract_input: bool, + extra_inputs: Vec, + extra_outputs: Vec, +} + +impl<'a> SanityBenchmark<'a> { + pub fn with_extra_inputs(mut self, extra_inputs: Vec) -> Self { + self.extra_inputs = extra_inputs; + self + } + + pub fn with_extra_outputs(mut self, extra_outputs: Vec) -> Self { + self.extra_outputs = extra_outputs; + self + } + + pub fn run( + self, + id: &str, + group: &mut BenchmarkGroup, + script: Vec, + script_data: Vec, + ) { + run_with_service_with_extra_inputs( + id, + group, + script, + script_data, + self.service, + VmBench::CONTRACT, + self.rt, + self.rng, + self.extra_inputs, + self.extra_outputs, + ); + } +} + fn run( id: &str, group: &mut BenchmarkGroup, @@ -188,7 +288,8 @@ fn service_with_contract_id( .consensus_parameters .predicate_params .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; - config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; + // Some txs (e.g. smo) are too big so increasing this arbitrarily + config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT * 3; config.utxo_validation = false; config.block_production = Trigger::Instant; @@ -236,36 +337,9 @@ fn service_with_contract_id( (service, rt) } -/// Runs benchmark for `script` with prepared `service` and specified contract (by 'contract_id') which should be -/// included in service -#[allow(clippy::too_many_arguments)] -fn run_with_service( - id: &str, - group: &mut BenchmarkGroup, - script: Vec, - script_data: Vec, - service: &fuel_core::service::FuelService, - contract_id: ContractId, - rt: &tokio::runtime::Runtime, - rng: &mut rand::rngs::StdRng, -) { - run_with_service_with_extra_inputs( - id, - group, - script, - script_data, - service, - contract_id, - rt, - rng, - vec![], - vec![], - ); -} - -/// Runs benchmark for `script` with prepared `service` and specified contract (by `contract_id`) which should be -/// included in service. -/// Also include additional inputs and outputs in transaction +// Runs benchmark for `script` with prepared `service` and specified contract (by `contract_id`) which should be +// included in service. +// Also include additional inputs and outputs in transaction #[allow(clippy::too_many_arguments)] fn run_with_service_with_extra_inputs( id: &str, @@ -300,20 +374,20 @@ fn run_with_service_with_extra_inputs( Default::default(), Default::default(), ); - let input_count = tx_builder.inputs().len(); - - let contract_input = Input::contract( - UtxoId::default(), - Bytes32::zeroed(), - Bytes32::zeroed(), - TxPointer::default(), - contract_id, - ); - let contract_output = Output::contract(input_count as u8, Bytes32::zeroed(), Bytes32::zeroed()); + let input_count = tx_builder.inputs().len(); + + let contract_input = Input::contract( + UtxoId::default(), + Bytes32::zeroed(), + Bytes32::zeroed(), + TxPointer::default(), + contract_id, + ); + let contract_output = Output::contract(input_count as u8, Bytes32::zeroed(), Bytes32::zeroed()); - tx_builder - .add_input(contract_input) - .add_output(contract_output); + tx_builder + .add_input(contract_input) + .add_output(contract_output); for input in &extra_inputs { tx_builder.add_input(input.clone()); @@ -405,5 +479,57 @@ fn block_target_gas(c: &mut Criterion) { group.finish(); } +fn replace_contract_in_service( + service: &mut FuelService, + contract_id: &ContractId, + contract_instructions: Vec, +) { + let contract_bytecode: Vec<_> = contract_instructions + .iter() + .flat_map(|x| x.to_bytes()) + .collect(); + service + .shared + .database + .storage_as_mut::() + .insert(contract_id, &contract_bytecode) + .unwrap(); +} + +fn script_data(contract_id: &ContractId, asset_id: &AssetId) -> Vec { + contract_id + .iter() + .copied() + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain((0 as Word).to_be_bytes().iter().copied()) + .chain(asset_id.iter().copied()) + .collect() +} + +fn setup_instructions() -> Vec { + vec![ + op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), + op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), + ] +} + +fn call_contract_repeat() -> Vec { + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::jmpb(RegId::ZERO, 0), + ]); + instructions +} + +fn call_contract_once() -> Vec { + let mut instructions = setup_instructions(); + instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); + instructions +} + criterion_group!(benches, block_target_gas); criterion_main!(benches); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index e7242598687..abc540173c9 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -2,11 +2,6 @@ use crate::{ utils::arb_dependent_cost_values, *, }; -use fuel_core::service::FuelService; -use fuel_core_storage::{ - tables::ContractsRawCode, - StorageAsMut, -}; use fuel_core_types::{ fuel_types::{ Address, @@ -41,12 +36,11 @@ use fuel_core_types::{ // TRO: Transfer coins to output pub fn run_contract(group: &mut BenchmarkGroup) { let contract_id = ContractId::zeroed(); - let (mut service, rt) = service_with_contract_id(contract_id); - let mut rng = rand::rngs::StdRng::seed_from_u64(2322u64); let asset_id = AssetId::zeroed(); - let contract_id = ContractId::zeroed(); let script_data = script_data(&contract_id, &asset_id); + let mut shared_factory = SanityBenchmarkFactory::new_shared(contract_id); + // bal contract { let contract_instructions = @@ -54,36 +48,20 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); - - replace_contract_in_service(&mut service, &contract_id, contract_instructions); - let id = "contract/bal contract"; - run_with_service( - id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + + shared_factory + .build_with_new_contract(contract_instructions) + .run(id, group, instructions, script_data.clone()); } + { let mut instructions = setup_instructions(); instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); - let id = "contract/bal script"; - run_with_service( - id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + shared_factory + .build() + .run(id, group, instructions, script_data.clone()); } // bhei @@ -112,22 +90,16 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; let mut instructions = setup_instructions(); - // TODO: I don't know why we need these extra ops instructions.extend(vec![ op::movi(0x10, 32), op::aloc(0x10), op::call(0x10, RegId::ZERO, 0x11, 0x12), ]); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/burn", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -148,19 +120,10 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]; - replace_contract_in_service(&mut service, &contract_id, contract_instructions); - let id = format!("contract/call {:?}", size); - run_with_service( - &id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + shared_factory + .build_with_new_contract(contract_instructions) + .run(&id, group, instructions, script_data.clone()); } // cb @@ -198,20 +161,14 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::ccp(0x15, 0x10, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/ccp {:?}", i); - run_with_service( + shared_factory.build_with_new_contract(contract).run( &id, group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } - // croo { let contract = vec![ @@ -223,16 +180,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::ret(RegId::ZERO), ]; let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/croo", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -248,17 +200,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::csiz(0x11, 0x10), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/csiz {:?}", size); - run_with_service( + shared_factory.build_with_new_contract(contract).run( &id, group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -274,17 +221,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::ldc(0x10, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/ldc {:?}", size); - run_with_service( + shared_factory.build_with_new_contract(contract).run( &id, group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -308,16 +250,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/logd {:?}", i); - run_with_service( - &id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - ); + shared_factory + .build() + .run(&id, group, instructions, script_data.clone()); } } @@ -325,16 +260,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/mint", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -342,16 +272,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![op::ret(RegId::ONE), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/ret contract", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -360,17 +285,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { for i in arb_dependent_cost_values() { let contract = vec![op::movi(0x14, i), op::retd(RegId::ONE, 0x14)]; let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); + // replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/retd contract {:?}", i); - run_with_service( + shared_factory.build_with_new_contract(contract).run( &id, group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } } @@ -423,15 +344,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::addi(0x16, 0x15, 32), // data ppinter op::movi(0x17, i), // data length op::smo(0x15, 0x16, 0x17, 0x18), - op::ret(RegId::ZERO), + op::jmpb(RegId::ZERO, 0), ]; let mut instructions = setup_instructions(); instructions.extend(vec![ - op::movi(0x18, 10), // coins to send - op::call(0x10, 0x18, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), + op::movi(0x18, 1), // coins to send + op::call(0x10, 0x12, 0x11, 0x12), ]); - replace_contract_in_service(&mut service, &contract_id, contract); let mut data = script_data.clone(); data.extend( Address::new([1u8; 32]) @@ -440,18 +359,10 @@ pub fn run_contract(group: &mut BenchmarkGroup) { .chain(vec![2u8; i as usize]), ); let id = format!("contract/smo {:?}", i); - run_with_service_with_extra_inputs( - &id, - group, - instructions, - script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, - extra_inputs.clone(), - vec![], - ); + shared_factory + .build_with_new_contract(contract) + .with_extra_inputs(extra_inputs.clone()) + .run(&id, group, instructions, data); } } @@ -497,16 +408,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/srw", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -543,19 +449,19 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // sww - { - let contract = vec![op::sww(RegId::ZERO, 0x29, RegId::ONE), op::ret(RegId::ZERO)]; - let instructions = call_contract_repeat(); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( - "contract/sww", + for i in 1..5 { + let contract = vec![op::sww(RegId::ZERO, 0x29, 0x13), op::jmpb(RegId::ZERO, 0)]; + let mut instructions = setup_instructions(); + instructions.extend(vec![ + op::movi(0x13, i), + op::call(0x10, RegId::ZERO, 0x11, 0x12), + ]); + let id = format!("contract/sww {:?}", i); + shared_factory.build_with_new_contract(contract).run( + &id, group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -608,7 +514,6 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } // tr - { let contract = vec![op::tr(0x15, 0x14, 0x15), op::ret(RegId::ZERO)]; let mut instructions = setup_instructions(); @@ -618,16 +523,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]); - replace_contract_in_service(&mut service, &contract_id, contract); - run_with_service( + shared_factory.build_with_new_contract(contract).run( "contract/tr", group, instructions, script_data.clone(), - &service, - contract_id, - &rt, - &mut rng, ); } @@ -693,49 +593,3 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // } } - -fn replace_contract_in_service( - service: &mut FuelService, - contract_id: &ContractId, - contract_instructions: Vec, -) { - let contract_bytecode: Vec<_> = contract_instructions - .iter() - .flat_map(|x| x.to_bytes()) - .collect(); - service - .shared - .database - .storage_as_mut::() - .insert(contract_id, &contract_bytecode) - .unwrap(); -} - -fn script_data(contract_id: &ContractId, asset_id: &AssetId) -> Vec { - contract_id - .iter() - .copied() - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain((0 as Word).to_be_bytes().iter().copied()) - .chain(asset_id.iter().copied()) - .collect() -} - -fn setup_instructions() -> Vec { - vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), - ] -} - -fn call_contract_repeat() -> Vec { - let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), - ]); - instructions -} From a3f70602f46829ce0bcd1600965a4c309d545031 Mon Sep 17 00:00:00 2001 From: mitchell Date: Mon, 13 Nov 2023 23:24:36 -0800 Subject: [PATCH 33/36] Add all review changes but `tro` stuff --- benches/benches/block_target_gas.rs | 34 ++++--- .../benches/block_target_gas_set/contract.rs | 91 +++++++++++-------- 2 files changed, 73 insertions(+), 52 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 2612f12a505..9b87bd845c3 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -84,7 +84,7 @@ const STATE_SIZE: u64 = 10_000_000; const TARGET_BLOCK_GAS_LIMIT: u64 = 262143; const BASE: u64 = 10_000; -pub struct SanityBenchmarkFactory; +pub struct SanityBenchmarkRunnerBuilder; pub struct SharedSanityBenchmarkFactory { service: FuelService, @@ -93,11 +93,12 @@ pub struct SharedSanityBenchmarkFactory { rng: rand::rngs::StdRng, } -impl SanityBenchmarkFactory { +impl SanityBenchmarkRunnerBuilder { /// Creates a factory for benchmarks that share a service with a contract, `contract_id`, pre- /// deployed. pub fn new_shared(contract_id: ContractId) -> SharedSanityBenchmarkFactory { - let (service, rt) = service_with_contract_id(contract_id); + let state_size = get_state_size(); + let (service, rt) = service_with_contract_id(state_size, contract_id); let rng = rand::rngs::StdRng::seed_from_u64(2322u64); SharedSanityBenchmarkFactory { service, @@ -109,7 +110,7 @@ impl SanityBenchmarkFactory { } impl SharedSanityBenchmarkFactory { - pub fn build(&mut self) -> SanityBenchmark { + fn build(&mut self) -> SanityBenchmark { SanityBenchmark { service: &mut self.service, rt: &self.rt, @@ -256,6 +257,7 @@ fn run( /// Sets up a service with a full database. Returns the service with the associated Runtime. /// The size of the database can be overridden with the `STATE_SIZE` environment variable. fn service_with_contract_id( + state_size: u64, contract_id: ContractId, ) -> (fuel_core::service::FuelService, tokio::runtime::Runtime) { let rt = tokio::runtime::Builder::new_current_thread() @@ -293,16 +295,6 @@ fn service_with_contract_id( config.utxo_validation = false; config.block_production = Trigger::Instant; - // Override state size if the env var is set - let state_size = std::env::var_os("STATE_SIZE") - .map(|value| { - let value = value.to_str().unwrap(); - let value = value.parse::().unwrap(); - println!("Overriding state size with {}", value); - value - }) - .unwrap_or(STATE_SIZE); - database .init_contract_state( &contract_id, @@ -337,6 +329,19 @@ fn service_with_contract_id( (service, rt) } +fn get_state_size() -> u64 { + // Override state size if the env var is set + let state_size = std::env::var_os("STATE_SIZE") + .map(|value| { + let value = value.to_str().unwrap(); + let value = value.parse::().unwrap(); + println!("Overriding state size with {}", value); + value + }) + .unwrap_or(STATE_SIZE); + state_size +} + // Runs benchmark for `script` with prepared `service` and specified contract (by `contract_id`) which should be // included in service. // Also include additional inputs and outputs in transaction @@ -411,6 +416,7 @@ fn run_with_service_with_extra_inputs( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); + dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index abc540173c9..9f13312595d 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -39,7 +39,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let asset_id = AssetId::zeroed(); let script_data = script_data(&contract_id, &asset_id); - let mut shared_factory = SanityBenchmarkFactory::new_shared(contract_id); + let mut shared_runner_builder = SanityBenchmarkRunnerBuilder::new_shared(contract_id); // bal contract { @@ -50,7 +50,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); let id = "contract/bal contract"; - shared_factory + shared_runner_builder .build_with_new_contract(contract_instructions) .run(id, group, instructions, script_data.clone()); } @@ -59,7 +59,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); let id = "contract/bal script"; - shared_factory + shared_runner_builder .build() .run(id, group, instructions, script_data.clone()); } @@ -95,7 +95,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::aloc(0x10), op::call(0x10, RegId::ZERO, 0x11, 0x12), ]); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( "contract/burn", group, instructions, @@ -121,7 +121,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { ]; let id = format!("contract/call {:?}", size); - shared_factory + shared_runner_builder .build_with_new_contract(contract_instructions) .run(&id, group, instructions, script_data.clone()); } @@ -162,7 +162,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/ccp {:?}", i); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( &id, group, instructions, @@ -173,14 +173,14 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![ op::gtf_args(0x16, 0x00, GTFArgs::ScriptData), - op::movi(0x15, 2000), + op::movi(0x15, 32), op::aloc(0x15), op::move_(0x14, RegId::HP), op::croo(0x14, 0x16), op::ret(RegId::ZERO), ]; let instructions = call_contract_repeat(); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( "contract/croo", group, instructions, @@ -201,7 +201,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/csiz {:?}", size); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( &id, group, instructions, @@ -222,7 +222,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/ldc {:?}", size); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( &id, group, instructions, @@ -250,17 +250,20 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/logd {:?}", i); - shared_factory - .build() - .run(&id, group, instructions, script_data.clone()); + shared_runner_builder.build().run( + &id, + group, + instructions, + script_data.clone(), + ); } } // mint { - let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::ret(RegId::ZERO)]; - let instructions = call_contract_repeat(); - shared_factory.build_with_new_contract(contract).run( + let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::jmpb(RegId::ZERO, 0)]; + let instructions = call_contract_once(); + shared_runner_builder.build_with_new_contract(contract).run( "contract/mint", group, instructions, @@ -272,7 +275,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let contract = vec![op::ret(RegId::ONE), op::ret(RegId::ZERO)]; let instructions = call_contract_repeat(); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( "contract/ret contract", group, instructions, @@ -287,7 +290,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let instructions = call_contract_repeat(); // replace_contract_in_service(&mut service, &contract_id, contract); let id = format!("contract/retd contract {:?}", i); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( &id, group, instructions, @@ -359,7 +362,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { .chain(vec![2u8; i as usize]), ); let id = format!("contract/smo {:?}", i); - shared_factory + shared_runner_builder .build_with_new_contract(contract) .with_extra_inputs(extra_inputs.clone()) .run(&id, group, instructions, data); @@ -408,7 +411,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( "contract/srw", group, instructions, @@ -457,7 +460,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::call(0x10, RegId::ZERO, 0x11, 0x12), ]); let id = format!("contract/sww {:?}", i); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( &id, group, instructions, @@ -515,15 +518,16 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // tr { - let contract = vec![op::tr(0x15, 0x14, 0x15), op::ret(RegId::ZERO)]; + let contract = vec![op::tr(0x15, 0x14, 0x15), op::jmpb(RegId::ZERO, 0)]; let mut instructions = setup_instructions(); instructions.extend(vec![ + op::movi(0x13, 1 << 18 - 1), op::movi(0x15, 2000), - op::movi(0x14, 100), - op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::movi(0x14, 1), + op::call(0x10, 0x13, 0x15, 0x12), op::jmpb(RegId::ZERO, 0), ]); - shared_factory.build_with_new_contract(contract).run( + shared_runner_builder.build_with_new_contract(contract).run( "contract/tr", group, instructions, @@ -578,18 +582,29 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // let extra_inputs = vec![coin_input]; // let extra_outputs = vec![coin_output]; // - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service_with_extra_inputs( - // "contract/tro", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // extra_inputs, - // extra_outputs, - // ); + // // replace_contract_in_service(&mut service, &contract_id, contract); + // // run_with_service_with_extra_inputs( + // // "contract/tro", + // // group, + // // instructions, + // // script_data.clone(), + // // &service, + // // contract_id, + // // &rt, + // // &mut rng, + // // extra_inputs, + // // extra_outputs, + // // ); + // // } + // shared_runner_builder + // .build_with_new_contract(contract) + // .with_extra_inputs(extra_inputs) + // .with_extra_outputs(extra_outputs) + // .run( + // "contract/tro", + // group, + // setup_instructions(), + // script_data.clone(), + // ); // } } From a3936c15ec239cdd43de52f6d0c8f5a7d2377417 Mon Sep 17 00:00:00 2001 From: mitchell Date: Wed, 15 Nov 2023 10:20:19 -0800 Subject: [PATCH 34/36] WIP fixing `tro` --- .../benches/block_target_gas_set/contract.rs | 131 +++++++++--------- 1 file changed, 63 insertions(+), 68 deletions(-) diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 9f13312595d..09997ef9cee 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -525,7 +525,6 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::movi(0x15, 2000), op::movi(0x14, 1), op::call(0x10, 0x13, 0x15, 0x12), - op::jmpb(RegId::ZERO, 0), ]); shared_runner_builder.build_with_new_contract(contract).run( "contract/tr", @@ -540,71 +539,67 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // The `tro` benchmark is disabled because it would require many, many outputs, because each // would get spent. But it's okay because that is putting a limit of 255 outputs per transaction // and that protects us from an attacker exploiting a poorly priced `tro` instruction. - // { - // let amount = 100; - // - // let contract = vec![ - // op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), - // op::ret(RegId::ZERO), - // ]; - // let mut instructions = setup_instructions(); - // instructions.extend(vec![ - // op::movi(0x14, amount), - // op::movi(0x15, 1), - // op::movi(0x20, 32), - // op::aloc(0x20), - // ]); - // - // for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { - // instructions.push(op::movi(0x20, v as u32)); - // instructions.push(op::sb(RegId::HP, 0x20, i as u16)); - // } - // - // instructions.extend(vec![ - // op::call(0x10, RegId::ZERO, 0x11, 0x12), - // op::jmpb(RegId::ZERO, 0), - // ]); - // - // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); - // let owner = Input::predicate_owner(&predicate); - // let coin_input = Input::coin_predicate( - // Default::default(), - // owner, - // 1000, - // AssetId::zeroed(), - // Default::default(), - // Default::default(), - // Default::default(), - // predicate, - // vec![], - // ); - // let coin_output = Output::variable(Address::zeroed(), 0, AssetId::zeroed()); - // let extra_inputs = vec![coin_input]; - // let extra_outputs = vec![coin_output]; - // - // // replace_contract_in_service(&mut service, &contract_id, contract); - // // run_with_service_with_extra_inputs( - // // "contract/tro", - // // group, - // // instructions, - // // script_data.clone(), - // // &service, - // // contract_id, - // // &rt, - // // &mut rng, - // // extra_inputs, - // // extra_outputs, - // // ); - // // } - // shared_runner_builder - // .build_with_new_contract(contract) - // .with_extra_inputs(extra_inputs) - // .with_extra_outputs(extra_outputs) - // .run( - // "contract/tro", - // group, - // setup_instructions(), - // script_data.clone(), - // ); - // } + { + let amount = 100; + + let contract = vec![ + op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), + // op::ret(RegId::ZERO), + ]; + let mut instructions = setup_instructions(); + + instructions.extend(vec![ + op::movi(0x14, amount), + op::movi(0x15, 1), + op::movi(0x20, 32), + op::aloc(0x20), + ]); + + for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { + instructions.push(op::movi(0x20, v as u32)); + instructions.push(op::sb(RegId::HP, 0x20, i as u16)); + } + + instructions.extend(vec![ + op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::jmpb(RegId::ZERO, 0), + ]); + + let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + let owner = Input::predicate_owner(&predicate); + let coin_input = Input::coin_predicate( + Default::default(), + owner, + 1000, + AssetId::zeroed(), + Default::default(), + Default::default(), + Default::default(), + predicate, + vec![], + ); + let coin_output = Output::variable(Address::zeroed(), 100, AssetId::zeroed()); + let extra_inputs = vec![coin_input]; + let extra_outputs = vec![coin_output]; + + // replace_contract_in_service(&mut service, &contract_id, contract); + // run_with_service_with_extra_inputs( + // "contract/tro", + // group, + // instructions, + // script_data.clone(), + // &service, + // contract_id, + // &rt, + // &mut rng, + // extra_inputs, + // extra_outputs, + // ); + // } + shared_runner_builder + .build_with_new_contract(contract) + .with_extra_inputs(extra_inputs) + .with_extra_outputs(extra_outputs) + .run("contract/tro", group, instructions, script_data.clone()); + } } From 37bfa179b5a2ad7fd87f23e592213a7af0dfbd12 Mon Sep 17 00:00:00 2001 From: xgreenx Date: Wed, 15 Nov 2023 19:55:28 +0000 Subject: [PATCH 35/36] Add incrementing u256 storage key --- benches/benches/block_target_gas.rs | 65 ++++-- .../benches/block_target_gas_set/contract.rs | 214 +++++++++--------- 2 files changed, 161 insertions(+), 118 deletions(-) diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 0d14434b150..8310d9437f6 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -82,7 +82,7 @@ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; const STATE_SIZE: u64 = 10_000_000; const TARGET_BLOCK_GAS_LIMIT: u64 = 262143; -const BASE: u64 = 10_000; +const BASE: u64 = 20_000; pub struct SanityBenchmarkRunnerBuilder; @@ -115,7 +115,6 @@ impl SharedSanityBenchmarkFactory { service: &mut self.service, rt: &self.rt, rng: &mut self.rng, - has_contract_input: true, extra_inputs: vec![], extra_outputs: vec![], } @@ -138,7 +137,6 @@ pub struct SanityBenchmark<'a> { service: &'a mut FuelService, rt: &'a tokio::runtime::Runtime, rng: &'a mut rand::rngs::StdRng, - has_contract_input: bool, extra_inputs: Vec, extra_outputs: Vec, } @@ -260,6 +258,7 @@ fn service_with_contract_id( state_size: u64, contract_id: ContractId, ) -> (fuel_core::service::FuelService, tokio::runtime::Runtime) { + use fuel_core::database::vm_database::IncreaseStorageKey; let rt = tokio::runtime::Builder::new_current_thread() .enable_all() .build() @@ -295,30 +294,36 @@ fn service_with_contract_id( config.utxo_validation = false; config.block_production = Trigger::Instant; + let mut storage_key = primitive_types::U256::zero(); + let mut key_bytes = Bytes32::zeroed(); + database .init_contract_state( &contract_id, - (0..state_size).map(|k| { - let mut key = Bytes32::zeroed(); - key.as_mut()[..8].copy_from_slice(&k.to_be_bytes()); - (key, key) + (0..state_size).map(|_| { + storage_key.to_big_endian(key_bytes.as_mut()); + storage_key.increase().unwrap(); + (key_bytes, key_bytes) }), ) .unwrap(); + + let mut storage_key = primitive_types::U256::zero(); + let mut sub_id = Bytes32::zeroed(); database .init_contract_balances( &contract_id, (0..state_size).map(|k| { - let key = k / 2; - let mut sub_id = Bytes32::zeroed(); - sub_id.as_mut()[..8].copy_from_slice(&key.to_be_bytes()); + storage_key.to_big_endian(sub_id.as_mut()); let asset = if k % 2 == 0 { VmBench::CONTRACT.asset_id(&sub_id) } else { - AssetId::new(*sub_id) + let asset_id = AssetId::new(*sub_id); + storage_key.increase().unwrap(); + asset_id }; - (asset, key + 1_000) + (asset, k / 2 + 1_000) }), ) .unwrap(); @@ -369,7 +374,7 @@ fn run_with_service_with_extra_inputs( script_data.clone(), ); tx_builder - .gas_limit(TARGET_BLOCK_GAS_LIMIT - BASE) + .script_gas_limit(TARGET_BLOCK_GAS_LIMIT - BASE) .gas_price(1) .add_unsigned_coin_input( SecretKey::random(rng), @@ -416,7 +421,6 @@ fn run_with_service_with_extra_inputs( .expect("Should be at least 1 element") .expect("Should include transaction successfully"); let res = sub.recv().await.expect("Should produce a block"); - dbg!(&res.tx_status); assert_eq!(res.tx_status.len(), 2, "res.tx_status: {:?}", res.tx_status); assert_eq!(res.sealed_block.entity.transactions().len(), 2); assert_eq!(res.tx_status[0].id, tx_id); @@ -428,7 +432,9 @@ fn run_with_service_with_extra_inputs( else { panic!("The execution should fails with out of gas") }; - assert!(reason.contains("OutOfGas")); + if !reason.contains("OutOfGas") { + panic!("The test failed because of {}", reason); + } } }) }); @@ -522,6 +528,35 @@ fn setup_instructions() -> Vec { ] } +/// Returns a bytecode that contains an infinite loop that increases the `u256` iterator by +/// `1` each iteration. A function expects a closure that returns an opcode that must +/// be called infinitely. The closure should accept one argument - +/// the register where the iterator is stored. +fn u256_iterator_loop(opcode: impl Fn(RegId) -> Instruction) -> Vec { + // Register where we store an iterator. + let iterator_register = RegId::new(0x20); + vec![ + op::movi(iterator_register, 32), + // Allocate 32 bytes for u256 iterator. + op::aloc(iterator_register), + // Store the address of the u256 iterator into `iterator_register`. + op::move_(iterator_register, RegId::HP), + // We need to pad number of isntruciton to be 8-byte aligned. + op::noop(), + // Execute benchmarking opcode. + opcode(iterator_register), + // Increment the iterator by one. + op::wqop( + iterator_register, + iterator_register, + RegId::ONE, + MathOp::ADD as u8, + ), + // Jump 4 instructions(jmpb, wqop, opcode, noop) back. + op::jmpb(RegId::ZERO, 1), + ] +} + fn call_contract_repeat() -> Vec { let mut instructions = setup_instructions(); instructions.extend(vec![ diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 09997ef9cee..6f55119167d 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -10,6 +10,9 @@ use fuel_core_types::{ fuel_vm::consts::WORD_SIZE, }; +// This register is used by `setup_instructions` function to set contract id. +const CONTRACT_ID_REGISTER: RegId = RegId::new(0x10); + // BAL: Balance of contract ID // BHEI: Block height // BHSH: Block hash @@ -44,10 +47,15 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // bal contract { let contract_instructions = - vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]; + u256_iterator_loop(|iterator| op::bal(0x13, iterator, CONTRACT_ID_REGISTER)); let mut instructions = setup_instructions(); - instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); + instructions.extend(vec![op::call( + CONTRACT_ID_REGISTER, + RegId::ZERO, + 0x11, + 0x12, + )]); let id = "contract/bal contract"; shared_runner_builder @@ -57,7 +65,9 @@ pub fn run_contract(group: &mut BenchmarkGroup) { { let mut instructions = setup_instructions(); - instructions.extend(vec![op::bal(0x13, 0x11, 0x10), op::jmpb(RegId::ZERO, 0)]); + instructions.extend(u256_iterator_loop(|iterator| { + op::bal(0x13, iterator, CONTRACT_ID_REGISTER) + })); let id = "contract/bal script"; shared_runner_builder .build() @@ -88,13 +98,14 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // burn { - let contract = vec![op::burn(RegId::ONE, RegId::HP), op::jmpb(RegId::ZERO, 0)]; + let contract = u256_iterator_loop(|iterator| op::burn(RegId::ONE, iterator)); let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::movi(0x10, 32), - op::aloc(0x10), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - ]); + instructions.extend(vec![op::call( + CONTRACT_ID_REGISTER, + RegId::ZERO, + 0x11, + 0x12, + )]); shared_runner_builder.build_with_new_contract(contract).run( "contract/burn", group, @@ -111,12 +122,12 @@ pub fn run_contract(group: &mut BenchmarkGroup) { contract_instructions.push(op::ret(0x10)); let instructions = vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), - op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), op::jmpb(RegId::ZERO, 0), ]; @@ -158,7 +169,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::addi(0x15, 0x15, 32), op::aloc(0x15), op::move_(0x15, RegId::HP), - op::ccp(0x15, 0x10, RegId::ZERO, 0x13), + op::ccp(0x15, CONTRACT_ID_REGISTER, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/ccp {:?}", i); @@ -196,8 +207,8 @@ pub fn run_contract(group: &mut BenchmarkGroup) { .collect(); let mut instructions = setup_instructions(); instructions.extend(vec![ - op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), - op::csiz(0x11, 0x10), + op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), + op::csiz(0x11, CONTRACT_ID_REGISTER), op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/csiz {:?}", size); @@ -218,7 +229,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![ op::movi(0x13, size), - op::ldc(0x10, RegId::ZERO, 0x13), + op::ldc(CONTRACT_ID_REGISTER, RegId::ZERO, 0x13), op::jmpb(RegId::ZERO, 0), ]); let id = format!("contract/ldc {:?}", size); @@ -261,7 +272,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // mint { - let contract = vec![op::mint(RegId::ONE, RegId::ZERO), op::jmpb(RegId::ZERO, 0)]; + let contract = u256_iterator_loop(|iterator| op::mint(RegId::ONE, iterator)); let instructions = call_contract_once(); shared_runner_builder.build_with_new_contract(contract).run( "contract/mint", @@ -352,7 +363,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![ op::movi(0x18, 1), // coins to send - op::call(0x10, 0x12, 0x11, 0x12), + op::call(CONTRACT_ID_REGISTER, 0x12, 0x11, 0x12), ]); let mut data = script_data.clone(); data.extend( @@ -381,13 +392,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .collect(); // let gas = 100_000; // let instructions = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::movi(0x12, gas), // op::movi(0x14, size), - // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), // ]; // replace_contract_in_service(&mut service, &contract_id, contract); // run_with_service( @@ -404,12 +415,11 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // srw { - let contract = vec![op::srw(0x13, 0x14, 0x15), op::ret(RegId::ZERO)]; + let contract = u256_iterator_loop(|iterator| op::srw(0x13, 0x14, iterator)); let mut instructions = setup_instructions(); instructions.extend(vec![ op::movi(0x15, 2000), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - op::jmpb(RegId::ZERO, 0), + op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), ]); shared_runner_builder.build_with_new_contract(contract).run( "contract/srw", @@ -430,13 +440,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // .collect(); // let gas = 100_000; // let instructions = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::movi(0x12, gas), // op::movi(0x15, size), - // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), // ]; // replace_contract_in_service(&mut service, &contract_id, contract); // run_with_service( @@ -451,23 +461,22 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // sww - - for i in 1..5 { - let contract = vec![op::sww(RegId::ZERO, 0x29, 0x13), op::jmpb(RegId::ZERO, 0)]; + { + let contract = u256_iterator_loop(|iterator| op::sww(iterator, 0x29, RegId::ONE)); let mut instructions = setup_instructions(); - instructions.extend(vec![ - op::movi(0x13, i), - op::call(0x10, RegId::ZERO, 0x11, 0x12), - ]); - let id = format!("contract/sww {:?}", i); + instructions.extend(vec![op::call( + CONTRACT_ID_REGISTER, + RegId::ZERO, + 0x11, + 0x12, + )]); shared_runner_builder.build_with_new_contract(contract).run( - &id, + "contract/sww", group, instructions, script_data.clone(), ); } - // swwq // TODO: This is under-costed, so it runs too long and will complete before running out of gas @@ -480,14 +489,14 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // let gas = 100_000; // let value = 2000; // let instructions = vec![ - // op::gtf_args(0x10, 0x00, GTFArgs::ScriptData), + // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), // op::movi(0x12, gas), // op::movi(0x14, value), // op::movi(0x15, size), - // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), // ]; // replace_contract_in_service(&mut service, &contract_id, contract); // run_with_service( @@ -502,7 +511,6 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // ); // time - { run( "contract/time", @@ -518,13 +526,13 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // tr { - let contract = vec![op::tr(0x15, 0x14, 0x15), op::jmpb(RegId::ZERO, 0)]; + let contract = u256_iterator_loop(|iterator| op::tr(0x15, 0x14, iterator)); let mut instructions = setup_instructions(); instructions.extend(vec![ - op::movi(0x13, 1 << 18 - 1), + op::movi(0x13, (1 << 18) - 1), op::movi(0x15, 2000), op::movi(0x14, 1), - op::call(0x10, 0x13, 0x15, 0x12), + op::call(CONTRACT_ID_REGISTER, 0x13, 0x15, 0x12), ]); shared_runner_builder.build_with_new_contract(contract).run( "contract/tr", @@ -539,67 +547,67 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // The `tro` benchmark is disabled because it would require many, many outputs, because each // would get spent. But it's okay because that is putting a limit of 255 outputs per transaction // and that protects us from an attacker exploiting a poorly priced `tro` instruction. - { - let amount = 100; - - let contract = vec![ - op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), - // op::ret(RegId::ZERO), - ]; - let mut instructions = setup_instructions(); - - instructions.extend(vec![ - op::movi(0x14, amount), - op::movi(0x15, 1), - op::movi(0x20, 32), - op::aloc(0x20), - ]); - - for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { - instructions.push(op::movi(0x20, v as u32)); - instructions.push(op::sb(RegId::HP, 0x20, i as u16)); - } - - instructions.extend(vec![ - op::call(0x10, RegId::ZERO, 0x11, 0x12), - // op::jmpb(RegId::ZERO, 0), - ]); - - let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); - let owner = Input::predicate_owner(&predicate); - let coin_input = Input::coin_predicate( - Default::default(), - owner, - 1000, - AssetId::zeroed(), - Default::default(), - Default::default(), - Default::default(), - predicate, - vec![], - ); - let coin_output = Output::variable(Address::zeroed(), 100, AssetId::zeroed()); - let extra_inputs = vec![coin_input]; - let extra_outputs = vec![coin_output]; - - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service_with_extra_inputs( - // "contract/tro", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // extra_inputs, - // extra_outputs, - // ); - // } - shared_runner_builder - .build_with_new_contract(contract) - .with_extra_inputs(extra_inputs) - .with_extra_outputs(extra_outputs) - .run("contract/tro", group, instructions, script_data.clone()); - } + // { + // let amount = 100; + // + // let contract = vec![ + // op::tro(RegId::ZERO, 0x15, 0x14, RegId::HP), + // // op::ret(RegId::ZERO), + // ]; + // let mut instructions = setup_instructions(); + // + // instructions.extend(vec![ + // op::movi(0x14, amount), + // op::movi(0x15, 1), + // op::movi(0x20, 32), + // op::aloc(0x20), + // ]); + // + // for (i, v) in (*AssetId::zeroed()).into_iter().enumerate() { + // instructions.push(op::movi(0x20, v as u32)); + // instructions.push(op::sb(RegId::HP, 0x20, i as u16)); + // } + // + // instructions.extend(vec![ + // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // // op::jmpb(RegId::ZERO, 0), + // ]); + // + // let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); + // let owner = Input::predicate_owner(&predicate); + // let coin_input = Input::coin_predicate( + // Default::default(), + // owner, + // 1000, + // AssetId::zeroed(), + // Default::default(), + // Default::default(), + // Default::default(), + // predicate, + // vec![], + // ); + // let coin_output = Output::variable(Address::zeroed(), 100, AssetId::zeroed()); + // let extra_inputs = vec![coin_input]; + // let extra_outputs = vec![coin_output]; + // + // // replace_contract_in_service(&mut service, &contract_id, contract); + // // run_with_service_with_extra_inputs( + // // "contract/tro", + // // group, + // // instructions, + // // script_data.clone(), + // // &service, + // // contract_id, + // // &rt, + // // &mut rng, + // // extra_inputs, + // // extra_outputs, + // // ); + // // } + // shared_runner_builder + // .build_with_new_contract(contract) + // .with_extra_inputs(extra_inputs) + // .with_extra_outputs(extra_outputs) + // .run("contract/tro", group, instructions, script_data.clone()); + // } } From e24af3e4357bd176b4bda3a0f44766da6f454d6a Mon Sep 17 00:00:00 2001 From: xgreenx Date: Wed, 15 Nov 2023 22:15:58 +0000 Subject: [PATCH 36/36] Use updated costs for sequential opcodes. Uncommented sequential opcodes. --- benches/benches/block_target_gas.rs | 75 ++++---- .../benches/block_target_gas_set/contract.rs | 170 ++++++----------- .../block_target_gas_set/default_gas_costs.rs | 172 ++++++++++++++++++ benches/benches/block_target_gas_set/mod.rs | 7 + benches/benches/vm_set/blockchain.rs | 2 +- benches/src/bin/collect.rs | 5 +- 6 files changed, 274 insertions(+), 157 deletions(-) create mode 100644 benches/benches/block_target_gas_set/default_gas_costs.rs diff --git a/benches/benches/block_target_gas.rs b/benches/benches/block_target_gas.rs index 8310d9437f6..2bd8feec1da 100644 --- a/benches/benches/block_target_gas.rs +++ b/benches/benches/block_target_gas.rs @@ -50,6 +50,7 @@ use fuel_core_types::{ }, fuel_tx::{ ContractIdExt, + GasCosts, Input, Output, TxPointer, @@ -71,6 +72,7 @@ mod utils; mod block_target_gas_set; +use crate::block_target_gas_set::default_gas_costs::default_gas_costs; use utils::{ make_u128, make_u256, @@ -81,8 +83,8 @@ use utils::{ static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; const STATE_SIZE: u64 = 10_000_000; -const TARGET_BLOCK_GAS_LIMIT: u64 = 262143; -const BASE: u64 = 20_000; +const TARGET_BLOCK_GAS_LIMIT: u64 = 1_000_000; +const BASE: u64 = 100_000; pub struct SanityBenchmarkRunnerBuilder; @@ -196,6 +198,8 @@ fn run( .predicate_params .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; + config.chain_conf.consensus_parameters.gas_costs = GasCosts::new(default_gas_costs()); + config.chain_conf.consensus_parameters.fee_params.gas_per_byte = 0; config.utxo_validation = false; config.block_production = Trigger::Instant; @@ -289,8 +293,13 @@ fn service_with_contract_id( .consensus_parameters .predicate_params .max_gas_per_predicate = TARGET_BLOCK_GAS_LIMIT; - // Some txs (e.g. smo) are too big so increasing this arbitrarily - config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT * 3; + config.chain_conf.block_gas_limit = TARGET_BLOCK_GAS_LIMIT; + config.chain_conf.consensus_parameters.gas_costs = GasCosts::new(default_gas_costs()); + config + .chain_conf + .consensus_parameters + .fee_params + .gas_per_byte = 0; config.utxo_validation = false; config.block_production = Trigger::Instant; @@ -443,41 +452,6 @@ fn run_with_service_with_extra_inputs( fn block_target_gas(c: &mut Criterion) { let mut group = c.benchmark_group("block target estimation"); - run( - "Script with meq opcode and infinite loop", - &mut group, - [ - op::movi(0x10, (1 << 18) - 1), - op::meq(0x11, RegId::SP, RegId::SP, 0x10), - op::jmpb(RegId::ZERO, 0), - ] - .to_vec(), - vec![], - ); - - run( - "Script with logd opcode and infinite loop", - &mut group, - [ - op::movi(0x10, (1 << 18) - 1), - op::logd(RegId::ZERO, RegId::ZERO, RegId::ZERO, 0x10), - op::jmpb(RegId::ZERO, 0), - ] - .to_vec(), - vec![], - ); - - run( - "Script with gtf opcode and infinite loop", - &mut group, - [ - op::gtf(0x10, RegId::ZERO, GTFArgs::InputCoinOwner as u16), - op::jmpb(RegId::ZERO, 0), - ] - .to_vec(), - vec![], - ); - run_alu(&mut group); run_contract(&mut group); @@ -524,7 +498,7 @@ fn setup_instructions() -> Vec { op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), + op::movi(0x12, (1 << 18) - 1), ] } @@ -533,10 +507,25 @@ fn setup_instructions() -> Vec { /// be called infinitely. The closure should accept one argument - /// the register where the iterator is stored. fn u256_iterator_loop(opcode: impl Fn(RegId) -> Instruction) -> Vec { + u256_iterator_loop_with_step(opcode, 1) +} + +/// Returns a bytecode that contains an infinite loop that increases the `u256` iterator by +/// `step` each iteration. A function expects a closure that returns an opcode that must +/// be called infinitely. The closure should accept one argument - +/// the register where the iterator is stored. +fn u256_iterator_loop_with_step( + opcode: impl Fn(RegId) -> Instruction, + step: u32, +) -> Vec { // Register where we store an iterator. let iterator_register = RegId::new(0x20); + let step_register = RegId::new(0x21); vec![ + // Store size of the iterator. op::movi(iterator_register, 32), + // Store step value. + op::movi(step_register, step), // Allocate 32 bytes for u256 iterator. op::aloc(iterator_register), // Store the address of the u256 iterator into `iterator_register`. @@ -549,7 +538,7 @@ fn u256_iterator_loop(opcode: impl Fn(RegId) -> Instruction) -> Vec op::wqop( iterator_register, iterator_register, - RegId::ONE, + step_register, MathOp::ADD as u8, ), // Jump 4 instructions(jmpb, wqop, opcode, noop) back. @@ -560,7 +549,7 @@ fn u256_iterator_loop(opcode: impl Fn(RegId) -> Instruction) -> Vec fn call_contract_repeat() -> Vec { let mut instructions = setup_instructions(); instructions.extend(vec![ - op::call(0x10, RegId::ZERO, 0x11, 0x12), + op::call(0x10, RegId::ZERO, 0x11, RegId::CGAS), op::jmpb(RegId::ZERO, 0), ]); instructions @@ -568,7 +557,7 @@ fn call_contract_repeat() -> Vec { fn call_contract_once() -> Vec { let mut instructions = setup_instructions(); - instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, 0x12)]); + instructions.extend(vec![op::call(0x10, RegId::ZERO, 0x11, RegId::CGAS)]); instructions } diff --git a/benches/benches/block_target_gas_set/contract.rs b/benches/benches/block_target_gas_set/contract.rs index 6f55119167d..f4b1b8363b1 100644 --- a/benches/benches/block_target_gas_set/contract.rs +++ b/benches/benches/block_target_gas_set/contract.rs @@ -12,6 +12,7 @@ use fuel_core_types::{ // This register is used by `setup_instructions` function to set contract id. const CONTRACT_ID_REGISTER: RegId = RegId::new(0x10); +const SEQUENTIAL_STEP: u32 = 10; // BAL: Balance of contract ID // BHEI: Block height @@ -49,13 +50,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let contract_instructions = u256_iterator_loop(|iterator| op::bal(0x13, iterator, CONTRACT_ID_REGISTER)); - let mut instructions = setup_instructions(); - instructions.extend(vec![op::call( - CONTRACT_ID_REGISTER, - RegId::ZERO, - 0x11, - 0x12, - )]); + let instructions = call_contract_once(); let id = "contract/bal contract"; shared_runner_builder @@ -99,13 +94,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // burn { let contract = u256_iterator_loop(|iterator| op::burn(RegId::ONE, iterator)); - let mut instructions = setup_instructions(); - instructions.extend(vec![op::call( - CONTRACT_ID_REGISTER, - RegId::ZERO, - 0x11, - 0x12, - )]); + let instructions = call_contract_once(); shared_runner_builder.build_with_new_contract(contract).run( "contract/burn", group, @@ -126,8 +115,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - op::movi(0x12, TARGET_BLOCK_GAS_LIMIT as u32), - op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), + op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, RegId::CGAS), op::jmpb(RegId::ZERO, 0), ]; @@ -334,7 +322,6 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // } // smo - { let predicate = op::ret(RegId::ONE).to_bytes().to_vec(); let owner = Input::predicate_owner(&predicate); @@ -363,7 +350,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![ op::movi(0x18, 1), // coins to send - op::call(CONTRACT_ID_REGISTER, 0x12, 0x11, 0x12), + op::call(CONTRACT_ID_REGISTER, 0x12, 0x11, RegId::CGAS), ]); let mut data = script_data.clone(); data.extend( @@ -381,36 +368,19 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } // scwq - - // TODO: This is under-costed, so it runs too long and will complete before running out - // of gas at 100_000. - // let size = 2620_u32; // 18bit integer maxes at 262144 - // let contract: Vec<_> = (0..100_u32) - // .map(|x| x * size) - // .map(|x| vec![op::movi(0x13, x), op::scwq(0x13, 0x29, 0x14)]) // copy range starting at $rA of size $rC - // .flatten() - // .collect(); - // let gas = 100_000; - // let instructions = vec![ - // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, gas), - // op::movi(0x14, size), - // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), - // ]; - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service( - // "contract/scwq", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // ); + { + let step = SEQUENTIAL_STEP; + let contract = + u256_iterator_loop_with_step(|iterator| op::scwq(iterator, 0x13, 0x15), step); + let mut instructions = vec![op::movi(0x15, step)]; + instructions.extend(call_contract_once()); + shared_runner_builder.build_with_new_contract(contract).run( + "contract/scwq", + group, + instructions, + script_data.clone(), + ); + } // srw @@ -419,7 +389,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { let mut instructions = setup_instructions(); instructions.extend(vec![ op::movi(0x15, 2000), - op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), + op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, RegId::CGAS), ]); shared_runner_builder.build_with_new_contract(contract).run( "contract/srw", @@ -430,35 +400,26 @@ pub fn run_contract(group: &mut BenchmarkGroup) { } // srwq - - // TODO: This is under-costed, so it runs too long and will complete before running out of gas - // let size = 2620_u32; - // let contract = (0..2620) - // .map(|x| x * size) - // .map(|x| vec![op::movi(0x13, x), op::srwq(0x14, 0x29, 0x13, 0x15)]) - // .flatten() - // .collect(); - // let gas = 100_000; - // let instructions = vec![ - // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, gas), - // op::movi(0x15, size), - // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), - // ]; - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service( - // "contract/srwq", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // ); + { + let step = SEQUENTIAL_STEP; + let mut contract = vec![ + op::movi(0x15, step), + op::movi(0x16, step * Bytes32::LEN as u32), + op::aloc(0x16), + op::move_(0x17, RegId::HP), + ]; + contract.extend(u256_iterator_loop_with_step( + |iterator| op::srwq(0x17, 0x13, iterator, 0x15), + step, + )); + let instructions = call_contract_once(); + shared_runner_builder.build_with_new_contract(contract).run( + "contract/srwq", + group, + instructions, + script_data.clone(), + ); + } // sww { @@ -468,7 +429,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, - 0x12, + RegId::CGAS, )]); shared_runner_builder.build_with_new_contract(contract).run( "contract/sww", @@ -477,38 +438,23 @@ pub fn run_contract(group: &mut BenchmarkGroup) { script_data.clone(), ); } - // swwq - // TODO: This is under-costed, so it runs too long and will complete before running out of gas - // let size = 2620_u32; - // // Copy value stored at $rC to the state starting at 0x13 - // let contract = (0..2620) - // .map(|x| x * size) - // .map(|x| vec![op::movi(0x13, x), op::swwq(0x13, 0x29, 0x14, 0x15)]) .flatten() - // .collect(); - // let gas = 100_000; - // let value = 2000; - // let instructions = vec![ - // op::gtf_args(CONTRACT_ID_REGISTER, 0x00, GTFArgs::ScriptData), - // op::addi(0x11, 0x10, ContractId::LEN.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::addi(0x11, 0x11, WORD_SIZE.try_into().unwrap()), - // op::movi(0x12, gas), - // op::movi(0x14, value), - // op::movi(0x15, size), - // op::call(CONTRACT_ID_REGISTER, RegId::ZERO, 0x11, 0x12), - // ]; - // replace_contract_in_service(&mut service, &contract_id, contract); - // run_with_service( - // "contract/swwq", - // group, - // instructions, - // script_data.clone(), - // &service, - // contract_id, - // &rt, - // &mut rng, - // ); + // swwq + { + let step = SEQUENTIAL_STEP; + let contract = u256_iterator_loop_with_step( + |iterator| op::swwq(iterator, 0x13, RegId::ZERO, 0x15), + step, + ); + let mut instructions = vec![op::movi(0x15, step)]; + instructions.extend(call_contract_once()); + shared_runner_builder.build_with_new_contract(contract).run( + "contract/swwq", + group, + instructions, + script_data.clone(), + ); + } // time { @@ -532,7 +478,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { op::movi(0x13, (1 << 18) - 1), op::movi(0x15, 2000), op::movi(0x14, 1), - op::call(CONTRACT_ID_REGISTER, 0x13, 0x15, 0x12), + op::call(CONTRACT_ID_REGISTER, 0x13, 0x15, RegId::CGAS), ]); shared_runner_builder.build_with_new_contract(contract).run( "contract/tr", @@ -569,7 +515,7 @@ pub fn run_contract(group: &mut BenchmarkGroup) { // } // // instructions.extend(vec![ - // op::call(0x10, RegId::ZERO, 0x11, 0x12), + // op::call(0x10, RegId::ZERO, 0x11, RegId::CGAS), // // op::jmpb(RegId::ZERO, 0), // ]); // diff --git a/benches/benches/block_target_gas_set/default_gas_costs.rs b/benches/benches/block_target_gas_set/default_gas_costs.rs new file mode 100644 index 00000000000..7431bbeaa6d --- /dev/null +++ b/benches/benches/block_target_gas_set/default_gas_costs.rs @@ -0,0 +1,172 @@ +use super::*; +pub fn default_gas_costs() -> GasCostsValues { + GasCostsValues { + add: 1, + addi: 1, + aloc: 1, + and: 1, + andi: 1, + bal: 26, + bhei: 1, + bhsh: 1, + burn: 27286, + cb: 1, + cfei: 1, + cfsi: 1, + croo: 37, + div: 1, + divi: 1, + eck1: 3351, + ecr1: 46061, + ed19: 3163, + eq: 1, + exp: 1, + expi: 1, + flag: 1, + gm: 1, + gt: 1, + gtf: 1, + ji: 1, + jmp: 1, + jne: 1, + jnei: 1, + jnzi: 1, + jmpf: 1, + jmpb: 1, + jnzf: 1, + jnzb: 1, + jnef: 1, + jneb: 1, + lb: 1, + log: 92, + lt: 1, + lw: 1, + mint: 25370, + mlog: 1, + vm_initialization: 1, + modi: 1, + mod_op: 1, + movi: 1, + mroo: 4, + mul: 1, + muli: 1, + mldv: 3, + noop: 1, + not: 1, + or: 1, + ori: 1, + poph: 1, + popl: 1, + pshh: 1, + pshl: 1, + move_op: 1, + ret: 135, + sb: 1, + sll: 1, + slli: 1, + srl: 1, + srli: 1, + srw: 237, + sub: 1, + subi: 1, + sw: 1, + sww: 27313, + time: 1, + tr: 38459, + tro: 26269, + wdcm: 1, + wqcm: 2, + wdop: 2, + wqop: 2, + wdml: 2, + wqml: 3, + wddv: 4, + wqdv: 6, + wdmd: 10, + wqmd: 16, + wdam: 8, + wqam: 10, + wdmm: 9, + wqmm: 9, + xor: 1, + xori: 1, + call: DependentCost::LightOperation { + base: 1171, + units_per_gas: 47, + }, + ccp: DependentCost::LightOperation { + base: 39, + units_per_gas: 65, + }, + csiz: DependentCost::LightOperation { + base: 49, + units_per_gas: 214, + }, + k256: DependentCost::LightOperation { + base: 277, + units_per_gas: 3, + }, + ldc: DependentCost::LightOperation { + base: 37, + units_per_gas: 63, + }, + logd: DependentCost::LightOperation { + base: 444, + units_per_gas: 3, + }, + mcl: DependentCost::LightOperation { + base: 1, + units_per_gas: 500, + }, + mcli: DependentCost::LightOperation { + base: 1, + units_per_gas: 500, + }, + mcp: DependentCost::LightOperation { + base: 2, + units_per_gas: 493, + }, + mcpi: DependentCost::LightOperation { + base: 4, + units_per_gas: 1023, + }, + meq: DependentCost::LightOperation { + base: 2, + units_per_gas: 1111, + }, + rvrt: 136, + s256: DependentCost::LightOperation { + base: 44, + units_per_gas: 3, + }, + scwq: DependentCost::HeavyOperation { + base: 28687, + gas_per_unit: 27036, + }, + smo: DependentCost::LightOperation { + base: 58089, + units_per_gas: 1, + }, + srwq: DependentCost::LightOperation { + base: 121, + units_per_gas: 1, + }, + swwq: DependentCost::HeavyOperation { + base: 26790, + gas_per_unit: 25451, + }, + contract_root: DependentCost::LightOperation { + base: 44, + units_per_gas: 2, + }, + state_root: DependentCost::HeavyOperation { + base: 347, + gas_per_unit: 176, + }, + new_storage_per_byte: 1, + retd: DependentCost::LightOperation { + base: 466, + units_per_gas: 3, + }, + } +} diff --git a/benches/benches/block_target_gas_set/mod.rs b/benches/benches/block_target_gas_set/mod.rs index 8bda84df858..cd266169cf3 100644 --- a/benches/benches/block_target_gas_set/mod.rs +++ b/benches/benches/block_target_gas_set/mod.rs @@ -1,3 +1,8 @@ +use fuel_core_types::fuel_tx::{ + DependentCost, + GasCostsValues, +}; + pub mod alu; pub mod crypto; @@ -7,3 +12,5 @@ pub mod flow; pub mod contract; pub mod memory; + +pub mod default_gas_costs; diff --git a/benches/benches/vm_set/blockchain.rs b/benches/benches/vm_set/blockchain.rs index 67553ef4b92..a716f4d46d6 100644 --- a/benches/benches/vm_set/blockchain.rs +++ b/benches/benches/vm_set/blockchain.rs @@ -255,7 +255,7 @@ pub fn run(c: &mut Criterion) { run_group_ref( &mut call, format!("{i}"), - VmBench::new(op::call(0x10, RegId::ZERO, 0x11, 0x12)) + VmBench::new(op::call(0x10, RegId::ZERO, 0x11, RegId::CGAS)) .with_db(db.to_vm_database()) .with_contract_code(code) .with_data(data) diff --git a/benches/src/bin/collect.rs b/benches/src/bin/collect.rs index fd0db403d96..0b81125d1d0 100644 --- a/benches/src/bin/collect.rs +++ b/benches/src/bin/collect.rs @@ -319,7 +319,10 @@ fn decode_input(line: &str) -> Option { fn map_to_ratio(baseline: u64, mean: Duration) -> u64 { let mean: u64 = mean.as_nanos().try_into().unwrap(); - mean.checked_div(baseline).unwrap_or(1).max(1) + (mean + (baseline - 1)) + .checked_div(baseline) + .unwrap_or(1) + .max(1) } impl Display for State {