From fd8b3879f059a8dc1cbf8c8c1bd4efa75b784bb0 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 11:20:44 +0300 Subject: [PATCH 01/14] vm - separate VMAddress and H256 --- .../src/facade/scenario_world_steps.rs | 7 +- .../src/scenario/model/value/address_key.rs | 4 + .../src/scenario/model/value/address_value.rs | 4 + .../src/scenario/run_vm/check_state.rs | 2 +- .../scenario/src/scenario/run_vm/sc_call.rs | 4 +- .../scenario/src/scenario/run_vm/sc_deploy.rs | 11 +- .../scenario/src/scenario/run_vm/sc_query.rs | 4 +- .../scenario/src/scenario/run_vm/set_state.rs | 21 +-- .../scenario/src/scenario/run_vm/transfer.rs | 6 +- .../src/whitebox/contract_obj_wrapper.rs | 90 +++++++---- .../scenario/src/whitebox/raw_converter.rs | 10 +- vm/Cargo.toml | 1 + vm/src/display_util.rs | 9 +- vm/src/lib.rs | 1 + .../builtin_func_trait.rs | 9 +- .../general/change_owner_mock.rs | 9 +- .../transfer/esdt_multi_transfer_mock.rs | 5 +- .../transfer/esdt_nft_transfer_mock.rs | 5 +- .../transfer/transfer_common.rs | 5 +- vm/src/tx_execution/exec_call.rs | 12 +- vm/src/tx_execution/exec_create.rs | 5 +- vm/src/tx_execution/exec_general_tx.rs | 12 +- vm/src/tx_mock/tx_async_call_data.rs | 14 +- vm/src/tx_mock/tx_cache.rs | 19 ++- vm/src/tx_mock/tx_cache_balance_util.rs | 21 ++- vm/src/tx_mock/tx_cache_source.rs | 13 +- vm/src/tx_mock/tx_context.rs | 12 +- vm/src/tx_mock/tx_input.rs | 15 +- vm/src/tx_mock/tx_input_util.rs | 2 +- vm/src/tx_mock/tx_log.rs | 4 +- .../tx_managed_types/tx_managed_buffer.rs | 11 +- vm/src/types.rs | 7 + vm/src/types/vm_address.rs | 140 ++++++++++++++++ vm/src/types/vm_code_metadata.rs | 122 ++++++++++++++ vm/src/types/vm_h256.rs | 153 ++++++++++++++++++ vm/src/vm_hooks/vh_debugger_stack.rs | 24 ++- vm/src/vm_hooks/vh_handler/vh_blockchain.rs | 11 +- vm/src/vm_hooks/vh_handler/vh_send.rs | 12 +- vm/src/vm_hooks/vh_handler/vh_storage.rs | 12 +- vm/src/vm_hooks/vh_managed_types_cell.rs | 17 +- vm/src/vm_hooks/vh_source.rs | 17 +- vm/src/world_mock/account_data.rs | 7 +- vm/src/world_mock/blockchain_mock.rs | 14 +- .../blockchain_mock_account_util.rs | 16 +- vm/src/world_mock/blockchain_tx_info.rs | 7 +- vm/src/world_mock/esdt_instance_metadata.rs | 4 +- 46 files changed, 685 insertions(+), 225 deletions(-) create mode 100644 vm/src/types.rs create mode 100644 vm/src/types/vm_address.rs create mode 100644 vm/src/types/vm_code_metadata.rs create mode 100644 vm/src/types/vm_h256.rs diff --git a/framework/scenario/src/facade/scenario_world_steps.rs b/framework/scenario/src/facade/scenario_world_steps.rs index cecc65662f..85917173da 100644 --- a/framework/scenario/src/facade/scenario_world_steps.rs +++ b/framework/scenario/src/facade/scenario_world_steps.rs @@ -1,10 +1,9 @@ +use multiversx_sc::types::{heap::Address, ContractCall}; + use crate::{ api::DebugApi, facade::ScenarioWorld, - multiversx_sc::{ - codec::{CodecFrom, PanicErrorHandler, TopEncodeMulti}, - types::{Address, ContractCall}, - }, + multiversx_sc::codec::{CodecFrom, PanicErrorHandler, TopEncodeMulti}, scenario::{model::*, ScenarioRunner}, }; diff --git a/framework/scenario/src/scenario/model/value/address_key.rs b/framework/scenario/src/scenario/model/value/address_key.rs index eeebd2f6ed..5bbc1d79ae 100644 --- a/framework/scenario/src/scenario/model/value/address_key.rs +++ b/framework/scenario/src/scenario/model/value/address_key.rs @@ -27,6 +27,10 @@ impl AddressKey { pub fn to_address(&self) -> Address { self.value.clone() } + + pub fn to_vm_address(&self) -> multiversx_chain_vm::types::VMAddress { + self.value.as_array().into() + } } impl Ord for AddressKey { diff --git a/framework/scenario/src/scenario/model/value/address_value.rs b/framework/scenario/src/scenario/model/value/address_value.rs index 9f9b65b6e2..85886e4cf8 100644 --- a/framework/scenario/src/scenario/model/value/address_value.rs +++ b/framework/scenario/src/scenario/model/value/address_value.rs @@ -29,6 +29,10 @@ impl AddressValue { pub fn to_address(&self) -> Address { self.value.clone() } + + pub fn to_vm_address(&self) -> multiversx_chain_vm::types::VMAddress { + self.value.as_array().into() + } } impl fmt::Display for AddressValue { diff --git a/framework/scenario/src/scenario/run_vm/check_state.rs b/framework/scenario/src/scenario/run_vm/check_state.rs index 9f05c8c399..bc630cf38f 100644 --- a/framework/scenario/src/scenario/run_vm/check_state.rs +++ b/framework/scenario/src/scenario/run_vm/check_state.rs @@ -23,7 +23,7 @@ impl ScenarioVMRunner { fn execute(state: &BlockchainMock, accounts: &CheckAccounts) { for (expected_address, expected_account) in accounts.accounts.iter() { - if let Some(account) = state.accounts.get(&expected_address.value) { + if let Some(account) = state.accounts.get(&expected_address.to_vm_address()) { assert!( expected_account.nonce.check(account.nonce), "bad account nonce. Address: {}. Want: {}. Have: {}", diff --git a/framework/scenario/src/scenario/run_vm/sc_call.rs b/framework/scenario/src/scenario/run_vm/sc_call.rs index 9713c84937..a069be02e1 100644 --- a/framework/scenario/src/scenario/run_vm/sc_call.rs +++ b/framework/scenario/src/scenario/run_vm/sc_call.rs @@ -48,8 +48,8 @@ pub(crate) fn execute( ) -> (TxResult, BlockchainMock) { let tx = &sc_call_step.tx; let tx_input = TxInput { - from: tx.from.to_address(), - to: tx.to.to_address(), + from: tx.from.to_vm_address(), + to: tx.to.to_vm_address(), egld_value: tx.egld_value.value.clone(), esdt_values: tx_esdt_transfers_from_scenario(tx.esdt_value.as_slice()), func_name: tx.function.clone().into(), diff --git a/framework/scenario/src/scenario/run_vm/sc_deploy.rs b/framework/scenario/src/scenario/run_vm/sc_deploy.rs index 2ad72029a8..205fefc829 100644 --- a/framework/scenario/src/scenario/run_vm/sc_deploy.rs +++ b/framework/scenario/src/scenario/run_vm/sc_deploy.rs @@ -48,7 +48,7 @@ impl ScenarioVMRunner { RequestedResult::multi_decode_or_handle_err(&mut raw_result, PanicErrorHandler) .unwrap(); - (new_address, deser_result) + (new_address.as_array().into(), deser_result) } } @@ -58,8 +58,8 @@ pub(crate) fn execute( ) -> (TxResult, Address, BlockchainMock) { let tx = &sc_deploy_step.tx; let tx_input = TxInput { - from: tx.from.to_address(), - to: Address::zero(), + from: tx.from.to_vm_address(), + to: multiversx_chain_vm::types::VMAddress::zero(), egld_value: tx.egld_value.value.clone(), esdt_values: Vec::new(), func_name: TxFunctionName::INIT, @@ -73,7 +73,8 @@ pub(crate) fn execute( tx_hash: generate_tx_hash_dummy(&sc_deploy_step.id), ..Default::default() }; - sc_create(tx_input, &tx.contract_code.value, state) + let (tx_result, address, blockchain_mock) = sc_create(tx_input, &tx.contract_code.value, state); + (tx_result, address.as_array().into(), blockchain_mock) } fn execute_and_check( @@ -84,5 +85,5 @@ fn execute_and_check( if let Some(tx_expect) = &sc_deploy_step.expect { check_tx_output(&sc_deploy_step.id, tx_expect, &tx_result); } - (tx_result, address, state) + (tx_result, address.as_array().into(), state) } diff --git a/framework/scenario/src/scenario/run_vm/sc_query.rs b/framework/scenario/src/scenario/run_vm/sc_query.rs index 60f742346a..ef659a8749 100644 --- a/framework/scenario/src/scenario/run_vm/sc_query.rs +++ b/framework/scenario/src/scenario/run_vm/sc_query.rs @@ -48,8 +48,8 @@ pub(crate) fn execute( sc_query_step: &ScQueryStep, ) -> (TxResult, BlockchainMock) { let tx_input = TxInput { - from: sc_query_step.tx.to.to_address(), - to: sc_query_step.tx.to.to_address(), + from: sc_query_step.tx.to.to_vm_address(), + to: sc_query_step.tx.to.to_vm_address(), egld_value: BigUint::from(0u32), esdt_values: Vec::new(), func_name: sc_query_step.tx.function.clone().into(), diff --git a/framework/scenario/src/scenario/run_vm/set_state.rs b/framework/scenario/src/scenario/run_vm/set_state.rs index 85780d5791..2f8239793c 100644 --- a/framework/scenario/src/scenario/run_vm/set_state.rs +++ b/framework/scenario/src/scenario/run_vm/set_state.rs @@ -1,8 +1,11 @@ -use crate::{multiversx_sc::types::heap::Address, scenario::model::SetStateStep}; +use crate::scenario::model::SetStateStep; -use multiversx_chain_vm::world_mock::{ - AccountData, AccountEsdt, BlockInfo as CrateBlockInfo, BlockchainMock, EsdtData, EsdtInstance, - EsdtInstanceMetadata, EsdtInstances, EsdtRoles, +use multiversx_chain_vm::{ + types::VMAddress, + world_mock::{ + AccountData, AccountEsdt, BlockInfo as CrateBlockInfo, BlockchainMock, EsdtData, + EsdtInstance, EsdtInstanceMetadata, EsdtInstances, EsdtRoles, + }, }; use super::ScenarioVMRunner; @@ -29,7 +32,7 @@ fn execute(state: &mut BlockchainMock, set_state_step: &SetStateStep) { ); state.validate_and_add_account(AccountData { - address: address.to_address(), + address: address.to_vm_address(), nonce: account .nonce .as_ref() @@ -54,7 +57,7 @@ fn execute(state: &mut BlockchainMock, set_state_step: &SetStateStep) { contract_owner: account .owner .as_ref() - .map(|address_value| address_value.value.clone()), + .map(|address_value| address_value.to_vm_address()), developer_rewards: account .developer_rewards .as_ref() @@ -68,9 +71,9 @@ fn execute(state: &mut BlockchainMock, set_state_step: &SetStateStep) { "field should have SC format" ); state.put_new_address( - new_address.creator_address.value.clone(), + new_address.creator_address.to_vm_address(), new_address.creator_nonce.value, - new_address.new_address.value.clone(), + new_address.new_address.to_vm_address(), ) } if let Some(block_info_obj) = &*set_state_step.previous_block_info { @@ -141,7 +144,7 @@ fn convert_scenario_esdt_instance_to_world_mock( creator: scenario_esdt .creator .as_ref() - .map(|creator| Address::from_slice(creator.value.as_slice())), + .map(|creator| VMAddress::from_slice(creator.value.as_slice())), royalties: scenario_esdt .royalties .as_ref() diff --git a/framework/scenario/src/scenario/run_vm/transfer.rs b/framework/scenario/src/scenario/run_vm/transfer.rs index eeb0501411..df35fe6835 100644 --- a/framework/scenario/src/scenario/run_vm/transfer.rs +++ b/framework/scenario/src/scenario/run_vm/transfer.rs @@ -14,7 +14,7 @@ impl ScenarioVMRunner { pub fn perform_validator_reward(&mut self, validator_rewards_step: &ValidatorRewardStep) { self.blockchain_mock.increase_validator_reward( - &validator_rewards_step.tx.to.to_address(), + &validator_rewards_step.tx.to.to_vm_address(), &validator_rewards_step.tx.egld_value.value, ); } @@ -22,8 +22,8 @@ impl ScenarioVMRunner { fn execute(mut state: BlockchainMock, tx_transfer: &TxTransfer) -> BlockchainMock { let tx_input = TxInput { - from: tx_transfer.from.value.clone(), - to: tx_transfer.to.value.clone(), + from: tx_transfer.from.to_vm_address(), + to: tx_transfer.to.to_vm_address(), egld_value: tx_transfer.egld_value.value.clone(), esdt_values: tx_esdt_transfers_from_scenario(tx_transfer.esdt_value.as_slice()), func_name: TxFunctionName::EMPTY, diff --git a/framework/scenario/src/whitebox/contract_obj_wrapper.rs b/framework/scenario/src/whitebox/contract_obj_wrapper.rs index 0f4c70995a..5f136e6496 100644 --- a/framework/scenario/src/whitebox/contract_obj_wrapper.rs +++ b/framework/scenario/src/whitebox/contract_obj_wrapper.rs @@ -6,10 +6,7 @@ use crate::{ multiversx_sc::{ codec::{TopDecode, TopEncode}, contract_base::{CallableContract, ContractBase}, - types::{ - heap::{Address, H256}, - EsdtLocalRole, - }, + types::{heap::Address, EsdtLocalRole}, }, testing_framework::raw_converter::bytes_to_hex, }; @@ -19,6 +16,7 @@ use multiversx_chain_vm::{ tx_mock::{ TxCache, TxContext, TxContextRef, TxContextStack, TxFunctionName, TxInput, TxResult, }, + types::VMAddress, world_mock::{AccountData, AccountEsdt, EsdtInstanceMetadata}, BlockchainMock, }; @@ -98,7 +96,7 @@ impl BlockchainStateWrapper { } pub fn check_egld_balance(&self, address: &Address, expected_balance: &num_bigint::BigUint) { - let actual_balance = match &self.rc_b_mock.accounts.get(address) { + let actual_balance = match &self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => acc.egld_balance.clone(), None => num_bigint::BigUint::zero(), }; @@ -118,7 +116,7 @@ impl BlockchainStateWrapper { token_id: &[u8], expected_balance: &num_bigint::BigUint, ) { - let actual_balance = match &self.rc_b_mock.accounts.get(address) { + let actual_balance = match &self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => acc.esdt.get_esdt_balance(token_id, 0), None => num_bigint::BigUint::zero(), }; @@ -144,7 +142,7 @@ impl BlockchainStateWrapper { T: TopEncode + TopDecode + PartialEq + core::fmt::Debug, { let (actual_balance, actual_attributes_serialized) = - match &self.rc_b_mock.accounts.get(address) { + match &self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => { let esdt_data = acc.esdt.get_by_identifier_or_default(token_id); let opt_instance = esdt_data.instances.get_by_nonce(nonce); @@ -290,19 +288,20 @@ impl BlockchainStateWrapper { sc_identifier: Option>, sc_mandos_path_expr: Option>, ) { - if self.rc_b_mock.account_exists(address) { + let vm_address = to_vm_address(address); + if self.rc_b_mock.account_exists(&vm_address) { panic!("Address already used: {:?}", address_to_hex(address)); } let acc_data = AccountData { - address: address.clone(), + address: vm_address, nonce: 0, egld_balance: egld_balance.clone(), esdt: AccountEsdt::default(), storage: HashMap::new(), username: Vec::new(), contract_path: sc_identifier, - contract_owner: owner.cloned(), + contract_owner: owner.map(to_vm_address), developer_rewards: num_bigint::BigUint::zero(), }; self.scenario_generator @@ -323,11 +322,20 @@ impl BlockchainStateWrapper { CB: ContractBase + CallableContract + 'static, ContractObjBuilder: 'static + Copy + Fn() -> CB, { + let deployer_vm_address = to_vm_address(deployer); let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - let deployer_acc = b_mock_ref.accounts.get(deployer).unwrap().clone(); + let deployer_acc = b_mock_ref + .accounts + .get(&deployer_vm_address) + .unwrap() + .clone(); let new_sc_address = self.address_factory.new_sc_address(); - b_mock_ref.put_new_address(deployer.clone(), deployer_acc.nonce, new_sc_address.clone()); + b_mock_ref.put_new_address( + deployer_vm_address, + deployer_acc.nonce, + to_vm_address(&new_sc_address), + ); ContractObjWrapper::new(new_sc_address, obj_builder) } @@ -348,7 +356,8 @@ impl BlockchainStateWrapper { pub fn set_egld_balance(&mut self, address: &Address, balance: &num_bigint::BigUint) { let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - match b_mock_ref.accounts.get_mut(address) { + let vm_address = to_vm_address(address); + match b_mock_ref.accounts.get_mut(&vm_address) { Some(acc) => { acc.egld_balance = balance.clone(); @@ -369,7 +378,8 @@ impl BlockchainStateWrapper { balance: &num_bigint::BigUint, ) { let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - match b_mock_ref.accounts.get_mut(address) { + let vm_address = to_vm_address(address); + match b_mock_ref.accounts.get_mut(&vm_address) { Some(acc) => { acc.esdt.set_esdt_balance( token_id.to_vec(), @@ -415,8 +425,8 @@ impl BlockchainStateWrapper { developer_rewards: num_bigint::BigUint, ) { let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - - match b_mock_ref.accounts.get_mut(address) { + let vm_address = to_vm_address(address); + match b_mock_ref.accounts.get_mut(&vm_address) { Some(acc) => { acc.developer_rewards = developer_rewards; @@ -444,15 +454,15 @@ impl BlockchainStateWrapper { uris: &[Vec], ) { let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - - match b_mock_ref.accounts.get_mut(address) { + let vm_address = to_vm_address(address); + match b_mock_ref.accounts.get_mut(&vm_address) { Some(acc) => { acc.esdt.set_esdt_balance( token_id.to_vec(), nonce, balance, EsdtInstanceMetadata { - creator: creator.cloned(), + creator: creator.map(to_vm_address), attributes: serialize_attributes(attributes), royalties, name: name.unwrap_or_default().to_vec(), @@ -477,7 +487,8 @@ impl BlockchainStateWrapper { roles: &[EsdtLocalRole], ) { let b_mock_ref = Rc::get_mut(&mut self.rc_b_mock).unwrap(); - match b_mock_ref.accounts.get_mut(address) { + let vm_address = to_vm_address(address); + match b_mock_ref.accounts.get_mut(&vm_address) { Some(acc) => { let mut roles_raw = Vec::new(); for role in roles { @@ -613,7 +624,8 @@ impl BlockchainStateWrapper { } pub fn add_mandos_set_account(&mut self, address: &Address) { - if let Some(acc) = self.rc_b_mock.accounts.get(address) { + let vm_address = to_vm_address(address); + if let Some(acc) = self.rc_b_mock.accounts.get(&vm_address) { let opt_contract_path = self.address_to_code_path.get(address); self.scenario_generator .set_account(acc, opt_contract_path.cloned()); @@ -621,7 +633,8 @@ impl BlockchainStateWrapper { } pub fn add_mandos_check_account(&mut self, address: &Address) { - if let Some(acc) = self.rc_b_mock.accounts.get(address) { + let vm_address = to_vm_address(address); + if let Some(acc) = self.rc_b_mock.accounts.get(&vm_address) { self.scenario_generator.check_account(acc); } } @@ -727,17 +740,17 @@ impl BlockchainStateWrapper { let rust_zero = num_bigint::BigUint::zero(); if egld_payment > &rust_zero { - if let Err(err) = tx_cache.subtract_egld_balance(caller, egld_payment) { + if let Err(err) = tx_cache.subtract_egld_balance(&to_vm_address(caller), egld_payment) { return TxResult::from_panic_obj(&err); } - tx_cache.increase_egld_balance(sc_address, egld_payment); + tx_cache.increase_egld_balance(&to_vm_address(sc_address), egld_payment); } for esdt in &esdt_payments { if esdt.value > rust_zero { let transfer_result = tx_cache.transfer_esdt_balance( - caller, - sc_address, + &to_vm_address(caller), + &to_vm_address(sc_address), &esdt.token_identifier, esdt.nonce, &esdt.value, @@ -802,7 +815,7 @@ impl BlockchainStateWrapper { impl BlockchainStateWrapper { pub fn get_egld_balance(&self, address: &Address) -> num_bigint::BigUint { - match self.rc_b_mock.accounts.get(address) { + match self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => acc.egld_balance.clone(), None => panic!( "get_egld_balance: Account {:?} does not exist", @@ -817,7 +830,7 @@ impl BlockchainStateWrapper { token_id: &[u8], token_nonce: u64, ) -> num_bigint::BigUint { - match self.rc_b_mock.accounts.get(address) { + match self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => acc.esdt.get_esdt_balance(token_id, token_nonce), None => panic!( "get_esdt_balance: Account {:?} does not exist", @@ -832,7 +845,7 @@ impl BlockchainStateWrapper { token_id: &[u8], token_nonce: u64, ) -> Option { - match self.rc_b_mock.accounts.get(address) { + match self.rc_b_mock.accounts.get(&to_vm_address(address)) { Some(acc) => match acc.esdt.get_by_identifier(token_id) { Some(esdt_data) => esdt_data .instances @@ -849,7 +862,7 @@ impl BlockchainStateWrapper { pub fn dump_state(&self) { for addr in self.rc_b_mock.accounts.keys() { - self.dump_state_for_account_hex_attributes(addr); + self.dump_state_for_account_hex_attributes(&to_framework_address(addr)); println!(); } } @@ -865,7 +878,8 @@ impl BlockchainStateWrapper { &self, address: &Address, ) { - let account = match self.rc_b_mock.accounts.get(address) { + let vm_address = to_vm_address(address); + let account = match self.rc_b_mock.accounts.get(&vm_address) { Some(acc) => acc, None => panic!( "dump_state_for_account: Account {:?} does not exist", @@ -928,15 +942,15 @@ fn build_tx_input( esdt_values: Vec, ) -> TxInput { TxInput { - from: caller.clone(), - to: dest.clone(), + from: to_vm_address(caller), + to: to_vm_address(dest), egld_value: egld_value.clone(), esdt_values, func_name: TxFunctionName::EMPTY, args: Vec::new(), gas_limit: u64::MAX, gas_price: 0, - tx_hash: H256::zero(), + tx_hash: multiversx_chain_vm::types::H256::zero(), ..Default::default() } } @@ -985,3 +999,11 @@ where let c_base = func(); Box::new(c_base) } + +fn to_vm_address(address: &Address) -> VMAddress { + address.as_array().into() +} + +fn to_framework_address(vm_address: &VMAddress) -> Address { + vm_address.as_array().into() +} diff --git a/framework/scenario/src/whitebox/raw_converter.rs b/framework/scenario/src/whitebox/raw_converter.rs index ea2c547c07..0dd19681eb 100644 --- a/framework/scenario/src/whitebox/raw_converter.rs +++ b/framework/scenario/src/whitebox/raw_converter.rs @@ -12,7 +12,7 @@ use crate::{ }; use multiversx_chain_vm::{ num_bigint, - world_mock::{AccountData, BlockInfo, EsdtData}, + world_mock::{AccountData, BlockInfo, EsdtData}, types::VMAddress, }; use num_traits::Zero; @@ -50,7 +50,7 @@ pub(crate) fn account_as_raw(acc: &AccountData) -> AccountRaw { comment: None, esdt: all_esdt_raw, nonce: Some(u64_as_raw(acc.nonce)), - owner: acc.contract_owner.as_ref().map(address_as_raw), + owner: acc.contract_owner.as_ref().map(vm_address_as_raw), storage: storage_raw, username: None, // TODO: Add if needed developer_rewards: developer_rewards_raw, @@ -75,7 +75,7 @@ pub(crate) fn esdt_data_as_raw(esdt: &EsdtData) -> EsdtRaw { let inst_raw = EsdtInstanceRaw { attributes: Some(bytes_as_raw(&inst.metadata.attributes)), balance: Some(rust_biguint_as_raw(&inst.balance)), - creator: inst.metadata.creator.as_ref().map(address_as_raw), + creator: inst.metadata.creator.as_ref().map(vm_address_as_raw), hash: inst.metadata.hash.as_ref().map(|h| bytes_as_raw(h)), nonce: Some(u64_as_raw(inst.nonce)), royalties: Some(u64_as_raw(inst.metadata.royalties)), @@ -301,6 +301,10 @@ pub(crate) fn address_as_raw(address: &Address) -> ValueSubTree { bytes_as_raw(address.as_bytes()) } +pub(crate) fn vm_address_as_raw(address: &VMAddress) -> ValueSubTree { + bytes_as_raw(address.as_bytes()) +} + pub(crate) fn u64_as_raw(value: u64) -> ValueSubTree { ValueSubTree::Str(value.to_string()) } diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 775de7da4b..c3dda8bab9 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -27,6 +27,7 @@ rand_seeder = "0.2.2" ed25519-dalek = "1.0.1" itertools = "0.10.3" bech32 = "0.9" +bitflags = "1.3.2" [dependencies.multiversx-sc] version = "=0.41.0" diff --git a/vm/src/display_util.rs b/vm/src/display_util.rs index 5e92ba21e2..e8e6b8ae1e 100644 --- a/vm/src/display_util.rs +++ b/vm/src/display_util.rs @@ -1,11 +1,8 @@ -use crate::{num_bigint, num_bigint::BigInt}; +use crate::{num_bigint, num_bigint::BigInt, types::VMAddress}; use alloc::string::String; use multiversx_sc::{ api::ManagedTypeApi, - types::{ - heap::{Address, BoxedBytes}, - BigUint, ManagedType, - }, + types::{heap::BoxedBytes, BigUint, ManagedType}, }; use std::fmt; @@ -13,7 +10,7 @@ pub struct BigUintPrinter { pub value: BigUint, } -pub fn address_hex(address: &Address) -> String { +pub fn address_hex(address: &VMAddress) -> String { alloc::format!("0x{}", hex::encode(address.as_bytes())) } diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 697df8a552..69fd6b30a9 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -4,6 +4,7 @@ pub mod display_util; pub mod mem_conv; pub mod tx_execution; pub mod tx_mock; +pub mod types; pub mod vm_hooks; pub mod world_mock; diff --git a/vm/src/tx_execution/builtin_function_mocks/builtin_func_trait.rs b/vm/src/tx_execution/builtin_function_mocks/builtin_func_trait.rs index 7bbf2c1700..2a8e712d54 100644 --- a/vm/src/tx_execution/builtin_function_mocks/builtin_func_trait.rs +++ b/vm/src/tx_execution/builtin_function_mocks/builtin_func_trait.rs @@ -1,6 +1,7 @@ -use multiversx_sc::types::Address; - -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult, TxTokenTransfer}; +use crate::{ + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult, TxTokenTransfer}, + types::VMAddress, +}; pub trait BuiltinFunction { fn name(&self) -> &str; @@ -15,7 +16,7 @@ pub trait BuiltinFunction { /// Contains a builtin function call ESDT transfers (if any) and the real recipient of the transfer /// (can be different from the "to" field.) pub struct BuiltinFunctionEsdtTransferInfo { - pub real_recipient: Address, + pub real_recipient: VMAddress, pub transfers: Vec, } diff --git a/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs index ef6897c914..750c3c52cf 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs @@ -1,6 +1,9 @@ -use multiversx_sc::{api::CHANGE_OWNER_BUILTIN_FUNC_NAME, codec::TopDecode, types::heap::Address}; +use multiversx_sc::api::CHANGE_OWNER_BUILTIN_FUNC_NAME; -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}; +use crate::{ + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, + types::VMAddress, +}; use super::super::builtin_func_trait::BuiltinFunction; @@ -19,7 +22,7 @@ impl BuiltinFunction for ChangeOwner { ); } - let new_owner_address = Address::top_decode(tx_input.args[0].as_slice()).unwrap(); + let new_owner_address = VMAddress::from_slice(&tx_input.args[0]); tx_cache.with_account_mut(&tx_input.to, |account| { account.contract_owner = Some(new_owner_address); }); diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs index 968352386c..8ed1ca2600 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs @@ -1,8 +1,9 @@ -use multiversx_sc::{api::ESDT_MULTI_TRANSFER_FUNC_NAME, codec::TopDecode, types::heap::Address}; +use multiversx_sc::{api::ESDT_MULTI_TRANSFER_FUNC_NAME, codec::TopDecode}; use crate::{ tx_execution::builtin_function_mocks::builtin_func_trait::BuiltinFunctionEsdtTransferInfo, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, + types::VMAddress, }; use super::{ @@ -52,7 +53,7 @@ fn try_parse_input(tx_input: &TxInput) -> Result Result 5 { diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs index 1599c0eeff..dbb822c357 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/transfer_common.rs @@ -6,13 +6,14 @@ use crate::{ tx_mock::{ BlockchainUpdate, TxCache, TxFunctionName, TxInput, TxLog, TxResult, TxTokenTransfer, }, + types::VMAddress, }; -use multiversx_sc::{codec::TopDecode, types::heap::Address}; +use multiversx_sc::codec::TopDecode; use num_bigint::BigUint; use num_traits::Zero; pub(super) struct ParsedTransferBuiltinFunCall { - pub destination: Address, + pub destination: VMAddress, pub raw_esdt_transfers: Vec, pub func_name: TxFunctionName, pub args: Vec>, diff --git a/vm/src/tx_execution/exec_call.rs b/vm/src/tx_execution/exec_call.rs index 65dbc9012b..da326cec62 100644 --- a/vm/src/tx_execution/exec_call.rs +++ b/vm/src/tx_execution/exec_call.rs @@ -1,16 +1,14 @@ -use std::{collections::HashMap, rc::Rc}; - -use multiversx_sc::types::Address; -use num_bigint::BigUint; -use num_traits::Zero; - use crate::{ tx_mock::{ async_call_tx_input, async_callback_tx_input, async_promise_tx_input, merge_results, AsyncCallTxData, Promise, TxCache, TxContext, TxInput, TxResult, TxResultCalls, }, + types::VMAddress, world_mock::{AccountData, AccountEsdt, BlockchainMock}, }; +use num_bigint::BigUint; +use num_traits::Zero; +use std::{collections::HashMap, rc::Rc}; use super::{execute_builtin_function_or_default, execute_tx_context}; @@ -121,7 +119,7 @@ pub fn sc_call_with_async_and_callback( } pub fn execute_promise_call_and_callback( - address: &Address, + address: &VMAddress, promise: &Promise, state: BlockchainMock, ) -> (TxResult, TxResult, BlockchainMock) { diff --git a/vm/src/tx_execution/exec_create.rs b/vm/src/tx_execution/exec_create.rs index 84df96cb3e..f7d062cebf 100644 --- a/vm/src/tx_execution/exec_create.rs +++ b/vm/src/tx_execution/exec_create.rs @@ -1,9 +1,8 @@ use std::rc::Rc; -use multiversx_sc::types::Address; - use crate::{ tx_mock::{TxCache, TxInput, TxResult}, + types::VMAddress, world_mock::BlockchainMock, }; @@ -13,7 +12,7 @@ pub fn sc_create( tx_input: TxInput, contract_path: &[u8], mut state: BlockchainMock, -) -> (TxResult, Address, BlockchainMock) { +) -> (TxResult, VMAddress, BlockchainMock) { // nonce gets increased irrespective of whether the tx fails or not // must be done after computing the new address state.increase_account_nonce(&tx_input.from); diff --git a/vm/src/tx_execution/exec_general_tx.rs b/vm/src/tx_execution/exec_general_tx.rs index 0370ef98db..44d7bf5d03 100644 --- a/vm/src/tx_execution/exec_general_tx.rs +++ b/vm/src/tx_execution/exec_general_tx.rs @@ -1,8 +1,8 @@ -use multiversx_sc::types::heap::Address; use num_traits::Zero; -use crate::tx_mock::{ - BlockchainUpdate, TxCache, TxContext, TxFunctionName, TxInput, TxLog, TxResult, +use crate::{ + tx_mock::{BlockchainUpdate, TxCache, TxContext, TxFunctionName, TxInput, TxLog, TxResult}, + types::VMAddress, }; use super::execute_tx_context; @@ -27,7 +27,7 @@ pub fn default_execution(tx_input: TxInput, tx_cache: TxCache) -> (TxResult, Blo && !tx_context.tx_input_box.egld_value.is_zero(); let transfer_value_log = if add_transfer_log { Some(TxLog { - address: Address::zero(), // TODO: figure out the real VM behavior + address: VMAddress::zero(), // TODO: figure out the real VM behavior endpoint: "transferValueOnly".into(), topics: vec![ tx_context.tx_input_box.from.to_vec(), @@ -78,7 +78,7 @@ pub fn deploy_contract( mut tx_input: TxInput, contract_path: Vec, tx_cache: TxCache, -) -> (TxResult, Address, BlockchainUpdate) { +) -> (TxResult, VMAddress, BlockchainUpdate) { let new_address = tx_cache.get_new_address(&tx_input.from); tx_input.to = new_address.clone(); tx_input.func_name = TxFunctionName::INIT; @@ -91,7 +91,7 @@ pub fn deploy_contract( { return ( TxResult::from_panic_obj(&err), - Address::zero(), + VMAddress::zero(), BlockchainUpdate::empty(), ); } diff --git a/vm/src/tx_mock/tx_async_call_data.rs b/vm/src/tx_mock/tx_async_call_data.rs index ccc9b81f6f..07471c66d2 100644 --- a/vm/src/tx_mock/tx_async_call_data.rs +++ b/vm/src/tx_mock/tx_async_call_data.rs @@ -1,11 +1,9 @@ use crate::{ tx_execution::BuiltinFunctionMap, tx_mock::{TxInput, TxResult}, + types::{VMAddress, H256}, }; -use multiversx_sc::{ - codec::*, - types::heap::{Address, H256}, -}; +use multiversx_sc::codec::*; use crate::num_bigint::BigUint; @@ -13,8 +11,8 @@ use super::{CallbackPayments, Promise, TxFunctionName}; #[derive(Debug, Clone)] pub struct AsyncCallTxData { - pub from: Address, - pub to: Address, + pub from: VMAddress, + pub to: VMAddress, pub call_value: BigUint, pub endpoint_name: TxFunctionName, pub arguments: Vec>, @@ -73,7 +71,7 @@ pub fn async_callback_tx_input( } fn extract_callback_payments( - callback_contract_address: &Address, + callback_contract_address: &VMAddress, async_result: &TxResult, builtin_functions: &BuiltinFunctionMap, ) -> CallbackPayments { @@ -94,7 +92,7 @@ fn extract_callback_payments( } pub fn async_promise_tx_input( - address: &Address, + address: &VMAddress, promise: &Promise, async_result: &TxResult, ) -> TxInput { diff --git a/vm/src/tx_mock/tx_cache.rs b/vm/src/tx_mock/tx_cache.rs index 5fa7c5f1f1..f32aa7677f 100644 --- a/vm/src/tx_mock/tx_cache.rs +++ b/vm/src/tx_mock/tx_cache.rs @@ -5,10 +5,9 @@ use std::{ rc::Rc, }; -use multiversx_sc::types::heap::Address; - use crate::{ display_util::address_hex, + types::VMAddress, world_mock::{AccountData, BlockchainMock}, }; @@ -16,7 +15,7 @@ use super::TxCacheSource; pub struct TxCache { source_ref: Rc, - pub(super) accounts: RefCell>, + pub(super) accounts: RefCell>, } impl fmt::Debug for TxCache { @@ -39,7 +38,7 @@ impl TxCache { self.source_ref.blockchain_ref() } - fn load_account_if_necessary(&self, address: &Address) { + fn load_account_if_necessary(&self, address: &VMAddress) { let mut accounts_mut = self.accounts.borrow_mut(); if !accounts_mut.contains_key(address) { if let Some(blockchain_account) = self.source_ref.load_account(address) { @@ -48,7 +47,7 @@ impl TxCache { } } - pub fn with_account(&self, address: &Address, f: F) -> R + pub fn with_account(&self, address: &VMAddress, f: F) -> R where F: FnOnce(&AccountData) -> R, { @@ -60,7 +59,7 @@ impl TxCache { f(account) } - pub fn with_account_mut(&self, address: &Address, f: F) -> R + pub fn with_account_mut(&self, address: &VMAddress, f: F) -> R where F: FnOnce(&mut AccountData) -> R, { @@ -78,18 +77,18 @@ impl TxCache { .insert(account_data.address.clone(), account_data); } - pub fn increase_acount_nonce(&self, address: &Address) { + pub fn increase_acount_nonce(&self, address: &VMAddress) { self.with_account_mut(address, |account| { account.nonce += 1; }); } - pub fn get_all_accounts(&self) -> Ref> { + pub fn get_all_accounts(&self) -> Ref> { self.accounts.borrow() } /// Assumes the nonce has already been increased. - pub fn get_new_address(&self, creator_address: &Address) -> Address { + pub fn get_new_address(&self, creator_address: &VMAddress) -> VMAddress { let current_nonce = self.with_account(creator_address, |account| account.nonce); self.blockchain_ref() .get_new_address(creator_address.clone(), current_nonce - 1) @@ -112,7 +111,7 @@ impl TxCache { } pub struct BlockchainUpdate { - accounts: HashMap, + accounts: HashMap, } impl BlockchainUpdate { diff --git a/vm/src/tx_mock/tx_cache_balance_util.rs b/vm/src/tx_mock/tx_cache_balance_util.rs index 1f564e9886..5ac5ab603e 100644 --- a/vm/src/tx_mock/tx_cache_balance_util.rs +++ b/vm/src/tx_mock/tx_cache_balance_util.rs @@ -1,14 +1,13 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::types::heap::Address; - -use crate::{tx_mock::TxPanic, world_mock::EsdtInstanceMetadata}; +use crate::{ + num_bigint::BigUint, tx_mock::TxPanic, types::VMAddress, world_mock::EsdtInstanceMetadata, +}; use super::TxCache; impl TxCache { pub fn subtract_egld_balance( &self, - address: &Address, + address: &VMAddress, call_value: &BigUint, ) -> Result<(), TxPanic> { self.with_account_mut(address, |account| { @@ -20,7 +19,7 @@ impl TxCache { }) } - pub fn subtract_tx_gas(&self, address: &Address, gas_limit: u64, gas_price: u64) { + pub fn subtract_tx_gas(&self, address: &VMAddress, gas_limit: u64, gas_price: u64) { self.with_account_mut(address, |account| { let gas_cost = BigUint::from(gas_limit) * BigUint::from(gas_price); assert!( @@ -31,7 +30,7 @@ impl TxCache { }); } - pub fn increase_egld_balance(&self, address: &Address, amount: &BigUint) { + pub fn increase_egld_balance(&self, address: &VMAddress, amount: &BigUint) { self.with_account_mut(address, |account| { account.egld_balance += amount; }); @@ -39,7 +38,7 @@ impl TxCache { pub fn subtract_esdt_balance( &self, - address: &Address, + address: &VMAddress, esdt_token_identifier: &[u8], nonce: u64, value: &BigUint, @@ -68,7 +67,7 @@ impl TxCache { pub fn increase_esdt_balance( &self, - address: &Address, + address: &VMAddress, esdt_token_identifier: &[u8], nonce: u64, value: &BigUint, @@ -86,8 +85,8 @@ impl TxCache { pub fn transfer_esdt_balance( &self, - from: &Address, - to: &Address, + from: &VMAddress, + to: &VMAddress, esdt_token_identifier: &[u8], nonce: u64, value: &BigUint, diff --git a/vm/src/tx_mock/tx_cache_source.rs b/vm/src/tx_mock/tx_cache_source.rs index 3208b75059..5a6df3c515 100644 --- a/vm/src/tx_mock/tx_cache_source.rs +++ b/vm/src/tx_mock/tx_cache_source.rs @@ -1,17 +1,18 @@ -use multiversx_sc::types::heap::Address; - -use crate::world_mock::{AccountData, BlockchainMock}; +use crate::{ + types::VMAddress, + world_mock::{AccountData, BlockchainMock}, +}; use super::TxCache; pub trait TxCacheSource { - fn load_account(&self, address: &Address) -> Option; + fn load_account(&self, address: &VMAddress) -> Option; fn blockchain_ref(&self) -> &BlockchainMock; } impl TxCacheSource for TxCache { - fn load_account(&self, address: &Address) -> Option { + fn load_account(&self, address: &VMAddress) -> Option { Some(self.with_account(address, AccountData::clone)) } @@ -21,7 +22,7 @@ impl TxCacheSource for TxCache { } impl TxCacheSource for BlockchainMock { - fn load_account(&self, address: &Address) -> Option { + fn load_account(&self, address: &VMAddress) -> Option { self.accounts.get(address).map(AccountData::clone) } diff --git a/vm/src/tx_mock/tx_context.rs b/vm/src/tx_mock/tx_context.rs index 8b1e9b512b..19edc2043a 100644 --- a/vm/src/tx_mock/tx_context.rs +++ b/vm/src/tx_mock/tx_context.rs @@ -1,9 +1,9 @@ use crate::{ num_bigint::BigUint, + types::VMAddress, world_mock::{AccountData, AccountEsdt, BlockchainMock, FailingExecutor}, }; use core::cell::RefCell; -use multiversx_sc::types::heap::Address; use num_traits::Zero; use std::{ cell::{Ref, RefMut}, @@ -36,7 +36,7 @@ impl TxContext { pub fn dummy() -> Self { let tx_cache = TxCache::new(Rc::new(BlockchainMock::new(Box::new(FailingExecutor)))); - let contract_address = Address::from(&[b'c'; 32]); + let contract_address = VMAddress::from([b'c'; 32]); tx_cache.insert_account(AccountData { address: contract_address.clone(), nonce: 0, @@ -82,7 +82,7 @@ impl TxContext { self.tx_cache.blockchain_ref() } - pub fn with_account(&self, address: &Address, f: F) -> R + pub fn with_account(&self, address: &VMAddress, f: F) -> R where F: FnOnce(&AccountData) -> R, { @@ -96,7 +96,7 @@ impl TxContext { self.with_account(&self.tx_input_box.to, f) } - pub fn with_account_mut(&self, address: &Address, f: F) -> R + pub fn with_account_mut(&self, address: &VMAddress, f: F) -> R where F: FnOnce(&mut AccountData) -> R, { @@ -132,9 +132,9 @@ impl TxContext { pub fn create_new_contract( &self, - new_address: &Address, + new_address: &VMAddress, contract_path: Vec, - contract_owner: Address, + contract_owner: VMAddress, ) { assert!( !self.tx_cache.blockchain_ref().account_exists(new_address), diff --git a/vm/src/tx_mock/tx_input.rs b/vm/src/tx_mock/tx_input.rs index a9ce6765d0..ebc92a164b 100644 --- a/vm/src/tx_mock/tx_input.rs +++ b/vm/src/tx_mock/tx_input.rs @@ -1,5 +1,8 @@ -use crate::{display_util::*, num_bigint::BigUint}; -use multiversx_sc::types::heap::{Address, H256}; +use crate::{ + display_util::*, + num_bigint::BigUint, + types::{VMAddress, H256}, +}; use num_traits::Zero; use std::fmt; @@ -7,8 +10,8 @@ use super::TxFunctionName; #[derive(Clone, Debug)] pub struct TxInput { - pub from: Address, - pub to: Address, + pub from: VMAddress, + pub to: VMAddress, pub egld_value: BigUint, pub esdt_values: Vec, pub func_name: TxFunctionName, @@ -23,8 +26,8 @@ pub struct TxInput { impl Default for TxInput { fn default() -> Self { TxInput { - from: Address::zero(), - to: Address::zero(), + from: VMAddress::zero(), + to: VMAddress::zero(), egld_value: BigUint::zero(), esdt_values: Vec::new(), func_name: TxFunctionName::EMPTY, diff --git a/vm/src/tx_mock/tx_input_util.rs b/vm/src/tx_mock/tx_input_util.rs index 795ab9eafc..463c96b8ac 100644 --- a/vm/src/tx_mock/tx_input_util.rs +++ b/vm/src/tx_mock/tx_input_util.rs @@ -1,4 +1,4 @@ -use multiversx_sc::types::heap::H256; +use crate::types::H256; pub fn generate_tx_hash_dummy(tx_id: &str) -> H256 { let bytes = tx_id.as_bytes(); diff --git a/vm/src/tx_mock/tx_log.rs b/vm/src/tx_mock/tx_log.rs index 15828754fe..d2a0a696da 100644 --- a/vm/src/tx_mock/tx_log.rs +++ b/vm/src/tx_mock/tx_log.rs @@ -1,10 +1,10 @@ -use multiversx_sc::types::heap::Address; +use crate::types::VMAddress; use super::TxFunctionName; #[derive(Clone, Debug)] pub struct TxLog { - pub address: Address, + pub address: VMAddress, pub endpoint: TxFunctionName, pub topics: Vec>, pub data: Vec, diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index 552852a911..462ddeecd3 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -1,9 +1,12 @@ use multiversx_sc::{ api::{handle_to_be_bytes, InvalidSliceError, RawHandle}, - types::{Address, BoxedBytes, CodeMetadata}, + types::BoxedBytes, }; -use crate::tx_mock::{TxFunctionName, TxTokenTransfer}; +use crate::{ + tx_mock::{TxFunctionName, TxTokenTransfer}, + types::{CodeMetadata, VMAddress}, +}; use super::TxManagedTypes; @@ -21,8 +24,8 @@ impl TxManagedTypes { data.into() } - pub fn mb_to_address(&self, handle: RawHandle) -> Address { - Address::from_slice(self.mb_get(handle)) + pub fn mb_to_address(&self, handle: RawHandle) -> VMAddress { + VMAddress::from_slice(self.mb_get(handle)) } pub fn mb_to_function_name(&self, handle: RawHandle) -> TxFunctionName { diff --git a/vm/src/types.rs b/vm/src/types.rs new file mode 100644 index 0000000000..231c0d7c6f --- /dev/null +++ b/vm/src/types.rs @@ -0,0 +1,7 @@ +mod vm_address; +mod vm_code_metadata; +mod vm_h256; + +pub use vm_address::VMAddress; +pub use vm_code_metadata::CodeMetadata; +pub use vm_h256::H256; diff --git a/vm/src/types/vm_address.rs b/vm/src/types/vm_address.rs new file mode 100644 index 0000000000..b555393ef8 --- /dev/null +++ b/vm/src/types/vm_address.rs @@ -0,0 +1,140 @@ +use super::H256; + +use core::fmt::Debug; + +const SC_ADDRESS_NUM_LEADING_ZEROS: u8 = 8; + +/// An Address is just a H256 with a different name. +/// Has a different ABI name than H256. +/// +/// Note: we are currently using ManagedAddress in contracts. +/// While this also works, its use in contracts is discouraged. +#[derive(Hash, PartialEq, Eq, Clone, Debug)] +pub struct VMAddress(H256); + +impl From for VMAddress { + fn from(hash: H256) -> Self { + VMAddress(hash) + } +} + +impl From for H256 { + fn from(address: VMAddress) -> Self { + address.0 + } +} + +impl<'a> From<&'a VMAddress> for &'a H256 { + fn from(address: &'a VMAddress) -> Self { + &address.0 + } +} + +impl From<[u8; 32]> for VMAddress { + fn from(arr: [u8; 32]) -> Self { + VMAddress(H256::from(arr)) + } +} + +impl From<&[u8; 32]> for VMAddress { + fn from(bytes: &[u8; 32]) -> Self { + VMAddress(H256::from(bytes)) + } +} + +impl From<&mut [u8; 32]> for VMAddress { + fn from(bytes: &mut [u8; 32]) -> Self { + VMAddress(H256::from(bytes)) + } +} + +impl From> for VMAddress { + fn from(bytes: Box<[u8; 32]>) -> Self { + VMAddress(H256::from(bytes)) + } +} + +impl VMAddress { + pub fn from_slice(slice: &[u8]) -> Self { + VMAddress(H256::from_slice(slice)) + } +} + +impl From for [u8; 32] { + fn from(addr: VMAddress) -> Self { + addr.0.into() + } +} + +impl AsRef<[u8]> for VMAddress { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl AsMut<[u8]> for VMAddress { + fn as_mut(&mut self) -> &mut [u8] { + self.0.as_mut() + } +} + +impl VMAddress { + /// Returns a new address of 32 zeros. + /// Allocates directly in heap. + /// Minimal resulting wasm code (14 bytes if not inlined). + pub fn zero() -> Self { + VMAddress(H256::zero()) + } + + /// Returns the size of an address in bytes. + pub fn len_bytes() -> usize { + H256::len_bytes() + } + + /// Extracts a byte slice containing the entire fixed hash. + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } + + pub fn as_array(&self) -> &[u8; 32] { + self.0.as_array() + } + + pub fn copy_to_array(&self, target: &mut [u8; 32]) { + self.0.copy_to_array(target) + } + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + /// Pointer to the data on the heap. + pub fn as_ptr(&self) -> *const u8 { + self.0.as_ptr() + } + + /// Returns an unsafe mutable pointer to the data on the heap. + /// Used by the API to populate data. + pub fn as_mut_ptr(&mut self) -> *mut u8 { + self.0.as_mut_ptr() + } + + /// True if all 32 bytes of the hash are zero. + pub fn is_zero(&self) -> bool { + self.0.is_zero() + } + + // /// Transmutes self to an (in principle) variable length boxed bytes object. + // /// Both BoxedBytes and H256 keep the data on the heap, so only the pointer to that data needs to be transmuted. + // /// Does not reallocate or copy data, the data on the heap remains untouched. + // pub fn into_boxed_bytes(self) -> BoxedBytes { + // self.0.into_boxed_bytes() + // } + + pub fn is_smart_contract_address(&self) -> bool { + self.as_bytes() + .iter() + .take(SC_ADDRESS_NUM_LEADING_ZEROS.into()) + .all(|item| item == &0u8) + } +} diff --git a/vm/src/types/vm_code_metadata.rs b/vm/src/types/vm_code_metadata.rs new file mode 100644 index 0000000000..d0bd4b6c5b --- /dev/null +++ b/vm/src/types/vm_code_metadata.rs @@ -0,0 +1,122 @@ +use bitflags::bitflags; + +// const UPGRADEABLE_STRING: &[u8] = b"Upgradeable"; +// const READABLE_STRING: &[u8] = b"Readable"; +// const PAYABLE_STRING: &[u8] = b"Payable"; +// const PAYABLE_BY_SC_STRING: &[u8] = b"PayableBySC"; +// const DEFAULT_STRING: &[u8] = b"Default"; + +bitflags! { + #[derive(Default)] + pub struct CodeMetadata: u16 { + const DEFAULT = 0; + const UPGRADEABLE = 0b0000_0001_0000_0000; // LSB of first byte + const READABLE = 0b0000_0100_0000_0000; // 3rd LSB of first byte + const PAYABLE = 0b0000_0000_0000_0010; // 2nd LSB of second byte + const PAYABLE_BY_SC = 0b0000_0000_0000_0100; // 3rd LSB of second byte + } +} + +impl CodeMetadata { + pub fn is_upgradeable(&self) -> bool { + *self & CodeMetadata::UPGRADEABLE != CodeMetadata::DEFAULT + } + + pub fn is_payable(&self) -> bool { + *self & CodeMetadata::PAYABLE != CodeMetadata::DEFAULT + } + + pub fn is_payable_by_sc(&self) -> bool { + *self & CodeMetadata::PAYABLE_BY_SC != CodeMetadata::DEFAULT + } + + pub fn is_readable(&self) -> bool { + *self & CodeMetadata::READABLE != CodeMetadata::DEFAULT + } + + pub fn to_byte_array(&self) -> [u8; 2] { + self.bits().to_be_bytes() + } + + pub fn to_vec(&self) -> Vec { + self.to_byte_array().to_vec() + } +} + +impl From<[u8; 2]> for CodeMetadata { + #[inline] + fn from(arr: [u8; 2]) -> Self { + CodeMetadata::from(u16::from_be_bytes(arr)) + } +} + +impl From for CodeMetadata { + #[inline] + fn from(value: u16) -> Self { + CodeMetadata::from_bits_truncate(value) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_default() { + assert!(!CodeMetadata::DEFAULT.is_upgradeable()); + assert!(!CodeMetadata::DEFAULT.is_payable()); + assert!(!CodeMetadata::DEFAULT.is_readable()); + } + + #[test] + fn test_all() { + let all = CodeMetadata::UPGRADEABLE + | CodeMetadata::PAYABLE + | CodeMetadata::PAYABLE_BY_SC + | CodeMetadata::READABLE; + assert!(all.is_upgradeable()); + assert!(all.is_payable()); + assert!(all.is_payable_by_sc()); + assert!(all.is_readable()); + + assert_eq!(all.bits(), 0x0506); + + assert_eq!(CodeMetadata::from_bits_truncate(0xffff), all); + } + + #[test] + fn test_each() { + assert!(CodeMetadata::UPGRADEABLE.is_upgradeable()); + assert!(!CodeMetadata::PAYABLE.is_upgradeable()); + assert!(!CodeMetadata::PAYABLE_BY_SC.is_upgradeable()); + assert!(!CodeMetadata::READABLE.is_upgradeable()); + + assert!(!CodeMetadata::UPGRADEABLE.is_payable()); + assert!(CodeMetadata::PAYABLE.is_payable()); + assert!(!CodeMetadata::PAYABLE_BY_SC.is_payable()); + assert!(!CodeMetadata::READABLE.is_payable()); + + assert!(!CodeMetadata::UPGRADEABLE.is_payable_by_sc()); + assert!(!CodeMetadata::PAYABLE.is_payable_by_sc()); + assert!(CodeMetadata::PAYABLE_BY_SC.is_payable_by_sc()); + assert!(!CodeMetadata::READABLE.is_payable_by_sc()); + + assert!(!CodeMetadata::UPGRADEABLE.is_readable()); + assert!(!CodeMetadata::PAYABLE.is_readable()); + assert!(!CodeMetadata::PAYABLE_BY_SC.is_readable()); + assert!(CodeMetadata::READABLE.is_readable()); + } + + /// Translated from vm-wasm. + #[test] + fn test_from_array() { + assert!(CodeMetadata::from([1, 0]).is_upgradeable()); + assert!(!CodeMetadata::from([1, 0]).is_readable()); + assert!(CodeMetadata::from([0, 2]).is_payable()); + assert!(CodeMetadata::from([4, 0]).is_readable()); + assert!(!CodeMetadata::from([4, 0]).is_upgradeable()); + assert!(!CodeMetadata::from([0, 0]).is_upgradeable()); + assert!(!CodeMetadata::from([0, 0]).is_payable()); + assert!(!CodeMetadata::from([0, 0]).is_readable()); + } +} diff --git a/vm/src/types/vm_h256.rs b/vm/src/types/vm_h256.rs new file mode 100644 index 0000000000..ded66956e5 --- /dev/null +++ b/vm/src/types/vm_h256.rs @@ -0,0 +1,153 @@ +use core::fmt::Debug; + +// const ERR_BAD_H256_LENGTH: &str = "bad H256 length"; +const ZERO_32: &[u8] = &[0u8; 32]; + +/// Type that holds 32 bytes of data. +/// Data is kept on the heap to keep wasm size low and avoid copies. +#[derive(Hash, PartialEq, Eq, Clone, Debug)] +pub struct H256(Box<[u8; 32]>); + +impl From<[u8; 32]> for H256 { + /// Constructs a hash type from the given bytes array of fixed length. + /// + /// # Note + /// + /// The given bytes are interpreted in big endian order. + #[inline] + fn from(arr: [u8; 32]) -> Self { + H256(Box::new(arr)) + } +} + +impl<'a> From<&'a [u8; 32]> for H256 { + /// Constructs a hash type from the given reference + /// to the bytes array of fixed length. + /// + /// # Note + /// + /// The given bytes are interpreted in big endian order. + #[inline] + fn from(bytes: &'a [u8; 32]) -> Self { + H256(Box::new(*bytes)) + } +} + +impl<'a> From<&'a mut [u8; 32]> for H256 { + /// Constructs a hash type from the given reference + /// to the mutable bytes array of fixed length. + /// + /// # Note + /// + /// The given bytes are interpreted in big endian order. + #[inline] + fn from(bytes: &'a mut [u8; 32]) -> Self { + H256(Box::new(*bytes)) + } +} + +impl From> for H256 { + #[inline] + fn from(bytes: Box<[u8; 32]>) -> Self { + H256(bytes) + } +} + +impl H256 { + pub fn from_slice(slice: &[u8]) -> Self { + let mut arr = [0u8; 32]; + let len = core::cmp::min(slice.len(), 32); + arr[..len].copy_from_slice(&slice[..len]); + H256(Box::new(arr)) + } +} + +impl From for [u8; 32] { + #[inline] + fn from(s: H256) -> Self { + *(s.0) + } +} + +impl AsRef<[u8]> for H256 { + #[inline] + fn as_ref(&self) -> &[u8] { + self.as_bytes() + } +} + +impl AsMut<[u8]> for H256 { + #[inline] + fn as_mut(&mut self) -> &mut [u8] { + self.0.as_mut() + } +} + +impl H256 { + /// Returns a new zero-initialized fixed hash. + /// Allocates directly in heap. + /// Minimal resulting wasm code (14 bytes if not inlined). + pub fn zero() -> Self { + use alloc::alloc::{alloc_zeroed, Layout}; + unsafe { + let ptr = alloc_zeroed(Layout::new::<[u8; 32]>()) as *mut [u8; 32]; + H256(Box::from_raw(ptr)) + } + } + + /// Returns the size of this hash in bytes. + #[inline] + pub fn len_bytes() -> usize { + 32 + } + + /// Extracts a byte slice containing the entire fixed hash. + #[inline] + pub fn as_bytes(&self) -> &[u8] { + self.0.as_ref() + } + + #[inline] + pub fn as_array(&self) -> &[u8; 32] { + self.0.as_ref() + } + + #[inline] + pub fn copy_to_array(&self, target: &mut [u8; 32]) { + target.copy_from_slice(&self.0[..]); + } + + #[inline] + pub fn to_vec(&self) -> Vec { + self.0[..].to_vec() + } + + /// Pointer to the data on the heap. + #[inline] + pub fn as_ptr(&self) -> *const u8 { + self.0.as_ptr() + } + + /// Returns an unsafe mutable pointer to the data on the heap. + /// Used by the API to populate data. + #[inline] + pub fn as_mut_ptr(&mut self) -> *mut u8 { + self.0.as_mut_ptr() + } + + /// True if all 32 bytes of the hash are zero. + pub fn is_zero(&self) -> bool { + self.as_bytes() == ZERO_32 + } + + // /// Transmutes self to an (in principle) variable length boxed bytes object. + // /// Both BoxedBytes and H256 keep the data on the heap, so only the pointer to that data needs to be transmuted. + // /// Does not reallocate or copy data, the data on the heap remains untouched. + // pub fn into_boxed_bytes(self) -> BoxedBytes { + // let raw = Box::into_raw(self.0) as *mut u8; + // unsafe { + // let bytes_box = Box::<[u8]>::from_raw(core::slice::from_raw_parts_mut(raw, 32)); + // bytes_box.into() + // } + // } +} diff --git a/vm/src/vm_hooks/vh_debugger_stack.rs b/vm/src/vm_hooks/vh_debugger_stack.rs index 4092d44e92..4ac37afaa9 100644 --- a/vm/src/vm_hooks/vh_debugger_stack.rs +++ b/vm/src/vm_hooks/vh_debugger_stack.rs @@ -4,10 +4,7 @@ use std::{ }; use multiversx_chain_vm_executor::BreakpointValue; -use multiversx_sc::{ - err_msg, - types::{Address, CodeMetadata}, -}; +use multiversx_sc::err_msg; use crate::{ tx_execution::{deploy_contract, execute_builtin_function_or_default}, @@ -15,6 +12,7 @@ use crate::{ async_call_tx_input, AsyncCallTxData, BlockchainUpdate, TxCache, TxContext, TxFunctionName, TxInput, TxManagedTypes, TxPanic, TxResult, }, + types::{CodeMetadata, VMAddress}, world_mock::{AccountData, BlockInfo, STORAGE_RESERVED_PREFIX}, }; @@ -67,7 +65,7 @@ impl VMHooksHandlerSource for TxContextWrapper { self.0.result_borrow_mut() } - fn storage_read_any_address(&self, address: &Address, key: &[u8]) -> Vec { + fn storage_read_any_address(&self, address: &VMAddress, key: &[u8]) -> Vec { self.0.with_account_mut(address, |account| { account.storage.get(key).cloned().unwrap_or_default() }) @@ -89,11 +87,11 @@ impl VMHooksHandlerSource for TxContextWrapper { &self.0.blockchain_ref().current_block_info } - fn account_data(&self, address: &Address) -> AccountData { + fn account_data(&self, address: &VMAddress) -> AccountData { self.0.with_account(address, |account| account.clone()) } - fn account_code(&self, address: &Address) -> Vec { + fn account_code(&self, address: &VMAddress) -> Vec { self.0 .blockchain_cache() .with_account(address, |account| account.contract_path.clone()) @@ -102,7 +100,7 @@ impl VMHooksHandlerSource for TxContextWrapper { fn perform_async_call( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, arguments: Vec>, @@ -117,7 +115,7 @@ impl VMHooksHandlerSource for TxContextWrapper { fn perform_execute_on_dest_context( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, arguments: Vec>, @@ -143,12 +141,12 @@ impl VMHooksHandlerSource for TxContextWrapper { contract_code: Vec, _code_metadata: CodeMetadata, args: Vec>, - ) -> (Address, Vec>) { + ) -> (VMAddress, Vec>) { let contract_address = &self.input_ref().to; let tx_hash = self.tx_hash(); let tx_input = TxInput { from: contract_address.clone(), - to: Address::zero(), + to: VMAddress::zero(), egld_value, esdt_values: Vec::new(), func_name: TxFunctionName::EMPTY, @@ -176,7 +174,7 @@ impl VMHooksHandlerSource for TxContextWrapper { fn perform_transfer_execute( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, arguments: Vec>, @@ -202,7 +200,7 @@ impl VMHooksHandlerSource for TxContextWrapper { impl TxContextWrapper { fn create_async_call_data( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, arguments: Vec>, diff --git a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs index a3e7857e75..c1837a3eaa 100644 --- a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs +++ b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs @@ -1,11 +1,12 @@ use crate::{ num_bigint, + types::VMAddress, vm_hooks::VMHooksHandlerSource, world_mock::{EsdtData, EsdtInstance}, }; use multiversx_sc::{ api::RawHandle, - types::{heap::Address, EsdtLocalRole, EsdtLocalRoleFlags}, + types::{EsdtLocalRole, EsdtLocalRoleFlags}, }; use num_bigint::BigInt; use num_traits::Zero; @@ -15,7 +16,7 @@ const ESDT_TOKEN_DATA_FUNC_RESETS_VALUES: bool = false; pub trait VMHooksBlockchain: VMHooksHandlerSource { fn is_contract_address(&self, address_bytes: &[u8]) -> bool { - let address = Address::from_slice(address_bytes); + let address = VMAddress::from_slice(address_bytes); address == self.input_ref().to } @@ -40,7 +41,7 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { } fn is_smart_contract(&self, address_bytes: &[u8]) -> bool { - Address::from_slice(address_bytes).is_smart_contract_address() + VMAddress::from_slice(address_bytes).is_smart_contract_address() } fn load_balance(&self, address_bytes: &[u8], dest: RawHandle) { @@ -154,7 +155,7 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { royalties_handle: RawHandle, uris_handle: RawHandle, ) { - let address = Address::from_slice(self.m_types_borrow().mb_get(address_handle)); + let address = VMAddress::from_slice(self.m_types_borrow().mb_get(address_handle)); let token_id_bytes = self.m_types_borrow().mb_get(token_id_handle).to_vec(); let account = self.account_data(&address); @@ -206,7 +207,7 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource { token_id_handle: RawHandle, _nonce: u64, ) -> bool { - let address = Address::from_slice(self.m_types_borrow().mb_get(address_handle)); + let address = VMAddress::from_slice(self.m_types_borrow().mb_get(address_handle)); let token_id_bytes = self.m_types_borrow().mb_get(token_id_handle).to_vec(); let account = self.account_data(&address); if let Some(esdt_data) = account.esdt.get_by_identifier(token_id_bytes.as_slice()) { diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index 2aebdc7b8f..456242fcaf 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -1,6 +1,7 @@ use crate::{ num_bigint, tx_mock::{AsyncCallTxData, Promise, TxFunctionName, TxTokenTransfer}, + types::{CodeMetadata, VMAddress}, vm_hooks::VMHooksHandlerSource, }; use multiversx_sc::{ @@ -9,7 +10,6 @@ use multiversx_sc::{ ESDT_TRANSFER_FUNC_NAME, UPGRADE_CONTRACT_FUNC_NAME, }, codec::top_encode_to_vec_u8, - types::{heap::Address, CodeMetadata}, }; use num_traits::Zero; @@ -27,7 +27,7 @@ fn append_endpoint_name_and_args( pub trait VMHooksSend: VMHooksHandlerSource { fn perform_transfer_execute_esdt( &self, - to: Address, + to: VMAddress, token: Vec, amount: num_bigint::BigUint, _gas_limit: u64, @@ -48,7 +48,7 @@ pub trait VMHooksSend: VMHooksHandlerSource { #[allow(clippy::too_many_arguments)] fn perform_transfer_execute_nft( &self, - to: Address, + to: VMAddress, token: Vec, nonce: u64, amount: num_bigint::BigUint, @@ -77,7 +77,7 @@ pub trait VMHooksSend: VMHooksHandlerSource { fn perform_transfer_execute_multi( &self, - to: Address, + to: VMAddress, payments: Vec, _gas_limit: u64, endpoint_name: TxFunctionName, @@ -108,13 +108,13 @@ pub trait VMHooksSend: VMHooksHandlerSource { fn perform_upgrade_contract( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, contract_code: Vec, code_metadata: CodeMetadata, args: Vec>, ) -> ! { - let mut arguments = vec![contract_code, top_encode_to_vec_u8(&code_metadata).unwrap()]; + let mut arguments = vec![contract_code, code_metadata.to_vec()]; arguments.extend(args.into_iter()); self.perform_async_call(to, egld_value, UPGRADE_CONTRACT_FUNC_NAME.into(), arguments) } diff --git a/vm/src/vm_hooks/vh_handler/vh_storage.rs b/vm/src/vm_hooks/vh_handler/vh_storage.rs index 59ab48b165..8d74b76fc9 100644 --- a/vm/src/vm_hooks/vh_handler/vh_storage.rs +++ b/vm/src/vm_hooks/vh_handler/vh_storage.rs @@ -3,14 +3,12 @@ use crate::{ num_bigint::{BigInt, Sign}, tx_mock::{TxContextRef, TxPanic}, + types::VMAddress, vm_hooks::VMHooksHandlerSource, }; -use multiversx_sc::{ - api::{ - BigIntApiImpl, ManagedBufferApiImpl, RawHandle, StorageReadApi, StorageReadApiImpl, - StorageWriteApi, StorageWriteApiImpl, - }, - types::heap::Address, +use multiversx_sc::api::{ + BigIntApiImpl, ManagedBufferApiImpl, RawHandle, StorageReadApi, StorageReadApiImpl, + StorageWriteApi, StorageWriteApiImpl, }; use super::VMHooksManagedTypes; @@ -27,7 +25,7 @@ pub trait VMHooksStorageRead: VMHooksHandlerSource { key_handle: RawHandle, dest: RawHandle, ) { - let address = Address::from_slice(self.m_types_borrow().mb_get(address_handle)); + let address = VMAddress::from_slice(self.m_types_borrow().mb_get(address_handle)); let value = self.storage_read_any_address(&address, self.m_types_borrow().mb_get(key_handle)); self.m_types_borrow_mut().mb_set(dest, value); diff --git a/vm/src/vm_hooks/vh_managed_types_cell.rs b/vm/src/vm_hooks/vh_managed_types_cell.rs index ee7284058c..abdd511998 100644 --- a/vm/src/vm_hooks/vh_managed_types_cell.rs +++ b/vm/src/vm_hooks/vh_managed_types_cell.rs @@ -1,9 +1,8 @@ use std::cell::{Ref, RefCell, RefMut}; -use multiversx_sc::types::{Address, CodeMetadata}; - use crate::{ tx_mock::{TxFunctionName, TxInput, TxLog, TxManagedTypes, TxResult}, + types::{CodeMetadata, VMAddress}, world_mock::{AccountData, BlockInfo}, }; @@ -49,7 +48,7 @@ impl VMHooksHandlerSource for TxManagedTypesCell { panic!("cannot log events in the StaticApi") } - fn storage_read_any_address(&self, _address: &Address, _key: &[u8]) -> Vec { + fn storage_read_any_address(&self, _address: &VMAddress, _key: &[u8]) -> Vec { panic!("cannot access the storage in the StaticApi") } @@ -65,17 +64,17 @@ impl VMHooksHandlerSource for TxManagedTypesCell { panic!("cannot access the block info in the StaticApi") } - fn account_data(&self, _address: &Address) -> AccountData { + fn account_data(&self, _address: &VMAddress) -> AccountData { panic!("cannot access account data in the StaticApi") } - fn account_code(&self, _address: &Address) -> Vec { + fn account_code(&self, _address: &VMAddress) -> Vec { panic!("cannot access account data in the StaticApi") } fn perform_async_call( &self, - _to: Address, + _to: VMAddress, _egld_value: num_bigint::BigUint, _func_name: TxFunctionName, _args: Vec>, @@ -85,7 +84,7 @@ impl VMHooksHandlerSource for TxManagedTypesCell { fn perform_execute_on_dest_context( &self, - _to: Address, + _to: VMAddress, _egld_value: num_bigint::BigUint, _func_name: TxFunctionName, _args: Vec>, @@ -99,13 +98,13 @@ impl VMHooksHandlerSource for TxManagedTypesCell { _contract_code: Vec, _code_metadata: CodeMetadata, _args: Vec>, - ) -> (Address, Vec>) { + ) -> (VMAddress, Vec>) { panic!("cannot launch contract calls in the StaticApi") } fn perform_transfer_execute( &self, - _to: Address, + _to: VMAddress, _egld_value: num_bigint::BigUint, _func_name: TxFunctionName, _arguments: Vec>, diff --git a/vm/src/vm_hooks/vh_source.rs b/vm/src/vm_hooks/vh_source.rs index c7172ae214..367182e67d 100644 --- a/vm/src/vm_hooks/vh_source.rs +++ b/vm/src/vm_hooks/vh_source.rs @@ -3,10 +3,9 @@ use std::{ fmt::Debug, }; -use multiversx_sc::types::{Address, CodeMetadata, H256}; - use crate::{ tx_mock::{TxFunctionName, TxInput, TxLog, TxManagedTypes, TxResult}, + types::{CodeMetadata, VMAddress, H256}, world_mock::{AccountData, BlockInfo}, }; @@ -41,7 +40,7 @@ pub trait VMHooksHandlerSource: Debug { self.storage_read_any_address(&self.input_ref().to, key) } - fn storage_read_any_address(&self, address: &Address, key: &[u8]) -> Vec; + fn storage_read_any_address(&self, address: &VMAddress, key: &[u8]) -> Vec; fn storage_write(&self, key: &[u8], value: &[u8]); @@ -52,7 +51,7 @@ pub trait VMHooksHandlerSource: Debug { /// For ownership reasons, needs to return a clone. /// /// Can be optimized, but is not a priority right now. - fn account_data(&self, address: &Address) -> AccountData; + fn account_data(&self, address: &VMAddress) -> AccountData; /// For ownership reasons, needs to return a clone. /// @@ -61,11 +60,11 @@ pub trait VMHooksHandlerSource: Debug { self.account_data(&self.input_ref().to) } - fn account_code(&self, address: &Address) -> Vec; + fn account_code(&self, address: &VMAddress) -> Vec; fn perform_async_call( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, args: Vec>, @@ -73,7 +72,7 @@ pub trait VMHooksHandlerSource: Debug { fn perform_execute_on_dest_context( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, args: Vec>, @@ -85,11 +84,11 @@ pub trait VMHooksHandlerSource: Debug { contract_code: Vec, code_metadata: CodeMetadata, args: Vec>, - ) -> (Address, Vec>); + ) -> (VMAddress, Vec>); fn perform_transfer_execute( &self, - to: Address, + to: VMAddress, egld_value: num_bigint::BigUint, func_name: TxFunctionName, arguments: Vec>, diff --git a/vm/src/world_mock/account_data.rs b/vm/src/world_mock/account_data.rs index 41229ebf35..ce16f70175 100644 --- a/vm/src/world_mock/account_data.rs +++ b/vm/src/world_mock/account_data.rs @@ -1,6 +1,5 @@ use super::AccountEsdt; -use crate::{display_util::key_hex, num_bigint::BigUint}; -use multiversx_sc::types::heap::Address; +use crate::{display_util::key_hex, num_bigint::BigUint, types::VMAddress}; use std::{collections::HashMap, fmt, fmt::Write}; pub const STORAGE_RESERVED_PREFIX: &[u8] = b"ELROND"; @@ -9,14 +8,14 @@ pub type AccountStorage = HashMap, Vec>; #[derive(Clone, Debug)] pub struct AccountData { - pub address: Address, + pub address: VMAddress, pub nonce: u64, pub egld_balance: BigUint, pub esdt: AccountEsdt, pub storage: AccountStorage, pub username: Vec, pub contract_path: Option>, - pub contract_owner: Option
, + pub contract_owner: Option, pub developer_rewards: BigUint, } diff --git a/vm/src/world_mock/blockchain_mock.rs b/vm/src/world_mock/blockchain_mock.rs index 8d927af597..2c67da1945 100644 --- a/vm/src/world_mock/blockchain_mock.rs +++ b/vm/src/world_mock/blockchain_mock.rs @@ -2,9 +2,9 @@ use crate::{ num_bigint::BigUint, tx_execution::{init_builtin_functions, BuiltinFunctionMap}, tx_mock::BlockchainUpdate, + types::VMAddress, }; use multiversx_chain_vm_executor::Executor; -use multiversx_sc::types::heap::Address; use num_traits::Zero; use std::{collections::HashMap, fmt::Debug, rc::Rc}; @@ -13,9 +13,9 @@ use super::{AccountData, BlockInfo, FailingExecutor}; const ELROND_REWARD_KEY: &[u8] = b"ELRONDreward"; pub struct BlockchainMock { - pub accounts: HashMap, + pub accounts: HashMap, pub builtin_functions: Rc, - pub new_addresses: HashMap<(Address, u64), Address>, + pub new_addresses: HashMap<(VMAddress, u64), VMAddress>, pub previous_block_info: BlockInfo, pub current_block_info: BlockInfo, pub executor: Box, @@ -41,7 +41,7 @@ impl Default for BlockchainMock { } impl BlockchainMock { - pub fn account_exists(&self, address: &Address) -> bool { + pub fn account_exists(&self, address: &VMAddress) -> bool { self.accounts.contains_key(address) } @@ -49,7 +49,7 @@ impl BlockchainMock { updates.apply(self); } - pub fn increase_account_nonce(&mut self, address: &Address) { + pub fn increase_account_nonce(&mut self, address: &VMAddress) { let account = self.accounts.get_mut(address).unwrap_or_else(|| { panic!( "Account not found: {}", @@ -59,7 +59,7 @@ impl BlockchainMock { account.nonce += 1; } - pub fn subtract_tx_gas(&mut self, address: &Address, gas_limit: u64, gas_price: u64) { + pub fn subtract_tx_gas(&mut self, address: &VMAddress, gas_limit: u64, gas_price: u64) { let account = self.accounts.get_mut(address).unwrap_or_else(|| { panic!( "Account not found: {}", @@ -74,7 +74,7 @@ impl BlockchainMock { account.egld_balance -= &gas_cost; } - pub fn increase_validator_reward(&mut self, address: &Address, amount: &BigUint) { + pub fn increase_validator_reward(&mut self, address: &VMAddress, amount: &BigUint) { let account = self.accounts.get_mut(address).unwrap_or_else(|| { panic!( "Account not found: {}", diff --git a/vm/src/world_mock/blockchain_mock_account_util.rs b/vm/src/world_mock/blockchain_mock_account_util.rs index 410cc03f54..ecc32bba2a 100644 --- a/vm/src/world_mock/blockchain_mock_account_util.rs +++ b/vm/src/world_mock/blockchain_mock_account_util.rs @@ -1,8 +1,6 @@ -use multiversx_sc::types::heap::Address; - use std::{collections::HashMap, fmt::Write}; -use crate::display_util::address_hex; +use crate::{display_util::address_hex, types::VMAddress}; use super::{AccountData, BlockchainMock}; @@ -17,7 +15,7 @@ impl BlockchainMock { self.add_account(acct); } - pub fn update_accounts(&mut self, accounts: HashMap) { + pub fn update_accounts(&mut self, accounts: HashMap) { self.accounts.extend(accounts.into_iter()); } @@ -31,15 +29,19 @@ impl BlockchainMock { pub fn put_new_address( &mut self, - creator_address: Address, + creator_address: VMAddress, creator_nonce: u64, - new_address: Address, + new_address: VMAddress, ) { self.new_addresses .insert((creator_address, creator_nonce), new_address); } - pub fn get_new_address(&self, creator_address: Address, creator_nonce: u64) -> Option
{ + pub fn get_new_address( + &self, + creator_address: VMAddress, + creator_nonce: u64, + ) -> Option { self.new_addresses .get(&(creator_address, creator_nonce)) .cloned() diff --git a/vm/src/world_mock/blockchain_tx_info.rs b/vm/src/world_mock/blockchain_tx_info.rs index 0718f752cc..5e4f62b47a 100644 --- a/vm/src/world_mock/blockchain_tx_info.rs +++ b/vm/src/world_mock/blockchain_tx_info.rs @@ -1,5 +1,4 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::types::heap::Address; +use crate::{num_bigint::BigUint, types::VMAddress}; use super::{AccountEsdt, BlockInfo, BlockchainMock}; @@ -12,11 +11,11 @@ pub struct BlockchainTxInfo { pub current_block_info: BlockInfo, pub contract_balance: BigUint, pub contract_esdt: AccountEsdt, - pub contract_owner: Option
, + pub contract_owner: Option, } impl BlockchainMock { - pub fn create_tx_info(&self, contract_address: &Address) -> BlockchainTxInfo { + pub fn create_tx_info(&self, contract_address: &VMAddress) -> BlockchainTxInfo { if let Some(contract) = self.accounts.get(contract_address) { BlockchainTxInfo { previous_block_info: self.previous_block_info.clone(), diff --git a/vm/src/world_mock/esdt_instance_metadata.rs b/vm/src/world_mock/esdt_instance_metadata.rs index 431840eab7..53b8af6fab 100644 --- a/vm/src/world_mock/esdt_instance_metadata.rs +++ b/vm/src/world_mock/esdt_instance_metadata.rs @@ -1,10 +1,10 @@ -use multiversx_sc::types::heap::Address; +use crate::types::VMAddress; /// Holds the data for a Elrond standard digital token transaction #[derive(Clone, Default, Debug)] pub struct EsdtInstanceMetadata { pub name: Vec, - pub creator: Option
, + pub creator: Option, pub royalties: u64, pub hash: Option>, pub uri: Vec>, From 4389932467477061075efb567c38deb94c151101 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 11:27:24 +0300 Subject: [PATCH 02/14] moved bech32 module to framework/scenario --- framework/scenario/Cargo.toml | 1 + {vm => framework/scenario}/src/bech32.rs | 0 framework/scenario/src/lib.rs | 3 ++- framework/scenario/src/whitebox/raw_converter.rs | 3 ++- vm/Cargo.toml | 1 - vm/src/lib.rs | 1 - 6 files changed, 5 insertions(+), 4 deletions(-) rename {vm => framework/scenario}/src/bech32.rs (100%) diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index ca78115ff7..e5e050a1f6 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -21,6 +21,7 @@ base64 = "0.13.0" num-bigint = "0.4" num-traits = "0.2" hex = "0.4" +bech32 = "0.9" log = "0.4.17" sha2 = "0.10.6" serde = "1.0" diff --git a/vm/src/bech32.rs b/framework/scenario/src/bech32.rs similarity index 100% rename from vm/src/bech32.rs rename to framework/scenario/src/bech32.rs diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index 7081618839..cfb374d1aa 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -2,6 +2,7 @@ #![feature(exhaustive_patterns)] pub mod api; +pub mod bech32; pub mod debug_executor; mod facade; pub mod managed_test_util; @@ -16,7 +17,7 @@ pub mod whitebox; pub use whitebox as testing_framework; pub use api::DebugApi; -pub use multiversx_chain_vm::{self, bech32, num_bigint}; +pub use multiversx_chain_vm::{self, num_bigint}; pub use multiversx_sc; diff --git a/framework/scenario/src/whitebox/raw_converter.rs b/framework/scenario/src/whitebox/raw_converter.rs index 0dd19681eb..855dae2a6c 100644 --- a/framework/scenario/src/whitebox/raw_converter.rs +++ b/framework/scenario/src/whitebox/raw_converter.rs @@ -12,7 +12,8 @@ use crate::{ }; use multiversx_chain_vm::{ num_bigint, - world_mock::{AccountData, BlockInfo, EsdtData}, types::VMAddress, + types::VMAddress, + world_mock::{AccountData, BlockInfo, EsdtData}, }; use num_traits::Zero; diff --git a/vm/Cargo.toml b/vm/Cargo.toml index c3dda8bab9..2a8e856abb 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -26,7 +26,6 @@ rand = "0.8.5" rand_seeder = "0.2.2" ed25519-dalek = "1.0.1" itertools = "0.10.3" -bech32 = "0.9" bitflags = "1.3.2" [dependencies.multiversx-sc] diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 69fd6b30a9..ebfc8bf092 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -1,4 +1,3 @@ -pub mod bech32; pub mod crypto_functions; pub mod display_util; pub mod mem_conv; From e4a764dd0f8b53e163562f440b249ccbb538d4c3 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 11:47:41 +0300 Subject: [PATCH 03/14] vm - separate error messages --- framework/base/src/err_msg.rs | 14 -------------- vm/src/lib.rs | 1 + vm/src/vm_err_msg.rs | 13 +++++++++++++ vm/src/vm_hooks/vh_debugger_stack.rs | 6 +++--- vm/src/vm_hooks/vh_handler/vh_call_value.rs | 8 ++++---- .../vh_managed_types/vh_big_float.rs | 19 +++++++++++-------- .../vh_handler/vh_managed_types/vh_big_int.rs | 13 +++++++------ 7 files changed, 39 insertions(+), 35 deletions(-) create mode 100644 vm/src/vm_err_msg.rs diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 6df9fe308b..46f43e3313 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -1,7 +1,6 @@ pub const PANIC_OCCURRED: &str = "panic occurred"; pub const MEM_ALLOC_ERROR: &str = "memory allocation error"; -pub const NON_PAYABLE_FUNC_EGLD: &str = "function does not accept EGLD payment"; pub const NON_PAYABLE_FUNC_ESDT: &str = "function does not accept ESDT payment"; pub const BAD_TOKEN_PROVIDED: &str = "bad call value token provided"; pub const BAD_TOKEN_TICKER_FORMAT: &[u8] = b"bad token ticker format"; @@ -40,16 +39,6 @@ pub const VALUE_EXCEEDS_SLICE: &[u8] = b"value exceeds target slice"; pub const CAST_TO_I64_ERROR: &[u8] = b"cast to i64 error"; pub const BIG_UINT_EXCEEDS_SLICE: &[u8] = b"big uint as_bytes exceed target slice"; pub const BIG_UINT_SUB_NEGATIVE: &[u8] = b"cannot subtract because result would be negative"; -pub const BIG_INT_BITWISE_OPERATION_NEGATIVE: &str = - "bitwise operations only allowed on positive integers"; -pub const BIG_INT_CANNOT_BE_REPRESENTED_AS_INT64: &str = "big int cannot be represented as int64"; -pub const DIVISION_BY_0: &str = "division by 0"; -pub const BAD_BOUNDS_LOWER: &str = "bad bounds (lower)"; - -pub const EXPONENT_IS_POSITIVE: &str = "exponent must be negative"; -pub const NUMBER_IS_NOT_NORMAL: &[u8] = - b"number is not normal. It is either infinite, NaN or subnormal"; -pub const CANNOT_COMPARE_VALUES: &[u8] = b"values are not comparable"; pub const DESERIALIZATION_INVALID_BYTE: &str = "call data deserialization error: not a valid byte"; pub const DESERIALIZATION_NOT_32_BYTES: &str = @@ -68,9 +57,6 @@ pub static ONLY_USER_ACCOUNT_CALLER: &[u8] = b"Endpoint can only be called by us pub const STORAGE_NOT_I64: &[u8] = b"storage not i64"; pub const STORAGE_NOT_32_BYTES: &[u8] = b"32 bytes of data expected in storage at key"; -/// Mirrors the error message from the VM. -pub const ERROR_SIGNALLED_BY_SMARTCONTRACT: &str = "error signalled by smartcontract"; - /// An additional non-VM status, meant just to signal an error in the debugger infrastructure of in the tests. pub const DEBUG_API_ERR_STATUS: u64 = 100; pub const DEBUG_API_ERR_HANDLE_STALE: &str = diff --git a/vm/src/lib.rs b/vm/src/lib.rs index ebfc8bf092..2625c34df6 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -4,6 +4,7 @@ pub mod mem_conv; pub mod tx_execution; pub mod tx_mock; pub mod types; +pub mod vm_err_msg; pub mod vm_hooks; pub mod world_mock; diff --git a/vm/src/vm_err_msg.rs b/vm/src/vm_err_msg.rs new file mode 100644 index 0000000000..894bbfa654 --- /dev/null +++ b/vm/src/vm_err_msg.rs @@ -0,0 +1,13 @@ +pub const NON_PAYABLE_FUNC_EGLD: &str = "function does not accept EGLD payment"; +pub const NON_PAYABLE_FUNC_ESDT: &str = "function does not accept ESDT payment"; + +pub const BIG_INT_BITWISE_OPERATION_NEGATIVE: &str = + "bitwise operations only allowed on positive integers"; +pub const DIVISION_BY_0: &str = "division by 0"; +pub const BAD_BOUNDS_LOWER: &str = "bad bounds (lower)"; +pub const EXPONENT_IS_POSITIVE: &str = "exponent must be negative"; +pub const NUMBER_IS_NOT_NORMAL: &str = + "number is not normal. It is either infinite, NaN or subnormal"; +pub const CANNOT_COMPARE_VALUES: &str = "values are not comparable"; + +pub const ERROR_SIGNALLED_BY_SMARTCONTRACT: &str = "error signalled by smartcontract"; diff --git a/vm/src/vm_hooks/vh_debugger_stack.rs b/vm/src/vm_hooks/vh_debugger_stack.rs index 4ac37afaa9..068a183d3d 100644 --- a/vm/src/vm_hooks/vh_debugger_stack.rs +++ b/vm/src/vm_hooks/vh_debugger_stack.rs @@ -4,7 +4,6 @@ use std::{ }; use multiversx_chain_vm_executor::BreakpointValue; -use multiversx_sc::err_msg; use crate::{ tx_execution::{deploy_contract, execute_builtin_function_or_default}, @@ -13,6 +12,7 @@ use crate::{ TxInput, TxManagedTypes, TxPanic, TxResult, }, types::{CodeMetadata, VMAddress}, + vm_err_msg, world_mock::{AccountData, BlockInfo, STORAGE_RESERVED_PREFIX}, }; @@ -168,7 +168,7 @@ impl VMHooksHandlerSource for TxContextWrapper { self.sync_call_post_processing(tx_result, blockchain_updates), ), 10 => self.vm_error(&tx_result.result_message), // TODO: not sure it's the right condition, it catches insufficient funds - _ => self.vm_error(err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT), + _ => self.vm_error(vm_err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT), } } @@ -192,7 +192,7 @@ impl VMHooksHandlerSource for TxContextWrapper { let _ = self.sync_call_post_processing(tx_result, blockchain_updates); }, 10 => self.vm_error(&tx_result.result_message), // TODO: not sure it's the right condition, it catches insufficient funds - _ => self.vm_error(err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT), + _ => self.vm_error(vm_err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT), } } } diff --git a/vm/src/vm_hooks/vh_handler/vh_call_value.rs b/vm/src/vm_hooks/vh_handler/vh_call_value.rs index ce88a504df..a8d52091c2 100644 --- a/vm/src/vm_hooks/vh_handler/vh_call_value.rs +++ b/vm/src/vm_hooks/vh_handler/vh_call_value.rs @@ -1,5 +1,5 @@ -use crate::{num_bigint, vm_hooks::VMHooksHandlerSource}; -use multiversx_sc::{api::RawHandle, err_msg}; +use crate::{num_bigint, vm_err_msg, vm_hooks::VMHooksHandlerSource}; +use multiversx_sc::api::RawHandle; use num_traits::Zero; use super::VMHooksManagedTypes; @@ -7,10 +7,10 @@ use super::VMHooksManagedTypes; pub trait VMHooksCallValue: VMHooksHandlerSource + VMHooksManagedTypes { fn check_not_payable(&self) { if self.input_ref().egld_value > num_bigint::BigUint::zero() { - self.vm_error(err_msg::NON_PAYABLE_FUNC_EGLD); + self.vm_error(vm_err_msg::NON_PAYABLE_FUNC_EGLD); } if self.esdt_num_transfers() > 0 { - self.vm_error(err_msg::NON_PAYABLE_FUNC_ESDT); + self.vm_error(vm_err_msg::NON_PAYABLE_FUNC_ESDT); } } diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs index 269f8d318a..ea6e80b29d 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs @@ -1,11 +1,14 @@ -use crate::vm_hooks::{VMHooksError, VMHooksHandlerSource}; +use crate::{ + vm_err_msg, + vm_hooks::{VMHooksError, VMHooksHandlerSource}, +}; use core::{ cmp::Ordering, ops::{Add, Div, Mul, Neg, Sub}, }; use std::convert::TryInto; -use multiversx_sc::{api::RawHandle, codec::num_bigint::BigInt, err_msg}; +use multiversx_sc::{api::RawHandle, codec::num_bigint::BigInt}; use num_traits::ToPrimitive; macro_rules! binary_op_method { @@ -42,7 +45,7 @@ macro_rules! unary_op_method_big_int_handle { pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { fn bf_from_parts(&self, integral_part: i32, fractional_part: i32, exponent: i32) -> RawHandle { if exponent > 0 { - self.vm_error(err_msg::EXPONENT_IS_POSITIVE); + self.vm_error(vm_err_msg::EXPONENT_IS_POSITIVE); } let exponent_multiplier = (10.0_f64).powi(exponent); @@ -60,7 +63,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { fn bf_from_frac(&self, numerator: i64, denominator: i64) -> RawHandle { if denominator == 0 { - self.vm_error(err_msg::DIVISION_BY_0); + self.vm_error(vm_err_msg::DIVISION_BY_0); } let value = if let (Some(f_numerator), Some(f_denominator)) = (numerator.to_f64(), denominator.to_f64()) @@ -76,7 +79,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { fn bf_from_sci(&self, significand: i64, exponent: i64) -> RawHandle { if exponent > 0 { - self.vm_error(err_msg::EXPONENT_IS_POSITIVE); + self.vm_error(vm_err_msg::EXPONENT_IS_POSITIVE); } let value = if let Some(f_significand) = significand.to_f64() { @@ -106,14 +109,14 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { Some(Ordering::Less) => -1, Some(Ordering::Equal) => 0, Some(Ordering::Greater) => 1, - None => self.signal_error(err_msg::CANNOT_COMPARE_VALUES), + None => self.vm_error(vm_err_msg::CANNOT_COMPARE_VALUES), } } fn bf_sign(&self, x: RawHandle) -> i32 { let bf = self.m_types_borrow().bf_get_f64(x); if !bf.is_normal() { - self.signal_error(err_msg::NUMBER_IS_NOT_NORMAL) + self.vm_error(vm_err_msg::NUMBER_IS_NOT_NORMAL) } if bf.is_sign_positive() { @@ -133,7 +136,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { fn bf_sqrt(&self, dest: RawHandle, x: RawHandle) { let bf_x = self.m_types_borrow().bf_get_f64(x); if bf_x < 0f64 { - self.vm_error(err_msg::BAD_BOUNDS_LOWER); + self.vm_error(vm_err_msg::BAD_BOUNDS_LOWER); } let result = bf_x.sqrt(); self.m_types_borrow_mut().bf_overwrite(dest, result); diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs index 59d196d8a6..64ef3918cf 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs @@ -1,13 +1,14 @@ use crate::{ num_bigint, tx_mock::big_int_to_i64, + vm_err_msg, vm_hooks::{VMHooksError, VMHooksHandlerSource}, }; use core::{ cmp::Ordering, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}, }; -use multiversx_sc::{api::RawHandle, err_msg, types::heap::BoxedBytes}; +use multiversx_sc::{api::RawHandle, types::heap::BoxedBytes}; use num_traits::{pow, sign::Signed}; use std::convert::TryInto; @@ -28,11 +29,11 @@ macro_rules! binary_bitwise_op_method { fn $method_name(&self, dest: RawHandle, x: RawHandle, y: RawHandle) { let bi_x = self.m_types_borrow().bi_get(x); if bi_x.sign() == num_bigint::Sign::Minus { - self.vm_error(err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); + self.vm_error(vm_err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); } let bi_y = self.m_types_borrow().bi_get(y); if bi_y.sign() == num_bigint::Sign::Minus { - self.vm_error(err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); + self.vm_error(vm_err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); } let result = bi_x.$rust_op_name(bi_y); self.m_types_borrow_mut().bi_overwrite(dest, result); @@ -99,7 +100,7 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError { fn bi_get_int64(&self, destination_handle: RawHandle) -> i64 { self.m_types_borrow() .bi_to_i64(destination_handle) - .unwrap_or_else(|| self.vm_error(err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE)) + .unwrap_or_else(|| self.vm_error(vm_err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE)) } binary_op_method! {bi_add, add} @@ -152,7 +153,7 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError { fn bi_shr(&self, dest: RawHandle, x: RawHandle, bits: usize) { let bi_x = self.m_types_borrow().bi_get(x); if bi_x.sign() == num_bigint::Sign::Minus { - self.vm_error(err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); + self.vm_error(vm_err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); } let result = bi_x.shr(bits); self.m_types_borrow_mut().bi_overwrite(dest, result); @@ -161,7 +162,7 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError { fn bi_shl(&self, dest: RawHandle, x: RawHandle, bits: usize) { let bi_x = self.m_types_borrow().bi_get(x); if bi_x.sign() == num_bigint::Sign::Minus { - self.vm_error(err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); + self.vm_error(vm_err_msg::BIG_INT_BITWISE_OPERATION_NEGATIVE); } let result = bi_x.shl(bits); self.m_types_borrow_mut().bi_overwrite(dest, result); From 2ee4653a4515773209b67e5366ca5d3f3d892fd1 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 12:07:11 +0300 Subject: [PATCH 04/14] vm - separate builtin function names --- .../mod.rs => builtin_function_mocks.rs} | 3 +++ .../esdt_nft/esdt_local_burn.rs | 3 +-- .../esdt_nft/esdt_local_mint.rs | 3 +-- .../esdt_nft/esdt_nft_add_quantity_mock.rs | 6 ++---- .../esdt_nft/esdt_nft_add_uri_mock.rs | 10 +++++----- .../esdt_nft/esdt_nft_burn_mock.rs | 11 +++++------ .../esdt_nft/esdt_nft_create_mock.rs | 9 +++------ .../esdt_nft/esdt_nft_update_attriutes_mock.rs | 9 ++++----- .../general/change_owner_mock.rs | 2 +- .../general/claim_developer_rewards_mock.rs | 2 +- .../general/migrate_username_mock.rs | 2 +- .../general/set_username_mock.rs | 2 +- .../general/upgrade_contract.rs | 2 +- .../transfer/esdt_multi_transfer_mock.rs | 7 ++++--- .../transfer/esdt_nft_transfer_mock.rs | 7 ++++--- .../transfer/esdt_transfer_mock.rs | 6 +++--- .../vm_builtin_function_names.rs | 15 +++++++++++++++ vm/src/vm_hooks/vh_handler/vh_send.rs | 13 ++++++------- vm/src/vm_hooks/vh_handler/vh_storage.rs | 14 ++------------ 19 files changed, 63 insertions(+), 63 deletions(-) rename vm/src/tx_execution/{builtin_function_mocks/mod.rs => builtin_function_mocks.rs} (61%) create mode 100644 vm/src/tx_execution/builtin_function_mocks/vm_builtin_function_names.rs diff --git a/vm/src/tx_execution/builtin_function_mocks/mod.rs b/vm/src/tx_execution/builtin_function_mocks.rs similarity index 61% rename from vm/src/tx_execution/builtin_function_mocks/mod.rs rename to vm/src/tx_execution/builtin_function_mocks.rs index 07f7b0f90f..948ada1b60 100644 --- a/vm/src/tx_execution/builtin_function_mocks/mod.rs +++ b/vm/src/tx_execution/builtin_function_mocks.rs @@ -5,6 +5,9 @@ mod builtin_func_trait; mod esdt_nft; mod general; mod transfer; +pub mod vm_builtin_function_names; pub use builtin_func_exec::{execute_builtin_function_or_default, init_builtin_functions}; pub use builtin_func_map::BuiltinFunctionMap; +pub use builtin_func_trait::{BuiltinFunction, BuiltinFunctionEsdtTransferInfo}; +pub use vm_builtin_function_names as builtin_function_names; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs index 3ec6fd4872..5b587ae4d8 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs @@ -1,5 +1,4 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::api::ESDT_LOCAL_BURN_FUNC_NAME; +use crate::{num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_LOCAL_BURN_FUNC_NAME}; use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs index c5baae2a07..2d076d31b5 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs @@ -1,5 +1,4 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::api::ESDT_LOCAL_MINT_FUNC_NAME; +use crate::{num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_LOCAL_MINT_FUNC_NAME}; use crate::{ tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs index 7f47afc23e..c5f9d8993d 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs @@ -1,10 +1,8 @@ use crate::num_bigint::BigUint; -use multiversx_sc::{ - api::ESDT_NFT_ADD_QUANTITY_FUNC_NAME, - codec::{top_encode_to_vec_u8, TopDecode}, -}; +use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use crate::{ + tx_execution::builtin_function_names::ESDT_NFT_ADD_QUANTITY_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, world_mock::EsdtInstanceMetadata, }; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs index ffeb57b757..93ffd696ed 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs @@ -1,9 +1,9 @@ -use multiversx_sc::{ - api::ESDT_NFT_ADD_URI_FUNC_NAME, - codec::{top_encode_to_vec_u8, TopDecode}, -}; +use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}; +use crate::{ + tx_execution::builtin_function_names::ESDT_NFT_ADD_URI_FUNC_NAME, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, +}; use super::super::builtin_func_trait::BuiltinFunction; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs index 31b865799f..3e2615c028 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs @@ -1,10 +1,9 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::{ - api::ESDT_NFT_BURN_FUNC_NAME, - codec::{top_encode_to_vec_u8, TopDecode}, +use crate::{ + num_bigint::BigUint, + tx_execution::builtin_function_names::ESDT_NFT_BURN_FUNC_NAME, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, }; - -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}; +use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs index efbf608049..9801e0e628 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs @@ -1,13 +1,10 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::{ - api::ESDT_NFT_CREATE_FUNC_NAME, - codec::{top_encode_to_vec_u8, TopDecode}, -}; - use crate::{ + num_bigint::BigUint, + tx_execution::builtin_function_names::ESDT_NFT_CREATE_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, world_mock::{EsdtInstance, EsdtInstanceMetadata}, }; +use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs index 04a9df8db3..ee7dac18b8 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs @@ -1,9 +1,8 @@ -use multiversx_sc::{ - api::ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, - codec::{top_encode_to_vec_u8, TopDecode}, +use crate::{ + tx_execution::builtin_function_names::ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, }; - -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}; +use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; diff --git a/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs index 750c3c52cf..a2ee0e0d27 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/change_owner_mock.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::CHANGE_OWNER_BUILTIN_FUNC_NAME; +use crate::tx_execution::builtin_function_names::CHANGE_OWNER_BUILTIN_FUNC_NAME; use crate::{ tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, diff --git a/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs index bbb4675737..502b19c765 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/claim_developer_rewards_mock.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::CLAIM_DEVELOPER_REWARDS_FUNC_NAME; +use crate::tx_execution::builtin_function_names::CLAIM_DEVELOPER_REWARDS_FUNC_NAME; use num_bigint::BigUint; use num_traits::Zero; diff --git a/vm/src/tx_execution/builtin_function_mocks/general/migrate_username_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/migrate_username_mock.rs index 1d5fc22069..c260e17c4c 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/migrate_username_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/migrate_username_mock.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::MIGRATE_USERNAME_FUNC_NAME; +use crate::tx_execution::builtin_function_names::MIGRATE_USERNAME_FUNC_NAME; use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}; diff --git a/vm/src/tx_execution/builtin_function_mocks/general/set_username_mock.rs b/vm/src/tx_execution/builtin_function_mocks/general/set_username_mock.rs index aad55eb8fd..518ba1483e 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/set_username_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/set_username_mock.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::SET_USERNAME_FUNC_NAME; +use crate::tx_execution::builtin_function_names::SET_USERNAME_FUNC_NAME; use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}; diff --git a/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs b/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs index 919b765450..3ec10b98df 100644 --- a/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs +++ b/vm/src/tx_execution/builtin_function_mocks/general/upgrade_contract.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::UPGRADE_CONTRACT_FUNC_NAME; +use crate::tx_execution::builtin_function_names::UPGRADE_CONTRACT_FUNC_NAME; use crate::{ tx_execution::default_execution, diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs index 8ed1ca2600..129ec79761 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs @@ -1,13 +1,14 @@ -use multiversx_sc::{api::ESDT_MULTI_TRANSFER_FUNC_NAME, codec::TopDecode}; +use crate::tx_execution::builtin_function_names::ESDT_MULTI_TRANSFER_FUNC_NAME; +use multiversx_sc::codec::TopDecode; use crate::{ - tx_execution::builtin_function_mocks::builtin_func_trait::BuiltinFunctionEsdtTransferInfo, + tx_execution::BuiltinFunctionEsdtTransferInfo, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, types::VMAddress, }; use super::{ - super::builtin_func_trait::BuiltinFunction, + super::BuiltinFunction, transfer_common::{ execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall, RawEsdtTransfer, diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs index f0277e21b1..dc1ba1722a 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_nft_transfer_mock.rs @@ -1,12 +1,13 @@ use crate::{ - tx_execution::builtin_function_mocks::builtin_func_trait::BuiltinFunctionEsdtTransferInfo, + tx_execution::{ + builtin_function_names::ESDT_NFT_TRANSFER_FUNC_NAME, BuiltinFunctionEsdtTransferInfo, + }, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, types::VMAddress, }; -use multiversx_sc::api::ESDT_NFT_TRANSFER_FUNC_NAME; use super::{ - super::builtin_func_trait::BuiltinFunction, + super::BuiltinFunction, transfer_common::{ execute_transfer_builtin_func, extract_transfer_info, ParsedTransferBuiltinFunCall, RawEsdtTransfer, diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs index 4c571aa41e..038e34120d 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_transfer_mock.rs @@ -1,7 +1,7 @@ -use multiversx_sc::api::ESDT_TRANSFER_FUNC_NAME; - use crate::{ - tx_execution::builtin_function_mocks::builtin_func_trait::BuiltinFunctionEsdtTransferInfo, + tx_execution::{ + builtin_function_names::ESDT_TRANSFER_FUNC_NAME, BuiltinFunctionEsdtTransferInfo, + }, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxResult}, }; diff --git a/vm/src/tx_execution/builtin_function_mocks/vm_builtin_function_names.rs b/vm/src/tx_execution/builtin_function_mocks/vm_builtin_function_names.rs new file mode 100644 index 0000000000..2c3b28dd0b --- /dev/null +++ b/vm/src/tx_execution/builtin_function_mocks/vm_builtin_function_names.rs @@ -0,0 +1,15 @@ +pub const ESDT_LOCAL_MINT_FUNC_NAME: &str = "ESDTLocalMint"; +pub const ESDT_LOCAL_BURN_FUNC_NAME: &str = "ESDTLocalBurn"; +pub const ESDT_MULTI_TRANSFER_FUNC_NAME: &str = "MultiESDTNFTTransfer"; +pub const ESDT_NFT_TRANSFER_FUNC_NAME: &str = "ESDTNFTTransfer"; +pub const ESDT_NFT_CREATE_FUNC_NAME: &str = "ESDTNFTCreate"; +pub const ESDT_NFT_ADD_QUANTITY_FUNC_NAME: &str = "ESDTNFTAddQuantity"; +pub const ESDT_NFT_ADD_URI_FUNC_NAME: &str = "ESDTNFTAddURI"; +pub const ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME: &str = "ESDTNFTUpdateAttributes"; +pub const ESDT_NFT_BURN_FUNC_NAME: &str = "ESDTNFTBurn"; +pub const ESDT_TRANSFER_FUNC_NAME: &str = "ESDTTransfer"; +pub const CHANGE_OWNER_BUILTIN_FUNC_NAME: &str = "ChangeOwnerAddress"; +pub const CLAIM_DEVELOPER_REWARDS_FUNC_NAME: &str = "ClaimDeveloperRewards"; +pub const SET_USERNAME_FUNC_NAME: &str = "SetUserName"; +pub const MIGRATE_USERNAME_FUNC_NAME: &str = "migrateUserName"; +pub const UPGRADE_CONTRACT_FUNC_NAME: &str = "upgradeContract"; diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index 456242fcaf..7ea9bcdde9 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -1,16 +1,15 @@ use crate::{ num_bigint, + tx_execution::builtin_function_names::{ + ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, ESDT_TRANSFER_FUNC_NAME, + UPGRADE_CONTRACT_FUNC_NAME, + }, tx_mock::{AsyncCallTxData, Promise, TxFunctionName, TxTokenTransfer}, types::{CodeMetadata, VMAddress}, vm_hooks::VMHooksHandlerSource, }; -use multiversx_sc::{ - api::{ - RawHandle, ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, - ESDT_TRANSFER_FUNC_NAME, UPGRADE_CONTRACT_FUNC_NAME, - }, - codec::top_encode_to_vec_u8, -}; + +use multiversx_sc::{api::RawHandle, codec::top_encode_to_vec_u8}; use num_traits::Zero; fn append_endpoint_name_and_args( diff --git a/vm/src/vm_hooks/vh_handler/vh_storage.rs b/vm/src/vm_hooks/vh_handler/vh_storage.rs index 8d74b76fc9..21d386bab0 100644 --- a/vm/src/vm_hooks/vh_handler/vh_storage.rs +++ b/vm/src/vm_hooks/vh_handler/vh_storage.rs @@ -1,15 +1,5 @@ -#![allow(unused)] - -use crate::{ - num_bigint::{BigInt, Sign}, - tx_mock::{TxContextRef, TxPanic}, - types::VMAddress, - vm_hooks::VMHooksHandlerSource, -}; -use multiversx_sc::api::{ - BigIntApiImpl, ManagedBufferApiImpl, RawHandle, StorageReadApi, StorageReadApiImpl, - StorageWriteApi, StorageWriteApiImpl, -}; +use crate::{types::VMAddress, vm_hooks::VMHooksHandlerSource}; +use multiversx_sc::api::RawHandle; use super::VMHooksManagedTypes; From 8f646be7f988c7de98e63d26c2082d015319d8e7 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 16:38:20 +0300 Subject: [PATCH 05/14] vm - separate encode/decode --- .../esdt_nft/esdt_nft_add_quantity_mock.rs | 10 ++++++---- .../esdt_nft/esdt_nft_add_uri_mock.rs | 7 +++---- .../esdt_nft/esdt_nft_burn_mock.rs | 6 +++--- .../esdt_nft/esdt_nft_create_mock.rs | 8 ++++---- .../esdt_nft_update_attriutes_mock.rs | 6 +++--- .../transfer/esdt_multi_transfer_mock.rs | 11 +++++----- .../transfer/transfer_common.rs | 5 ++--- vm/src/tx_mock/tx_async_call_data.rs | 6 +++--- vm/src/types.rs | 20 +++++++++++++++++++ vm/src/vm_hooks/vh_handler/vh_send.rs | 16 +++++++-------- 10 files changed, 58 insertions(+), 37 deletions(-) diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs index c5f9d8993d..69845089f1 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs @@ -1,5 +1,7 @@ -use crate::num_bigint::BigUint; -use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; +use crate::{ + num_bigint::BigUint, + types::{top_decode_u64, top_encode_u64}, +}; use crate::{ tx_execution::builtin_function_names::ESDT_NFT_ADD_QUANTITY_FUNC_NAME, @@ -23,7 +25,7 @@ impl BuiltinFunction for ESDTNftAddQuantity { } let token_identifier = tx_input.args[0].clone(); - let nonce = u64::top_decode(tx_input.args[1].as_slice()).unwrap(); + let nonce = top_decode_u64(tx_input.args[1].as_slice()); let value = BigUint::from_bytes_be(tx_input.args[2].as_slice()); tx_cache.increase_esdt_balance( @@ -39,7 +41,7 @@ impl BuiltinFunction for ESDTNftAddQuantity { endpoint: ESDT_NFT_ADD_QUANTITY_FUNC_NAME.into(), topics: vec![ token_identifier.to_vec(), - top_encode_to_vec_u8(&nonce).unwrap(), + top_encode_u64(nonce), value.to_bytes_be(), ], data: vec![], diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs index 93ffd696ed..d9c2dfc803 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_uri_mock.rs @@ -1,8 +1,7 @@ -use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; - use crate::{ tx_execution::builtin_function_names::ESDT_NFT_ADD_URI_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, + types::{top_decode_u64, top_encode_u64}, }; use super::super::builtin_func_trait::BuiltinFunction; @@ -21,7 +20,7 @@ impl BuiltinFunction for ESDTNftAddUri { } let token_identifier = tx_input.args[0].clone(); - let nonce = u64::top_decode(tx_input.args[1].as_slice()).unwrap(); + let nonce = top_decode_u64(tx_input.args[1].as_slice()); let mut new_uris = tx_input.args[2..].to_vec(); tx_cache.with_account_mut(&tx_input.from, |account| { @@ -32,7 +31,7 @@ impl BuiltinFunction for ESDTNftAddUri { let mut topics = vec![ token_identifier.to_vec(), - top_encode_to_vec_u8(&nonce).unwrap(), + top_encode_u64(nonce), Vec::new(), // value = 0 ]; topics.append(&mut new_uris); diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs index 3e2615c028..5a4dc62fcd 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs @@ -2,8 +2,8 @@ use crate::{ num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_NFT_BURN_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, + types::{top_decode_u64, top_encode_u64}, }; -use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; @@ -21,7 +21,7 @@ impl BuiltinFunction for ESDTNftBurn { } let token_identifier = tx_input.args[0].clone(); - let nonce = u64::top_decode(tx_input.args[1].as_slice()).unwrap(); + let nonce = top_decode_u64(tx_input.args[1].as_slice()); let value = BigUint::from_bytes_be(tx_input.args[2].as_slice()); let subtract_result = @@ -35,7 +35,7 @@ impl BuiltinFunction for ESDTNftBurn { endpoint: ESDT_NFT_BURN_FUNC_NAME.into(), topics: vec![ token_identifier.to_vec(), - top_encode_to_vec_u8(&nonce).unwrap(), + top_encode_u64(nonce), value.to_bytes_be(), ], data: vec![], diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs index 9801e0e628..56d88aa53a 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs @@ -2,9 +2,9 @@ use crate::{ num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_NFT_CREATE_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, + types::{top_decode_u64, top_encode_u64}, world_mock::{EsdtInstance, EsdtInstanceMetadata}, }; -use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; @@ -28,7 +28,7 @@ impl BuiltinFunction for ESDTNftCreate { let token_identifier = tx_input.args[0].as_slice(); let amount = BigUint::from_bytes_be(tx_input.args[1].as_slice()); let name = tx_input.args[2].clone(); - let royalties = u64::top_decode(tx_input.args[3].as_slice()).unwrap(); + let royalties = top_decode_u64(tx_input.args[3].as_slice()); let hash = tx_input.args[4].clone(); let attributes = tx_input.args[5].clone(); let uris = tx_input.args[6..].to_vec(); @@ -60,7 +60,7 @@ impl BuiltinFunction for ESDTNftCreate { endpoint: ESDT_NFT_CREATE_FUNC_NAME.into(), topics: vec![ token_identifier.to_vec(), - top_encode_to_vec_u8(&new_nonce).unwrap(), + top_encode_u64(new_nonce), amount.to_bytes_be(), Vec::new(), // in actuality this should contain the fully marshalled ESDT data ], @@ -69,7 +69,7 @@ impl BuiltinFunction for ESDTNftCreate { let tx_result = TxResult { result_status: 0, - result_values: vec![top_encode_to_vec_u8(&new_nonce).unwrap()], + result_values: vec![top_encode_u64(new_nonce)], result_logs: vec![esdt_nft_create_log], ..Default::default() }; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs index ee7dac18b8..d509c25ad5 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_update_attriutes_mock.rs @@ -1,8 +1,8 @@ use crate::{ tx_execution::builtin_function_names::ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, + types::{top_decode_u64, top_encode_u64}, }; -use multiversx_sc::codec::{top_encode_to_vec_u8, TopDecode}; use super::super::builtin_func_trait::BuiltinFunction; @@ -20,7 +20,7 @@ impl BuiltinFunction for ESDTNftUpdateAttributes { } let token_identifier = tx_input.args[0].as_slice(); - let nonce = u64::top_decode(tx_input.args[1].as_slice()).unwrap(); + let nonce = top_decode_u64(tx_input.args[1].as_slice()); let attributes_bytes = tx_input.args[2].as_slice(); tx_cache.with_account_mut(&tx_input.from, |account| { @@ -34,7 +34,7 @@ impl BuiltinFunction for ESDTNftUpdateAttributes { endpoint: ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME.into(), topics: vec![ token_identifier.to_vec(), - top_encode_to_vec_u8(&nonce).unwrap(), + top_encode_u64(nonce), Vec::new(), // value = 0 attributes_bytes.to_vec(), ], diff --git a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs index 129ec79761..edb1c43b63 100644 --- a/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/transfer/esdt_multi_transfer_mock.rs @@ -1,5 +1,6 @@ -use crate::tx_execution::builtin_function_names::ESDT_MULTI_TRANSFER_FUNC_NAME; -use multiversx_sc::codec::TopDecode; +use crate::{ + tx_execution::builtin_function_names::ESDT_MULTI_TRANSFER_FUNC_NAME, types::top_decode_u64, +}; use crate::{ tx_execution::BuiltinFunctionEsdtTransferInfo, @@ -56,15 +57,15 @@ fn try_parse_input(tx_input: &TxInput) -> Result TxTokenTransfer { TxTokenTransfer { token_identifier: raw_esdt_transfer.token_identifier, - nonce: u64::top_decode(raw_esdt_transfer.nonce_bytes.as_slice()).unwrap(), + nonce: top_decode_u64(raw_esdt_transfer.nonce_bytes.as_slice()), value: BigUint::from_bytes_be(raw_esdt_transfer.value_bytes.as_slice()), } } diff --git a/vm/src/tx_mock/tx_async_call_data.rs b/vm/src/tx_mock/tx_async_call_data.rs index 07471c66d2..a0249e914f 100644 --- a/vm/src/tx_mock/tx_async_call_data.rs +++ b/vm/src/tx_mock/tx_async_call_data.rs @@ -1,7 +1,7 @@ use crate::{ tx_execution::BuiltinFunctionMap, tx_mock::{TxInput, TxResult}, - types::{VMAddress, H256}, + types::{top_encode_u64, VMAddress, H256}, }; use multiversx_sc::codec::*; @@ -38,7 +38,7 @@ fn result_status_bytes(result_status: u64) -> Vec { if result_status == 0 { vec![0x00] } else { - top_encode_to_vec_u8(&result_status).unwrap() + top_encode_u64(result_status) } } @@ -97,7 +97,7 @@ pub fn async_promise_tx_input( async_result: &TxResult, ) -> TxInput { let mut args: Vec> = Vec::new(); - let serialized_bytes = top_encode_to_vec_u8(&async_result.result_status).unwrap(); + let serialized_bytes = async_result.result_status.to_be_bytes().to_vec(); args.push(serialized_bytes); let callback_name = if async_result.result_status == 0 { args.extend_from_slice(async_result.result_values.as_slice()); diff --git a/vm/src/types.rs b/vm/src/types.rs index 231c0d7c6f..069fff2743 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -2,6 +2,26 @@ mod vm_address; mod vm_code_metadata; mod vm_h256; +use num_bigint::BigUint; +use num_traits::Zero; pub use vm_address::VMAddress; pub use vm_code_metadata::CodeMetadata; pub use vm_h256::H256; + +pub type RawHandle = i32; + +pub(crate) fn top_encode_u64(value: u64) -> Vec { + top_encode_big_uint(&BigUint::from(value)) +} + +pub(crate) fn top_encode_big_uint(value: &BigUint) -> Vec { + if value.is_zero() { + Vec::new() + } else { + value.to_bytes_be() + } +} + +pub(crate) fn top_decode_u64(bytes: &[u8]) -> u64 { + BigUint::from_bytes_be(bytes).try_into().unwrap() +} diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index 7ea9bcdde9..b03bbadc16 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -5,11 +5,11 @@ use crate::{ UPGRADE_CONTRACT_FUNC_NAME, }, tx_mock::{AsyncCallTxData, Promise, TxFunctionName, TxTokenTransfer}, - types::{CodeMetadata, VMAddress}, + types::{top_encode_big_uint, top_encode_u64, CodeMetadata, VMAddress}, vm_hooks::VMHooksHandlerSource, }; -use multiversx_sc::{api::RawHandle, codec::top_encode_to_vec_u8}; +use multiversx_sc::api::RawHandle; use num_traits::Zero; fn append_endpoint_name_and_args( @@ -59,8 +59,8 @@ pub trait VMHooksSend: VMHooksHandlerSource { let mut args = vec![ token, - top_encode_to_vec_u8(&nonce).unwrap(), - amount.to_bytes_be(), + top_encode_u64(nonce), + top_encode_big_uint(&amount), to.to_vec(), ]; @@ -84,14 +84,14 @@ pub trait VMHooksSend: VMHooksHandlerSource { ) { let contract_address = self.input_ref().to.clone(); - let mut args = vec![to.to_vec(), top_encode_to_vec_u8(&payments.len()).unwrap()]; + let mut args = vec![to.to_vec(), top_encode_u64(payments.len() as u64)]; for payment in payments.into_iter() { - let token_bytes = top_encode_to_vec_u8(&payment.token_identifier).unwrap(); + let token_bytes = payment.token_identifier; args.push(token_bytes); - let nonce_bytes = top_encode_to_vec_u8(&payment.nonce).unwrap(); + let nonce_bytes = top_encode_u64(payment.nonce); args.push(nonce_bytes); - let amount_bytes = top_encode_to_vec_u8(&payment.value).unwrap(); + let amount_bytes = top_encode_big_uint(&payment.value); args.push(amount_bytes); } From 2eb1e46c46c2399e0e6f9e3e008cb3c26ca0aadd Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 16:40:36 +0300 Subject: [PATCH 06/14] vm - HandleMap cleanup --- vm/src/tx_mock/tx_managed_types/handle_map.rs | 7 +------ vm/src/tx_mock/tx_managed_types/tx_big_int.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_managed_map.rs | 2 +- .../vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs | 6 +++--- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/vm/src/tx_mock/tx_managed_types/handle_map.rs b/vm/src/tx_mock/tx_managed_types/handle_map.rs index 3f1391f7a6..a9d6476daf 100644 --- a/vm/src/tx_mock/tx_managed_types/handle_map.rs +++ b/vm/src/tx_mock/tx_managed_types/handle_map.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::{use_raw_handle, HandleConstraints, RawHandle}; +use multiversx_sc::api::RawHandle; use std::collections::HashMap; #[derive(Debug)] @@ -30,11 +30,6 @@ impl HandleMap { new_handle } - pub fn insert_new_handle(&mut self, value: V) -> H { - let new_handle = self.insert_new_handle_raw(value); - use_raw_handle(new_handle) - } - pub fn get(&self, handle: RawHandle) -> &V { // TODO: consider simulating the actual error from the VM self.map diff --git a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs index 9a54e6c268..3306bf963f 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs @@ -8,7 +8,7 @@ use super::TxManagedTypes; impl TxManagedTypes { pub fn bi_new_from_big_int(&mut self, value: num_bigint::BigInt) -> RawHandle { - self.big_int_map.insert_new_handle(value) + self.big_int_map.insert_new_handle_raw(value) } pub fn bi_overwrite(&mut self, destination: RawHandle, value: num_bigint::BigInt) { diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index 462ddeecd3..b5fcec54e1 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -67,7 +67,7 @@ impl TxManagedTypes { } pub fn mb_new(&mut self, value: Vec) -> RawHandle { - self.managed_buffer_map.insert_new_handle(value) + self.managed_buffer_map.insert_new_handle_raw(value) } pub fn mb_update) -> R>(&mut self, handle: RawHandle, f: F) -> R { diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs index 168274fb08..b428c9875c 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs @@ -5,7 +5,7 @@ use super::{ManagedMapImpl, TxManagedTypes}; impl TxManagedTypes { pub fn mm_new(&mut self) -> RawHandle { self.managed_map_map - .insert_new_handle(ManagedMapImpl::new()) + .insert_new_handle_raw(ManagedMapImpl::new()) } pub fn mm_values_insert(&mut self, map_handle: RawHandle, key: Vec, value: Vec) { diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs index ea6e80b29d..e752a5f950 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs @@ -58,7 +58,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { } let mut managed_types = self.m_types_borrow_mut(); - managed_types.big_float_map.insert_new_handle(value) + managed_types.big_float_map.insert_new_handle_raw(value) } fn bf_from_frac(&self, numerator: i64, denominator: i64) -> RawHandle { @@ -74,7 +74,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { }; let mut managed_types = self.m_types_borrow_mut(); - managed_types.big_float_map.insert_new_handle(value) + managed_types.big_float_map.insert_new_handle_raw(value) } fn bf_from_sci(&self, significand: i64, exponent: i64) -> RawHandle { @@ -90,7 +90,7 @@ pub trait VMHooksBigFloat: VMHooksHandlerSource + VMHooksError { }; let mut managed_types = self.m_types_borrow_mut(); - managed_types.big_float_map.insert_new_handle(value) + managed_types.big_float_map.insert_new_handle_raw(value) } binary_op_method!(bf_add, add); From 084a968006525b6fadeb054ef90e44ad9a83c6f5 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 16:46:03 +0300 Subject: [PATCH 07/14] vm - separate RawHandle alias --- vm/src/tx_mock/tx_managed_types/handle_map.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_big_float.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_big_int.rs | 3 ++- vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs | 4 ++-- vm/src/tx_mock/tx_managed_types/tx_managed_map.rs | 2 +- vm/src/vm_hooks/vh_handler/vh_blockchain.rs | 7 ++----- vm/src/vm_hooks/vh_handler/vh_call_value.rs | 3 +-- vm/src/vm_hooks/vh_handler/vh_crypto.rs | 3 +-- vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs | 2 +- vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs | 2 +- vm/src/vm_hooks/vh_handler/vh_error.rs | 4 +--- vm/src/vm_hooks/vh_handler/vh_log.rs | 4 +--- vm/src/vm_hooks/vh_handler/vh_managed_types.rs | 2 +- .../vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs | 6 +++--- vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs | 3 ++- .../vh_handler/vh_managed_types/vh_managed_buffer.rs | 2 +- .../vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs | 3 +-- vm/src/vm_hooks/vh_handler/vh_send.rs | 4 +--- vm/src/vm_hooks/vh_handler/vh_storage.rs | 6 ++++-- 19 files changed, 28 insertions(+), 36 deletions(-) diff --git a/vm/src/tx_mock/tx_managed_types/handle_map.rs b/vm/src/tx_mock/tx_managed_types/handle_map.rs index a9d6476daf..62f9c04659 100644 --- a/vm/src/tx_mock/tx_managed_types/handle_map.rs +++ b/vm/src/tx_mock/tx_managed_types/handle_map.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use std::collections::HashMap; #[derive(Debug)] diff --git a/vm/src/tx_mock/tx_managed_types/tx_big_float.rs b/vm/src/tx_mock/tx_managed_types/tx_big_float.rs index d17478e880..5152ae9ada 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_big_float.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_big_float.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use super::TxManagedTypes; diff --git a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs index 3306bf963f..b4f0ec2dff 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs @@ -1,6 +1,7 @@ use std::cmp::Ordering; -use multiversx_sc::{api::RawHandle, types::BoxedBytes}; +use crate::types::RawHandle; +use multiversx_sc::types::BoxedBytes; use num_bigint::Sign; use num_traits::Zero; diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index b5fcec54e1..3a24439610 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -1,11 +1,11 @@ use multiversx_sc::{ - api::{handle_to_be_bytes, InvalidSliceError, RawHandle}, + api::{handle_to_be_bytes, InvalidSliceError}, types::BoxedBytes, }; use crate::{ tx_mock::{TxFunctionName, TxTokenTransfer}, - types::{CodeMetadata, VMAddress}, + types::{CodeMetadata, RawHandle, VMAddress}, }; use super::TxManagedTypes; diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs index b428c9875c..1a61d6de66 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_map.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use super::{ManagedMapImpl, TxManagedTypes}; diff --git a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs index c1837a3eaa..b117742a5a 100644 --- a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs +++ b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs @@ -1,13 +1,10 @@ use crate::{ num_bigint, - types::VMAddress, + types::{RawHandle, VMAddress}, vm_hooks::VMHooksHandlerSource, world_mock::{EsdtData, EsdtInstance}, }; -use multiversx_sc::{ - api::RawHandle, - types::{EsdtLocalRole, EsdtLocalRoleFlags}, -}; +use multiversx_sc::types::{EsdtLocalRole, EsdtLocalRoleFlags}; use num_bigint::BigInt; use num_traits::Zero; diff --git a/vm/src/vm_hooks/vh_handler/vh_call_value.rs b/vm/src/vm_hooks/vh_handler/vh_call_value.rs index a8d52091c2..877f72a4a0 100644 --- a/vm/src/vm_hooks/vh_handler/vh_call_value.rs +++ b/vm/src/vm_hooks/vh_handler/vh_call_value.rs @@ -1,5 +1,4 @@ -use crate::{num_bigint, vm_err_msg, vm_hooks::VMHooksHandlerSource}; -use multiversx_sc::api::RawHandle; +use crate::{num_bigint, types::RawHandle, vm_err_msg, vm_hooks::VMHooksHandlerSource}; use num_traits::Zero; use super::VMHooksManagedTypes; diff --git a/vm/src/vm_hooks/vh_handler/vh_crypto.rs b/vm/src/vm_hooks/vh_handler/vh_crypto.rs index c6071e9a93..f401a2942f 100644 --- a/vm/src/vm_hooks/vh_handler/vh_crypto.rs +++ b/vm/src/vm_hooks/vh_handler/vh_crypto.rs @@ -1,5 +1,4 @@ -use crate::{crypto_functions, vm_hooks::VMHooksHandlerSource}; -use multiversx_sc::api::RawHandle; +use crate::{crypto_functions, types::RawHandle, vm_hooks::VMHooksHandlerSource}; pub trait VMHooksCrypto: VMHooksHandlerSource { fn sha256_managed(&self, dest: RawHandle, data_handle: RawHandle) { diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs index c89101d69b..f072e1b880 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs @@ -3,7 +3,7 @@ use crate::{ vm_hooks::VMHooksHandlerSource, }; -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use num_traits::cast::ToPrimitive; use super::VMHooksManagedTypes; diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs index af0700532a..4f6db953f9 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs @@ -1,8 +1,8 @@ use crate::{ num_bigint::{BigInt, BigUint}, + types::RawHandle, vm_hooks::{VMHooksHandlerSource, VMHooksManagedTypes}, }; -use multiversx_sc::api::RawHandle; /// Interface to only be used by code generated by the macros. /// The smart contract code doesn't have access to these methods directly. diff --git a/vm/src/vm_hooks/vh_handler/vh_error.rs b/vm/src/vm_hooks/vh_handler/vh_error.rs index 68ea6f0819..93ef714ed8 100644 --- a/vm/src/vm_hooks/vh_handler/vh_error.rs +++ b/vm/src/vm_hooks/vh_handler/vh_error.rs @@ -1,6 +1,4 @@ -use multiversx_sc::api::RawHandle; - -use crate::vm_hooks::VMHooksHandlerSource; +use crate::{types::RawHandle, vm_hooks::VMHooksHandlerSource}; use super::VMHooksManagedTypes; diff --git a/vm/src/vm_hooks/vh_handler/vh_log.rs b/vm/src/vm_hooks/vh_handler/vh_log.rs index ed43e8a809..868df836e7 100644 --- a/vm/src/vm_hooks/vh_handler/vh_log.rs +++ b/vm/src/vm_hooks/vh_handler/vh_log.rs @@ -1,6 +1,4 @@ -use multiversx_sc::api::RawHandle; - -use crate::{tx_mock::TxLog, vm_hooks::VMHooksHandlerSource}; +use crate::{tx_mock::TxLog, types::RawHandle, vm_hooks::VMHooksHandlerSource}; pub trait VMHooksLog: VMHooksHandlerSource { fn managed_write_log(&self, topics_handle: RawHandle, data_handle: RawHandle) { diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs index 6cde65f57e..0985a5a15a 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs @@ -10,7 +10,7 @@ pub use vh_managed_map::VMHooksManagedMap; use std::fmt::Debug; -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use super::VMHooksError; diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs index e752a5f950..dd2637e863 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_float.rs @@ -1,4 +1,5 @@ use crate::{ + types::RawHandle, vm_err_msg, vm_hooks::{VMHooksError, VMHooksHandlerSource}, }; @@ -6,10 +7,9 @@ use core::{ cmp::Ordering, ops::{Add, Div, Mul, Neg, Sub}, }; -use std::convert::TryInto; - -use multiversx_sc::{api::RawHandle, codec::num_bigint::BigInt}; +use num_bigint::BigInt; use num_traits::ToPrimitive; +use std::convert::TryInto; macro_rules! binary_op_method { ($method_name:ident, $rust_op_name:ident) => { diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs index 64ef3918cf..9c9e57520b 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs @@ -1,6 +1,7 @@ use crate::{ num_bigint, tx_mock::big_int_to_i64, + types::RawHandle, vm_err_msg, vm_hooks::{VMHooksError, VMHooksHandlerSource}, }; @@ -8,7 +9,7 @@ use core::{ cmp::Ordering, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}, }; -use multiversx_sc::{api::RawHandle, types::heap::BoxedBytes}; +use multiversx_sc::types::heap::BoxedBytes; use num_traits::{pow, sign::Signed}; use std::convert::TryInto; diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs index ad8098da9a..70f1e69f08 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_buffer.rs @@ -1,4 +1,4 @@ -use multiversx_sc::api::RawHandle; +use crate::types::RawHandle; use crate::vm_hooks::VMHooksHandlerSource; diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs index bbe9614bb6..8d905afb38 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_managed_map.rs @@ -1,5 +1,4 @@ -use crate::vm_hooks::VMHooksHandlerSource; -use multiversx_sc::api::RawHandle; +use crate::{types::RawHandle, vm_hooks::VMHooksHandlerSource}; pub trait VMHooksManagedMap: VMHooksHandlerSource { fn mm_new(&self) -> RawHandle { diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index b03bbadc16..e1dc494b5d 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -5,11 +5,9 @@ use crate::{ UPGRADE_CONTRACT_FUNC_NAME, }, tx_mock::{AsyncCallTxData, Promise, TxFunctionName, TxTokenTransfer}, - types::{top_encode_big_uint, top_encode_u64, CodeMetadata, VMAddress}, + types::{top_encode_big_uint, top_encode_u64, CodeMetadata, RawHandle, VMAddress}, vm_hooks::VMHooksHandlerSource, }; - -use multiversx_sc::api::RawHandle; use num_traits::Zero; fn append_endpoint_name_and_args( diff --git a/vm/src/vm_hooks/vh_handler/vh_storage.rs b/vm/src/vm_hooks/vh_handler/vh_storage.rs index 21d386bab0..6787faec4f 100644 --- a/vm/src/vm_hooks/vh_handler/vh_storage.rs +++ b/vm/src/vm_hooks/vh_handler/vh_storage.rs @@ -1,5 +1,7 @@ -use crate::{types::VMAddress, vm_hooks::VMHooksHandlerSource}; -use multiversx_sc::api::RawHandle; +use crate::{ + types::{RawHandle, VMAddress}, + vm_hooks::VMHooksHandlerSource, +}; use super::VMHooksManagedTypes; From e33988f7aef59b51033a8158b7da3984b7dc327a Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 20:52:37 +0300 Subject: [PATCH 08/14] vm - separate display_util --- framework/scenario/src/display_util.rs | 30 +++++++++++++++++++++ framework/scenario/src/lib.rs | 1 + framework/scenario/tests/test_print_api.rs | 3 +-- vm/src/display_util.rs | 31 +--------------------- 4 files changed, 33 insertions(+), 32 deletions(-) create mode 100644 framework/scenario/src/display_util.rs diff --git a/framework/scenario/src/display_util.rs b/framework/scenario/src/display_util.rs new file mode 100644 index 0000000000..7f9444d7ca --- /dev/null +++ b/framework/scenario/src/display_util.rs @@ -0,0 +1,30 @@ +use crate::{num_bigint, num_bigint::BigInt}; +use multiversx_sc::{ + api::ManagedTypeApi, + types::{heap::BoxedBytes, BigUint, ManagedType}, +}; +use std::fmt; + +/// Only seems to be used in tests, we can probably remove it. +pub struct BigUintPrinter { + pub value: BigUint, +} + +impl fmt::Debug for BigUintPrinter { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let handle = self.value.get_handle(); + let mut bytes = self.value.to_bytes_be(); + if bytes.is_empty() { + bytes = BoxedBytes::from(vec![0u8]); + } + + let hex = hex::encode(bytes.as_slice()); + let dec = BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes.as_slice()); + + f.debug_struct("BigUint") + .field("handle", &handle) + .field("hex", &hex) + .field("dec", &dec.to_string()) + .finish() + } +} diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index cfb374d1aa..0cdfe1ec20 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -4,6 +4,7 @@ pub mod api; pub mod bech32; pub mod debug_executor; +pub mod display_util; mod facade; pub mod managed_test_util; pub mod scenario; diff --git a/framework/scenario/tests/test_print_api.rs b/framework/scenario/tests/test_print_api.rs index c7635d50a3..f61cb78ea1 100644 --- a/framework/scenario/tests/test_print_api.rs +++ b/framework/scenario/tests/test_print_api.rs @@ -1,6 +1,5 @@ -use multiversx_chain_vm::display_util::BigUintPrinter; use multiversx_sc::types::BigUint; -use multiversx_sc_scenario::api::StaticApi; +use multiversx_sc_scenario::{api::StaticApi, display_util::BigUintPrinter}; #[test] fn test_print_api() { diff --git a/vm/src/display_util.rs b/vm/src/display_util.rs index e8e6b8ae1e..c3aefd2aeb 100644 --- a/vm/src/display_util.rs +++ b/vm/src/display_util.rs @@ -1,14 +1,4 @@ -use crate::{num_bigint, num_bigint::BigInt, types::VMAddress}; -use alloc::string::String; -use multiversx_sc::{ - api::ManagedTypeApi, - types::{heap::BoxedBytes, BigUint, ManagedType}, -}; -use std::fmt; - -pub struct BigUintPrinter { - pub value: BigUint, -} +use crate::types::VMAddress; pub fn address_hex(address: &VMAddress) -> String { alloc::format!("0x{}", hex::encode(address.as_bytes())) @@ -39,22 +29,3 @@ pub fn verbose_hex_list(values: &[Vec]) -> String { pub fn bytes_to_string(bytes: &[u8]) -> String { String::from_utf8(bytes.to_vec()).unwrap_or_else(|_| verbose_hex(bytes)) } - -impl fmt::Debug for BigUintPrinter { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let handle = self.value.get_handle(); - let mut bytes = self.value.to_bytes_be(); - if bytes.is_empty() { - bytes = BoxedBytes::from(vec![0u8]); - } - - let hex = hex::encode(bytes.as_slice()); - let dec = BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes.as_slice()); - - f.debug_struct("BigUint") - .field("handle", &handle) - .field("hex", &hex) - .field("dec", &dec.to_string()) - .finish() - } -} From a19fb9194fdbf144e855f4aeb9144c175a8f6ebb Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 20:59:37 +0300 Subject: [PATCH 09/14] vm - removed BoxedBytes --- vm/src/lib.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_big_int.rs | 13 ++++++------- .../tx_mock/tx_managed_types/tx_managed_buffer.rs | 10 +++------- vm/src/types/vm_address.rs | 7 ------- vm/src/types/vm_h256.rs | 11 ----------- vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs | 4 ++-- vm/src/vm_hooks/vh_handler/vh_managed_types.rs | 10 ++++------ .../vh_handler/vh_managed_types/vh_big_int.rs | 6 ++---- 8 files changed, 18 insertions(+), 45 deletions(-) diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 2625c34df6..9fafe707af 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -11,7 +11,7 @@ pub mod world_mock; pub use world_mock::BlockchainMock; // Re-exporting for convenience. Using the crate as imported in the codec to make sure the save version is used everywhere. -pub use multiversx_sc::codec::num_bigint; +pub use num_bigint; // Re-exporting the executor, for convenience. pub use multiversx_chain_vm_executor as executor; diff --git a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs index b4f0ec2dff..510dee9a51 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs @@ -1,7 +1,6 @@ use std::cmp::Ordering; use crate::types::RawHandle; -use multiversx_sc::types::BoxedBytes; use num_bigint::Sign; use num_traits::Zero; @@ -31,13 +30,13 @@ impl TxManagedTypes { big_int_to_i64(&bi) } - pub fn bi_get_unsigned_bytes(&self, handle: RawHandle) -> BoxedBytes { + pub fn bi_get_unsigned_bytes(&self, handle: RawHandle) -> Vec { let bi = self.bi_get(handle); if bi.is_zero() { - BoxedBytes::empty() + Vec::new() } else { let (_, bytes) = bi.to_bytes_be(); - bytes.into() + bytes } } @@ -46,12 +45,12 @@ impl TxManagedTypes { self.bi_overwrite(destination, bi); } - pub fn bi_get_signed_bytes(&self, handle: RawHandle) -> BoxedBytes { + pub fn bi_get_signed_bytes(&self, handle: RawHandle) -> Vec { let bi = self.bi_get(handle); if bi.is_zero() { - BoxedBytes::empty() + Vec::new() } else { - bi.to_signed_bytes_be().into() + bi.to_signed_bytes_be() } } diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index 3a24439610..97d2ef0f04 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -1,7 +1,4 @@ -use multiversx_sc::{ - api::{handle_to_be_bytes, InvalidSliceError}, - types::BoxedBytes, -}; +use multiversx_sc::api::{handle_to_be_bytes, InvalidSliceError}; use crate::{ tx_mock::{TxFunctionName, TxTokenTransfer}, @@ -19,9 +16,8 @@ impl TxManagedTypes { self.managed_buffer_map.get(handle).len() } - pub fn mb_to_boxed_bytes(&self, handle: RawHandle) -> BoxedBytes { - let data = self.mb_get(handle); - data.into() + pub fn mb_to_bytes(&self, handle: RawHandle) -> Vec { + self.mb_get(handle).to_vec() } pub fn mb_to_address(&self, handle: RawHandle) -> VMAddress { diff --git a/vm/src/types/vm_address.rs b/vm/src/types/vm_address.rs index b555393ef8..3d0573742a 100644 --- a/vm/src/types/vm_address.rs +++ b/vm/src/types/vm_address.rs @@ -124,13 +124,6 @@ impl VMAddress { self.0.is_zero() } - // /// Transmutes self to an (in principle) variable length boxed bytes object. - // /// Both BoxedBytes and H256 keep the data on the heap, so only the pointer to that data needs to be transmuted. - // /// Does not reallocate or copy data, the data on the heap remains untouched. - // pub fn into_boxed_bytes(self) -> BoxedBytes { - // self.0.into_boxed_bytes() - // } - pub fn is_smart_contract_address(&self) -> bool { self.as_bytes() .iter() diff --git a/vm/src/types/vm_h256.rs b/vm/src/types/vm_h256.rs index ded66956e5..f85bc621d8 100644 --- a/vm/src/types/vm_h256.rs +++ b/vm/src/types/vm_h256.rs @@ -139,15 +139,4 @@ impl H256 { pub fn is_zero(&self) -> bool { self.as_bytes() == ZERO_32 } - - // /// Transmutes self to an (in principle) variable length boxed bytes object. - // /// Both BoxedBytes and H256 keep the data on the heap, so only the pointer to that data needs to be transmuted. - // /// Does not reallocate or copy data, the data on the heap remains untouched. - // pub fn into_boxed_bytes(self) -> BoxedBytes { - // let raw = Box::into_raw(self.0) as *mut u8; - // unsafe { - // let bytes_box = Box::<[u8]>::from_raw(core::slice::from_raw_parts_mut(raw, 32)); - // bytes_box.into() - // } - // } } diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs index 4f6db953f9..5de1cd1d9f 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs @@ -17,13 +17,13 @@ pub trait VMHooksEndpointFinish: VMHooksHandlerSource + VMHooksManagedTypes { fn finish_big_int_raw(&self, handle: RawHandle) { let bi_bytes = self.bi_get_signed_bytes(handle); let mut tx_result = self.result_borrow_mut(); - tx_result.result_values.push(bi_bytes.into_vec()); + tx_result.result_values.push(bi_bytes); } fn finish_big_uint_raw(&self, handle: RawHandle) { let bu_bytes = self.bi_get_unsigned_bytes(handle); let mut tx_result = self.result_borrow_mut(); - tx_result.result_values.push(bu_bytes.into_vec()); + tx_result.result_values.push(bu_bytes); } fn finish_managed_buffer_raw(&self, handle: RawHandle) { diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs index 0985a5a15a..fcf5e4f9a0 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs @@ -21,27 +21,25 @@ pub trait VMHooksManagedTypes: VMHooksBigInt + VMHooksManagedBuffer + VMHooksManagedMap + VMHooksBigFloat + VMHooksError + Debug { fn mb_to_big_int_unsigned(&self, buffer_handle: RawHandle, bi_handle: RawHandle) { - let bytes = self.m_types_borrow().mb_to_boxed_bytes(buffer_handle); + let bytes = self.m_types_borrow().mb_to_bytes(buffer_handle); self.m_types_borrow_mut() .bi_set_unsigned_bytes(bi_handle, bytes.as_slice()); } fn mb_to_big_int_signed(&self, buffer_handle: RawHandle, bi_handle: RawHandle) { - let bytes = self.m_types_borrow().mb_to_boxed_bytes(buffer_handle); + let bytes = self.m_types_borrow().mb_to_bytes(buffer_handle); self.m_types_borrow_mut() .bi_set_signed_bytes(bi_handle, bytes.as_slice()); } fn mb_from_big_int_unsigned(&self, buffer_handle: RawHandle, bi_handle: RawHandle) { let bi_bytes = self.m_types_borrow().bi_get_unsigned_bytes(bi_handle); - self.m_types_borrow_mut() - .mb_set(buffer_handle, bi_bytes.into_vec()); + self.m_types_borrow_mut().mb_set(buffer_handle, bi_bytes); } fn mb_from_big_int_signed(&self, buffer_handle: RawHandle, bi_handle: RawHandle) { let bi_bytes = self.m_types_borrow().bi_get_signed_bytes(bi_handle); - self.m_types_borrow_mut() - .mb_set(buffer_handle, bi_bytes.into_vec()); + self.m_types_borrow_mut().mb_set(buffer_handle, bi_bytes); } fn bi_to_string(&self, bi_handle: RawHandle, str_handle: RawHandle) { diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs index 9c9e57520b..a417d90269 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs @@ -9,8 +9,6 @@ use core::{ cmp::Ordering, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub}, }; -use multiversx_sc::types::heap::BoxedBytes; - use num_traits::{pow, sign::Signed}; use std::convert::TryInto; @@ -68,7 +66,7 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError { self.m_types_borrow().bi_get_unsigned_bytes(handle).len() } - fn bi_get_unsigned_bytes(&self, handle: RawHandle) -> BoxedBytes { + fn bi_get_unsigned_bytes(&self, handle: RawHandle) -> Vec { self.m_types_borrow().bi_get_unsigned_bytes(handle) } @@ -77,7 +75,7 @@ pub trait VMHooksBigInt: VMHooksHandlerSource + VMHooksError { .bi_set_unsigned_bytes(destination, bytes); } - fn bi_get_signed_bytes(&self, handle: RawHandle) -> BoxedBytes { + fn bi_get_signed_bytes(&self, handle: RawHandle) -> Vec { self.m_types_borrow().bi_get_signed_bytes(handle) } From 2b08f21a80f81631e3215934ac0482784dc6deab Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 21:14:38 +0300 Subject: [PATCH 10/14] vm - separate esdt roles --- vm/src/types.rs | 4 + vm/src/types/vm_esdt_local_role.rs | 134 ++++++++++++++++++++ vm/src/types/vm_esdt_local_role_flags.rs | 70 ++++++++++ vm/src/vm_hooks/vh_handler/vh_blockchain.rs | 3 +- 4 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 vm/src/types/vm_esdt_local_role.rs create mode 100644 vm/src/types/vm_esdt_local_role_flags.rs diff --git a/vm/src/types.rs b/vm/src/types.rs index 069fff2743..6bca05ad90 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -1,11 +1,15 @@ mod vm_address; mod vm_code_metadata; +mod vm_esdt_local_role; +mod vm_esdt_local_role_flags; mod vm_h256; use num_bigint::BigUint; use num_traits::Zero; pub use vm_address::VMAddress; pub use vm_code_metadata::CodeMetadata; +pub use vm_esdt_local_role::EsdtLocalRole; +pub use vm_esdt_local_role_flags::EsdtLocalRoleFlags; pub use vm_h256::H256; pub type RawHandle = i32; diff --git a/vm/src/types/vm_esdt_local_role.rs b/vm/src/types/vm_esdt_local_role.rs new file mode 100644 index 0000000000..eb6cd0c565 --- /dev/null +++ b/vm/src/types/vm_esdt_local_role.rs @@ -0,0 +1,134 @@ +use super::EsdtLocalRoleFlags; + +static ESDT_ROLE_NONE: &[u8] = &[]; +static ESDT_ROLE_LOCAL_MINT: &[u8] = b"ESDTRoleLocalMint"; +static ESDT_ROLE_LOCAL_BURN: &[u8] = b"ESDTRoleLocalBurn"; +static ESDT_ROLE_NFT_CREATE: &[u8] = b"ESDTRoleNFTCreate"; +static ESDT_ROLE_NFT_ADD_QUANTITY: &[u8] = b"ESDTRoleNFTAddQuantity"; +static ESDT_ROLE_NFT_BURN: &[u8] = b"ESDTRoleNFTBurn"; +static ESDT_ROLE_NFT_ADD_URI: &[u8] = b"ESDTRoleNFTAddURI"; +static ESDT_ROLE_NFT_UPDATE_ATTRIBUTES: &[u8] = b"ESDTRoleNFTUpdateAttributes"; +static ESDT_ROLE_TRANSFER: &[u8] = b"ESDTTransferRole"; + +/// The VM implementation for EsdtLocalRole, used internally in builtin functions. +/// +/// There is another near-identical implementation in the framework, used for communicating with the VM. +/// +/// It might be a good idea to move it to some "common ground" crate, between the framework and the VM. +#[derive(Clone, PartialEq, Eq, Debug, Copy)] +pub enum EsdtLocalRole { + None, + Mint, + Burn, + NftCreate, + NftAddQuantity, + NftBurn, + NftAddUri, + NftUpdateAttributes, + Transfer, +} + +impl EsdtLocalRole { + pub fn as_u16(&self) -> u16 { + match self { + Self::None => 0, + Self::Mint => 1, + Self::Burn => 2, + Self::NftCreate => 3, + Self::NftAddQuantity => 4, + Self::NftBurn => 5, + Self::NftAddUri => 6, + Self::NftUpdateAttributes => 7, + Self::Transfer => 8, + } + } + + pub fn as_role_name(&self) -> &'static [u8] { + match self { + Self::None => ESDT_ROLE_NONE, + Self::Mint => ESDT_ROLE_LOCAL_MINT, + Self::Burn => ESDT_ROLE_LOCAL_BURN, + Self::NftCreate => ESDT_ROLE_NFT_CREATE, + Self::NftAddQuantity => ESDT_ROLE_NFT_ADD_QUANTITY, + Self::NftBurn => ESDT_ROLE_NFT_BURN, + Self::NftAddUri => ESDT_ROLE_NFT_ADD_URI, + Self::NftUpdateAttributes => ESDT_ROLE_NFT_UPDATE_ATTRIBUTES, + Self::Transfer => ESDT_ROLE_TRANSFER, + } + } + + pub fn to_flag(&self) -> EsdtLocalRoleFlags { + match self { + Self::None => EsdtLocalRoleFlags::NONE, + Self::Mint => EsdtLocalRoleFlags::MINT, + Self::Burn => EsdtLocalRoleFlags::BURN, + Self::NftCreate => EsdtLocalRoleFlags::NFT_CREATE, + Self::NftAddQuantity => EsdtLocalRoleFlags::NFT_ADD_QUANTITY, + Self::NftBurn => EsdtLocalRoleFlags::NFT_BURN, + Self::NftAddUri => EsdtLocalRoleFlags::NFT_ADD_URI, + Self::NftUpdateAttributes => EsdtLocalRoleFlags::NFT_UPDATE_ATTRIBUTES, + Self::Transfer => EsdtLocalRoleFlags::TRANSFER, + } + } +} + +// TODO: can be done with macros, but I didn't find a public library that does it and is no_std +// we can implement it, it's easy +const ALL_ROLES: [EsdtLocalRole; 8] = [ + EsdtLocalRole::Mint, + EsdtLocalRole::Burn, + EsdtLocalRole::NftCreate, + EsdtLocalRole::NftAddQuantity, + EsdtLocalRole::NftBurn, + EsdtLocalRole::NftAddUri, + EsdtLocalRole::NftUpdateAttributes, + EsdtLocalRole::Transfer, +]; + +impl EsdtLocalRole { + pub fn iter_all() -> core::slice::Iter<'static, EsdtLocalRole> { + ALL_ROLES.iter() + } +} + +impl From for EsdtLocalRole { + #[inline] + fn from(value: u16) -> Self { + match value { + 1 => Self::Mint, + 2 => Self::Burn, + 3 => Self::NftCreate, + 4 => Self::NftAddQuantity, + 5 => Self::NftBurn, + 6 => Self::NftAddUri, + 7 => Self::NftUpdateAttributes, + 8 => Self::Transfer, + _ => Self::None, + } + } +} + +impl<'a> From<&'a [u8]> for EsdtLocalRole { + #[inline] + fn from(byte_slice: &'a [u8]) -> Self { + if byte_slice == ESDT_ROLE_LOCAL_MINT { + Self::Mint + } else if byte_slice == ESDT_ROLE_LOCAL_BURN { + Self::Burn + } else if byte_slice == ESDT_ROLE_NFT_CREATE { + Self::NftCreate + } else if byte_slice == ESDT_ROLE_NFT_ADD_QUANTITY { + Self::NftAddQuantity + } else if byte_slice == ESDT_ROLE_NFT_BURN { + Self::NftBurn + } else if byte_slice == ESDT_ROLE_NFT_ADD_URI { + Self::NftAddUri + } else if byte_slice == ESDT_ROLE_NFT_UPDATE_ATTRIBUTES { + Self::NftUpdateAttributes + } else if byte_slice == ESDT_ROLE_TRANSFER { + Self::Transfer + } else { + Self::None + } + } +} diff --git a/vm/src/types/vm_esdt_local_role_flags.rs b/vm/src/types/vm_esdt_local_role_flags.rs new file mode 100644 index 0000000000..87f154a94f --- /dev/null +++ b/vm/src/types/vm_esdt_local_role_flags.rs @@ -0,0 +1,70 @@ +use super::EsdtLocalRole; +use bitflags::bitflags; + +bitflags! { + /// The VM implementation for EsdtLocalRoleFlags, used internally in builtin functions. + /// + /// There is another near-identical implementation in the framework, used for communicating with the VM. + /// + /// It might be a good idea to move it to some "common ground" crate, between the framework and the VM. + pub struct EsdtLocalRoleFlags: u64 { + const NONE = 0b00000000; + const MINT = 0b00000001; + const BURN = 0b00000010; + const NFT_CREATE = 0b00000100; + const NFT_ADD_QUANTITY = 0b00001000; + const NFT_BURN = 0b00010000; + const NFT_ADD_URI = 0b00100000; + const NFT_UPDATE_ATTRIBUTES = 0b01000000; + const TRANSFER = 0b10000000; + } +} + +impl EsdtLocalRoleFlags { + pub fn has_role(&self, role: &EsdtLocalRole) -> bool { + *self & role.to_flag() != EsdtLocalRoleFlags::NONE + } + + pub fn iter_roles(&self) -> impl Iterator { + EsdtLocalRole::iter_all().filter(move |role| self.has_role(role)) + } +} + +#[cfg(test)] +pub mod tests { + use super::*; + use alloc::vec::Vec; + + #[test] + fn test_flags_has_role() { + let flags = EsdtLocalRoleFlags::MINT; + assert!(flags.has_role(&EsdtLocalRole::Mint)); + let flags = EsdtLocalRoleFlags::MINT | EsdtLocalRoleFlags::BURN; + assert!(flags.has_role(&EsdtLocalRole::Mint)); + let flags = EsdtLocalRoleFlags::NONE; + assert!(!flags.has_role(&EsdtLocalRole::Mint)); + let flags = EsdtLocalRoleFlags::BURN; + assert!(!flags.has_role(&EsdtLocalRole::Mint)); + } + + #[test] + fn test_flags_iter_role() { + let flags = EsdtLocalRoleFlags::MINT; + assert_eq!( + flags.iter_roles().collect::>(), + alloc::vec![&EsdtLocalRole::Mint], + ); + + let flags = EsdtLocalRoleFlags::MINT | EsdtLocalRoleFlags::BURN; + assert_eq!( + flags.iter_roles().collect::>(), + alloc::vec![&EsdtLocalRole::Mint, &EsdtLocalRole::Burn], + ); + + let flags = EsdtLocalRoleFlags::NONE; + assert_eq!( + flags.iter_roles().collect::>(), + Vec::<&EsdtLocalRole>::new(), + ); + } +} diff --git a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs index b117742a5a..8d129c9710 100644 --- a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs +++ b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs @@ -1,10 +1,9 @@ use crate::{ num_bigint, - types::{RawHandle, VMAddress}, + types::{EsdtLocalRole, EsdtLocalRoleFlags, RawHandle, VMAddress}, vm_hooks::VMHooksHandlerSource, world_mock::{EsdtData, EsdtInstance}, }; -use multiversx_sc::types::{EsdtLocalRole, EsdtLocalRoleFlags}; use num_bigint::BigInt; use num_traits::Zero; From fb9c59639bcc45de83558902dca6bf4a1dbe49f8 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 21:25:56 +0300 Subject: [PATCH 11/14] vm - removed BigUint re-export --- vm/src/lib.rs | 3 --- .../builtin_function_mocks/esdt_nft/esdt_local_burn.rs | 7 +++++-- .../builtin_function_mocks/esdt_nft/esdt_local_mint.rs | 4 +++- .../esdt_nft/esdt_nft_add_quantity_mock.rs | 7 +++---- .../esdt_nft/esdt_nft_burn_mock.rs | 3 ++- .../esdt_nft/esdt_nft_create_mock.rs | 3 ++- vm/src/tx_mock/tx_async_call_data.rs | 3 +-- vm/src/tx_mock/tx_cache_balance_util.rs | 6 +++--- vm/src/tx_mock/tx_context.rs | 2 +- vm/src/tx_mock/tx_input.rs | 5 +++-- vm/src/tx_mock/tx_managed_types.rs | 2 +- vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs | 10 ++++++++-- vm/src/vm_hooks/vh_handler/vh_blockchain.rs | 1 - vm/src/vm_hooks/vh_handler/vh_call_value.rs | 2 +- vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs | 9 ++++----- vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs | 3 ++- .../vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs | 1 - vm/src/vm_hooks/vh_handler/vh_send.rs | 1 - vm/src/world_mock/account_data.rs | 4 +++- vm/src/world_mock/blockchain_mock.rs | 2 +- vm/src/world_mock/blockchain_tx_info.rs | 4 +++- vm/src/world_mock/esdt_data.rs | 4 +++- vm/src/world_mock/esdt_instance.rs | 2 +- vm/src/world_mock/esdt_instances.rs | 3 ++- 24 files changed, 52 insertions(+), 39 deletions(-) diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 9fafe707af..742a308e5f 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -10,9 +10,6 @@ pub mod world_mock; pub use world_mock::BlockchainMock; -// Re-exporting for convenience. Using the crate as imported in the codec to make sure the save version is used everywhere. -pub use num_bigint; - // Re-exporting the executor, for convenience. pub use multiversx_chain_vm_executor as executor; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs index 5b587ae4d8..4ab8da8016 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_burn.rs @@ -1,6 +1,9 @@ -use crate::{num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_LOCAL_BURN_FUNC_NAME}; +use num_bigint::BigUint; -use crate::tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}; +use crate::{ + tx_execution::builtin_function_names::ESDT_LOCAL_BURN_FUNC_NAME, + tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, +}; use super::super::builtin_func_trait::BuiltinFunction; diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs index 2d076d31b5..8bd0ef6dc0 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_local_mint.rs @@ -1,4 +1,6 @@ -use crate::{num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_LOCAL_MINT_FUNC_NAME}; +use num_bigint::BigUint; + +use crate::tx_execution::builtin_function_names::ESDT_LOCAL_MINT_FUNC_NAME; use crate::{ tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs index 69845089f1..4179bfa21e 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_add_quantity_mock.rs @@ -1,7 +1,6 @@ -use crate::{ - num_bigint::BigUint, - types::{top_decode_u64, top_encode_u64}, -}; +use num_bigint::BigUint; + +use crate::types::{top_decode_u64, top_encode_u64}; use crate::{ tx_execution::builtin_function_names::ESDT_NFT_ADD_QUANTITY_FUNC_NAME, diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs index 5a4dc62fcd..595054c7c4 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_burn_mock.rs @@ -1,5 +1,6 @@ +use num_bigint::BigUint; + use crate::{ - num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_NFT_BURN_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, types::{top_decode_u64, top_encode_u64}, diff --git a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs index 56d88aa53a..1c5d65d43d 100644 --- a/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs +++ b/vm/src/tx_execution/builtin_function_mocks/esdt_nft/esdt_nft_create_mock.rs @@ -1,5 +1,6 @@ +use num_bigint::BigUint; + use crate::{ - num_bigint::BigUint, tx_execution::builtin_function_names::ESDT_NFT_CREATE_FUNC_NAME, tx_mock::{BlockchainUpdate, TxCache, TxInput, TxLog, TxResult}, types::{top_decode_u64, top_encode_u64}, diff --git a/vm/src/tx_mock/tx_async_call_data.rs b/vm/src/tx_mock/tx_async_call_data.rs index a0249e914f..4ee37cdc7c 100644 --- a/vm/src/tx_mock/tx_async_call_data.rs +++ b/vm/src/tx_mock/tx_async_call_data.rs @@ -3,9 +3,8 @@ use crate::{ tx_mock::{TxInput, TxResult}, types::{top_encode_u64, VMAddress, H256}, }; -use multiversx_sc::codec::*; -use crate::num_bigint::BigUint; +use num_bigint::BigUint; use super::{CallbackPayments, Promise, TxFunctionName}; diff --git a/vm/src/tx_mock/tx_cache_balance_util.rs b/vm/src/tx_mock/tx_cache_balance_util.rs index 5ac5ab603e..72d300cdd5 100644 --- a/vm/src/tx_mock/tx_cache_balance_util.rs +++ b/vm/src/tx_mock/tx_cache_balance_util.rs @@ -1,6 +1,6 @@ -use crate::{ - num_bigint::BigUint, tx_mock::TxPanic, types::VMAddress, world_mock::EsdtInstanceMetadata, -}; +use num_bigint::BigUint; + +use crate::{tx_mock::TxPanic, types::VMAddress, world_mock::EsdtInstanceMetadata}; use super::TxCache; diff --git a/vm/src/tx_mock/tx_context.rs b/vm/src/tx_mock/tx_context.rs index 19edc2043a..75ea9f1eb5 100644 --- a/vm/src/tx_mock/tx_context.rs +++ b/vm/src/tx_mock/tx_context.rs @@ -1,9 +1,9 @@ use crate::{ - num_bigint::BigUint, types::VMAddress, world_mock::{AccountData, AccountEsdt, BlockchainMock, FailingExecutor}, }; use core::cell::RefCell; +use num_bigint::BigUint; use num_traits::Zero; use std::{ cell::{Ref, RefMut}, diff --git a/vm/src/tx_mock/tx_input.rs b/vm/src/tx_mock/tx_input.rs index ebc92a164b..cf16bbab8e 100644 --- a/vm/src/tx_mock/tx_input.rs +++ b/vm/src/tx_mock/tx_input.rs @@ -1,9 +1,10 @@ +use num_bigint::BigUint; +use num_traits::Zero; + use crate::{ display_util::*, - num_bigint::BigUint, types::{VMAddress, H256}, }; -use num_traits::Zero; use std::fmt; use super::TxFunctionName; diff --git a/vm/src/tx_mock/tx_managed_types.rs b/vm/src/tx_mock/tx_managed_types.rs index 197d31d187..d95f05b562 100644 --- a/vm/src/tx_mock/tx_managed_types.rs +++ b/vm/src/tx_mock/tx_managed_types.rs @@ -5,9 +5,9 @@ mod tx_managed_buffer; mod tx_managed_map; pub use handle_map::HandleMap; +use num_bigint::BigInt; pub use tx_big_int::big_int_to_i64; -use crate::num_bigint::BigInt; use std::collections::HashMap; pub(crate) type ManagedBufferImpl = Vec; diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index 97d2ef0f04..6ee0935e97 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -1,5 +1,3 @@ -use multiversx_sc::api::{handle_to_be_bytes, InvalidSliceError}; - use crate::{ tx_mock::{TxFunctionName, TxTokenTransfer}, types::{CodeMetadata, RawHandle, VMAddress}, @@ -7,6 +5,10 @@ use crate::{ use super::TxManagedTypes; +/// Returned if load/copy slice could not be performed. +/// No further data needed. +pub struct InvalidSliceError; + impl TxManagedTypes { pub fn mb_get(&self, handle: RawHandle) -> &[u8] { self.managed_buffer_map.get(handle).as_slice() @@ -165,6 +167,10 @@ impl TxManagedTypes { } } +pub fn handle_to_be_bytes(handle: RawHandle) -> [u8; 4] { + handle.to_be_bytes() +} + #[cfg(test)] pub mod tests { use super::*; diff --git a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs index 8d129c9710..aac0f88aa6 100644 --- a/vm/src/vm_hooks/vh_handler/vh_blockchain.rs +++ b/vm/src/vm_hooks/vh_handler/vh_blockchain.rs @@ -1,5 +1,4 @@ use crate::{ - num_bigint, types::{EsdtLocalRole, EsdtLocalRoleFlags, RawHandle, VMAddress}, vm_hooks::VMHooksHandlerSource, world_mock::{EsdtData, EsdtInstance}, diff --git a/vm/src/vm_hooks/vh_handler/vh_call_value.rs b/vm/src/vm_hooks/vh_handler/vh_call_value.rs index 877f72a4a0..c310054643 100644 --- a/vm/src/vm_hooks/vh_handler/vh_call_value.rs +++ b/vm/src/vm_hooks/vh_handler/vh_call_value.rs @@ -1,4 +1,4 @@ -use crate::{num_bigint, types::RawHandle, vm_err_msg, vm_hooks::VMHooksHandlerSource}; +use crate::{types::RawHandle, vm_err_msg, vm_hooks::VMHooksHandlerSource}; use num_traits::Zero; use super::VMHooksManagedTypes; diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs index f072e1b880..38a6c27328 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_arg.rs @@ -1,10 +1,9 @@ -use crate::{ - num_bigint::{BigInt, BigUint}, - vm_hooks::VMHooksHandlerSource, -}; +use num_bigint::{BigInt, BigUint}; +use num_traits::ToPrimitive; + +use crate::vm_hooks::VMHooksHandlerSource; use crate::types::RawHandle; -use num_traits::cast::ToPrimitive; use super::VMHooksManagedTypes; diff --git a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs index 5de1cd1d9f..ebb8a73385 100644 --- a/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs +++ b/vm/src/vm_hooks/vh_handler/vh_endpoint_finish.rs @@ -1,5 +1,6 @@ +use num_bigint::{BigInt, BigUint}; + use crate::{ - num_bigint::{BigInt, BigUint}, types::RawHandle, vm_hooks::{VMHooksHandlerSource, VMHooksManagedTypes}, }; diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs index a417d90269..9ddb67874d 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types/vh_big_int.rs @@ -1,5 +1,4 @@ use crate::{ - num_bigint, tx_mock::big_int_to_i64, types::RawHandle, vm_err_msg, diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index e1dc494b5d..6aae5fe1b9 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -1,5 +1,4 @@ use crate::{ - num_bigint, tx_execution::builtin_function_names::{ ESDT_MULTI_TRANSFER_FUNC_NAME, ESDT_NFT_TRANSFER_FUNC_NAME, ESDT_TRANSFER_FUNC_NAME, UPGRADE_CONTRACT_FUNC_NAME, diff --git a/vm/src/world_mock/account_data.rs b/vm/src/world_mock/account_data.rs index ce16f70175..3af2686624 100644 --- a/vm/src/world_mock/account_data.rs +++ b/vm/src/world_mock/account_data.rs @@ -1,5 +1,7 @@ +use num_bigint::BigUint; + use super::AccountEsdt; -use crate::{display_util::key_hex, num_bigint::BigUint, types::VMAddress}; +use crate::{display_util::key_hex, types::VMAddress}; use std::{collections::HashMap, fmt, fmt::Write}; pub const STORAGE_RESERVED_PREFIX: &[u8] = b"ELROND"; diff --git a/vm/src/world_mock/blockchain_mock.rs b/vm/src/world_mock/blockchain_mock.rs index 2c67da1945..cd2549e288 100644 --- a/vm/src/world_mock/blockchain_mock.rs +++ b/vm/src/world_mock/blockchain_mock.rs @@ -1,10 +1,10 @@ use crate::{ - num_bigint::BigUint, tx_execution::{init_builtin_functions, BuiltinFunctionMap}, tx_mock::BlockchainUpdate, types::VMAddress, }; use multiversx_chain_vm_executor::Executor; +use num_bigint::BigUint; use num_traits::Zero; use std::{collections::HashMap, fmt::Debug, rc::Rc}; diff --git a/vm/src/world_mock/blockchain_tx_info.rs b/vm/src/world_mock/blockchain_tx_info.rs index 5e4f62b47a..5dad717531 100644 --- a/vm/src/world_mock/blockchain_tx_info.rs +++ b/vm/src/world_mock/blockchain_tx_info.rs @@ -1,4 +1,6 @@ -use crate::{num_bigint::BigUint, types::VMAddress}; +use num_bigint::BigUint; + +use crate::types::VMAddress; use super::{AccountEsdt, BlockInfo, BlockchainMock}; diff --git a/vm/src/world_mock/esdt_data.rs b/vm/src/world_mock/esdt_data.rs index 54d932ec49..3155a62408 100644 --- a/vm/src/world_mock/esdt_data.rs +++ b/vm/src/world_mock/esdt_data.rs @@ -1,5 +1,7 @@ -use crate::{display_util::key_hex, num_bigint::BigUint}; +use num_bigint::BigUint; use num_traits::Zero; + +use crate::display_util::key_hex; use std::{ collections::{hash_map::Iter, HashMap}, fmt::{self, Write}, diff --git a/vm/src/world_mock/esdt_instance.rs b/vm/src/world_mock/esdt_instance.rs index d0716da012..269d6645ba 100644 --- a/vm/src/world_mock/esdt_instance.rs +++ b/vm/src/world_mock/esdt_instance.rs @@ -1,4 +1,4 @@ -use crate::num_bigint::BigUint; +use num_bigint::BigUint; use num_traits::Zero; use super::EsdtInstanceMetadata; diff --git a/vm/src/world_mock/esdt_instances.rs b/vm/src/world_mock/esdt_instances.rs index 5b3db46598..7ebe03d5a1 100644 --- a/vm/src/world_mock/esdt_instances.rs +++ b/vm/src/world_mock/esdt_instances.rs @@ -1,5 +1,6 @@ use super::{EsdtInstance, EsdtInstanceMetadata}; -use crate::{display_util::verbose_hex_list, num_bigint::BigUint}; +use crate::display_util::verbose_hex_list; +use num_bigint::BigUint; use num_traits::Zero; use std::{ collections::BTreeMap, From 480c69ea71641988e218de3893cb4dc484a83b42 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 21:26:13 +0300 Subject: [PATCH 12/14] vm - removed dependency to framework --- vm/Cargo.toml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 2a8e856abb..f76841b320 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -28,10 +28,5 @@ ed25519-dalek = "1.0.1" itertools = "0.10.3" bitflags = "1.3.2" -[dependencies.multiversx-sc] -version = "=0.41.0" -path = "../framework/base" -features = ["alloc", "num-bigint", "promises", "big-float"] - [dependencies.multiversx-chain-vm-executor] version = "0.1.0" From 274d57cc77ea5dbb895aec7c26717e6a7a1d1ec7 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Tue, 27 Jun 2023 21:50:24 +0300 Subject: [PATCH 13/14] re-export fix --- framework/scenario/src/lib.rs | 5 ++++- framework/scenario/src/whitebox/contract_obj_wrapper.rs | 1 - framework/scenario/src/whitebox/raw_converter.rs | 1 - framework/scenario/src/whitebox/tx_mandos.rs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/framework/scenario/src/lib.rs b/framework/scenario/src/lib.rs index 0cdfe1ec20..cadf6a44d0 100644 --- a/framework/scenario/src/lib.rs +++ b/framework/scenario/src/lib.rs @@ -18,7 +18,10 @@ pub mod whitebox; pub use whitebox as testing_framework; pub use api::DebugApi; -pub use multiversx_chain_vm::{self, num_bigint}; +pub use multiversx_chain_vm; + +/// Re-exporting for convenience. +pub use num_bigint; pub use multiversx_sc; diff --git a/framework/scenario/src/whitebox/contract_obj_wrapper.rs b/framework/scenario/src/whitebox/contract_obj_wrapper.rs index 5f136e6496..5799fae0d6 100644 --- a/framework/scenario/src/whitebox/contract_obj_wrapper.rs +++ b/framework/scenario/src/whitebox/contract_obj_wrapper.rs @@ -11,7 +11,6 @@ use crate::{ testing_framework::raw_converter::bytes_to_hex, }; use multiversx_chain_vm::{ - num_bigint, tx_execution::execute_async_call_and_callback, tx_mock::{ TxCache, TxContext, TxContextRef, TxContextStack, TxFunctionName, TxInput, TxResult, diff --git a/framework/scenario/src/whitebox/raw_converter.rs b/framework/scenario/src/whitebox/raw_converter.rs index 855dae2a6c..b65477aa72 100644 --- a/framework/scenario/src/whitebox/raw_converter.rs +++ b/framework/scenario/src/whitebox/raw_converter.rs @@ -11,7 +11,6 @@ use crate::{ }, }; use multiversx_chain_vm::{ - num_bigint, types::VMAddress, world_mock::{AccountData, BlockInfo, EsdtData}, }; diff --git a/framework/scenario/src/whitebox/tx_mandos.rs b/framework/scenario/src/whitebox/tx_mandos.rs index be513208d3..6d7babb5ba 100644 --- a/framework/scenario/src/whitebox/tx_mandos.rs +++ b/framework/scenario/src/whitebox/tx_mandos.rs @@ -2,7 +2,7 @@ use crate::multiversx_sc::{ codec::{top_encode_to_vec_u8_or_panic, TopEncode}, types::heap::Address, }; -use multiversx_chain_vm::{num_bigint, tx_mock::TxTokenTransfer}; +use multiversx_chain_vm::tx_mock::TxTokenTransfer; use num_traits::Zero; pub struct ScCallMandos { From 13af92e69e0c9b1ff06aab9376729009b507fb36 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Wed, 28 Jun 2023 19:52:33 +0300 Subject: [PATCH 14/14] cleanup, docs --- .../tx_managed_types/tx_managed_buffer.rs | 6 +- vm/src/types.rs | 2 +- vm/src/types/vm_address.rs | 32 +------ vm/src/types/vm_code_metadata.rs | 96 +++++++++---------- vm/src/types/vm_h256.rs | 34 ------- vm/src/vm_hooks/vh_debugger_stack.rs | 4 +- vm/src/vm_hooks/vh_handler/vh_send.rs | 4 +- vm/src/vm_hooks/vh_managed_types_cell.rs | 4 +- vm/src/vm_hooks/vh_source.rs | 4 +- 9 files changed, 60 insertions(+), 126 deletions(-) diff --git a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs index 6ee0935e97..ba43dde71f 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_managed_buffer.rs @@ -1,6 +1,6 @@ use crate::{ tx_mock::{TxFunctionName, TxTokenTransfer}, - types::{CodeMetadata, RawHandle, VMAddress}, + types::{RawHandle, VMAddress, VMCodeMetadata}, }; use super::TxManagedTypes; @@ -30,9 +30,9 @@ impl TxManagedTypes { TxFunctionName::from(self.mb_get(handle)) } - pub fn mb_to_code_metadata(&self, handle: RawHandle) -> CodeMetadata { + pub fn mb_to_code_metadata(&self, handle: RawHandle) -> VMCodeMetadata { let bytes: [u8; 2] = self.mb_get(handle).try_into().unwrap(); - CodeMetadata::from(bytes) + VMCodeMetadata::from(bytes) } pub fn mb_get_slice( diff --git a/vm/src/types.rs b/vm/src/types.rs index 6bca05ad90..c242d61cd2 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -7,7 +7,7 @@ mod vm_h256; use num_bigint::BigUint; use num_traits::Zero; pub use vm_address::VMAddress; -pub use vm_code_metadata::CodeMetadata; +pub use vm_code_metadata::VMCodeMetadata; pub use vm_esdt_local_role::EsdtLocalRole; pub use vm_esdt_local_role_flags::EsdtLocalRoleFlags; pub use vm_h256::H256; diff --git a/vm/src/types/vm_address.rs b/vm/src/types/vm_address.rs index 3d0573742a..944e3b14bf 100644 --- a/vm/src/types/vm_address.rs +++ b/vm/src/types/vm_address.rs @@ -4,11 +4,10 @@ use core::fmt::Debug; const SC_ADDRESS_NUM_LEADING_ZEROS: u8 = 8; -/// An Address is just a H256 with a different name. -/// Has a different ABI name than H256. +/// Address type being used in the VM only. /// -/// Note: we are currently using ManagedAddress in contracts. -/// While this also works, its use in contracts is discouraged. +/// Its implementation is similar to that of the heap Address in the framework, +/// but we have a separate implementation for the VM, because it is a separate component. #[derive(Hash, PartialEq, Eq, Clone, Debug)] pub struct VMAddress(H256); @@ -86,11 +85,6 @@ impl VMAddress { VMAddress(H256::zero()) } - /// Returns the size of an address in bytes. - pub fn len_bytes() -> usize { - H256::len_bytes() - } - /// Extracts a byte slice containing the entire fixed hash. pub fn as_bytes(&self) -> &[u8] { self.0.as_bytes() @@ -100,30 +94,10 @@ impl VMAddress { self.0.as_array() } - pub fn copy_to_array(&self, target: &mut [u8; 32]) { - self.0.copy_to_array(target) - } - pub fn to_vec(&self) -> Vec { self.0.to_vec() } - /// Pointer to the data on the heap. - pub fn as_ptr(&self) -> *const u8 { - self.0.as_ptr() - } - - /// Returns an unsafe mutable pointer to the data on the heap. - /// Used by the API to populate data. - pub fn as_mut_ptr(&mut self) -> *mut u8 { - self.0.as_mut_ptr() - } - - /// True if all 32 bytes of the hash are zero. - pub fn is_zero(&self) -> bool { - self.0.is_zero() - } - pub fn is_smart_contract_address(&self) -> bool { self.as_bytes() .iter() diff --git a/vm/src/types/vm_code_metadata.rs b/vm/src/types/vm_code_metadata.rs index d0bd4b6c5b..b00829f1ee 100644 --- a/vm/src/types/vm_code_metadata.rs +++ b/vm/src/types/vm_code_metadata.rs @@ -1,14 +1,8 @@ use bitflags::bitflags; -// const UPGRADEABLE_STRING: &[u8] = b"Upgradeable"; -// const READABLE_STRING: &[u8] = b"Readable"; -// const PAYABLE_STRING: &[u8] = b"Payable"; -// const PAYABLE_BY_SC_STRING: &[u8] = b"PayableBySC"; -// const DEFAULT_STRING: &[u8] = b"Default"; - bitflags! { #[derive(Default)] - pub struct CodeMetadata: u16 { + pub struct VMCodeMetadata: u16 { const DEFAULT = 0; const UPGRADEABLE = 0b0000_0001_0000_0000; // LSB of first byte const READABLE = 0b0000_0100_0000_0000; // 3rd LSB of first byte @@ -17,21 +11,21 @@ bitflags! { } } -impl CodeMetadata { +impl VMCodeMetadata { pub fn is_upgradeable(&self) -> bool { - *self & CodeMetadata::UPGRADEABLE != CodeMetadata::DEFAULT + *self & VMCodeMetadata::UPGRADEABLE != VMCodeMetadata::DEFAULT } pub fn is_payable(&self) -> bool { - *self & CodeMetadata::PAYABLE != CodeMetadata::DEFAULT + *self & VMCodeMetadata::PAYABLE != VMCodeMetadata::DEFAULT } pub fn is_payable_by_sc(&self) -> bool { - *self & CodeMetadata::PAYABLE_BY_SC != CodeMetadata::DEFAULT + *self & VMCodeMetadata::PAYABLE_BY_SC != VMCodeMetadata::DEFAULT } pub fn is_readable(&self) -> bool { - *self & CodeMetadata::READABLE != CodeMetadata::DEFAULT + *self & VMCodeMetadata::READABLE != VMCodeMetadata::DEFAULT } pub fn to_byte_array(&self) -> [u8; 2] { @@ -43,17 +37,17 @@ impl CodeMetadata { } } -impl From<[u8; 2]> for CodeMetadata { +impl From<[u8; 2]> for VMCodeMetadata { #[inline] fn from(arr: [u8; 2]) -> Self { - CodeMetadata::from(u16::from_be_bytes(arr)) + VMCodeMetadata::from(u16::from_be_bytes(arr)) } } -impl From for CodeMetadata { +impl From for VMCodeMetadata { #[inline] fn from(value: u16) -> Self { - CodeMetadata::from_bits_truncate(value) + VMCodeMetadata::from_bits_truncate(value) } } @@ -63,17 +57,17 @@ mod tests { #[test] fn test_default() { - assert!(!CodeMetadata::DEFAULT.is_upgradeable()); - assert!(!CodeMetadata::DEFAULT.is_payable()); - assert!(!CodeMetadata::DEFAULT.is_readable()); + assert!(!VMCodeMetadata::DEFAULT.is_upgradeable()); + assert!(!VMCodeMetadata::DEFAULT.is_payable()); + assert!(!VMCodeMetadata::DEFAULT.is_readable()); } #[test] fn test_all() { - let all = CodeMetadata::UPGRADEABLE - | CodeMetadata::PAYABLE - | CodeMetadata::PAYABLE_BY_SC - | CodeMetadata::READABLE; + let all = VMCodeMetadata::UPGRADEABLE + | VMCodeMetadata::PAYABLE + | VMCodeMetadata::PAYABLE_BY_SC + | VMCodeMetadata::READABLE; assert!(all.is_upgradeable()); assert!(all.is_payable()); assert!(all.is_payable_by_sc()); @@ -81,42 +75,42 @@ mod tests { assert_eq!(all.bits(), 0x0506); - assert_eq!(CodeMetadata::from_bits_truncate(0xffff), all); + assert_eq!(VMCodeMetadata::from_bits_truncate(0xffff), all); } #[test] fn test_each() { - assert!(CodeMetadata::UPGRADEABLE.is_upgradeable()); - assert!(!CodeMetadata::PAYABLE.is_upgradeable()); - assert!(!CodeMetadata::PAYABLE_BY_SC.is_upgradeable()); - assert!(!CodeMetadata::READABLE.is_upgradeable()); - - assert!(!CodeMetadata::UPGRADEABLE.is_payable()); - assert!(CodeMetadata::PAYABLE.is_payable()); - assert!(!CodeMetadata::PAYABLE_BY_SC.is_payable()); - assert!(!CodeMetadata::READABLE.is_payable()); - - assert!(!CodeMetadata::UPGRADEABLE.is_payable_by_sc()); - assert!(!CodeMetadata::PAYABLE.is_payable_by_sc()); - assert!(CodeMetadata::PAYABLE_BY_SC.is_payable_by_sc()); - assert!(!CodeMetadata::READABLE.is_payable_by_sc()); - - assert!(!CodeMetadata::UPGRADEABLE.is_readable()); - assert!(!CodeMetadata::PAYABLE.is_readable()); - assert!(!CodeMetadata::PAYABLE_BY_SC.is_readable()); - assert!(CodeMetadata::READABLE.is_readable()); + assert!(VMCodeMetadata::UPGRADEABLE.is_upgradeable()); + assert!(!VMCodeMetadata::PAYABLE.is_upgradeable()); + assert!(!VMCodeMetadata::PAYABLE_BY_SC.is_upgradeable()); + assert!(!VMCodeMetadata::READABLE.is_upgradeable()); + + assert!(!VMCodeMetadata::UPGRADEABLE.is_payable()); + assert!(VMCodeMetadata::PAYABLE.is_payable()); + assert!(!VMCodeMetadata::PAYABLE_BY_SC.is_payable()); + assert!(!VMCodeMetadata::READABLE.is_payable()); + + assert!(!VMCodeMetadata::UPGRADEABLE.is_payable_by_sc()); + assert!(!VMCodeMetadata::PAYABLE.is_payable_by_sc()); + assert!(VMCodeMetadata::PAYABLE_BY_SC.is_payable_by_sc()); + assert!(!VMCodeMetadata::READABLE.is_payable_by_sc()); + + assert!(!VMCodeMetadata::UPGRADEABLE.is_readable()); + assert!(!VMCodeMetadata::PAYABLE.is_readable()); + assert!(!VMCodeMetadata::PAYABLE_BY_SC.is_readable()); + assert!(VMCodeMetadata::READABLE.is_readable()); } /// Translated from vm-wasm. #[test] fn test_from_array() { - assert!(CodeMetadata::from([1, 0]).is_upgradeable()); - assert!(!CodeMetadata::from([1, 0]).is_readable()); - assert!(CodeMetadata::from([0, 2]).is_payable()); - assert!(CodeMetadata::from([4, 0]).is_readable()); - assert!(!CodeMetadata::from([4, 0]).is_upgradeable()); - assert!(!CodeMetadata::from([0, 0]).is_upgradeable()); - assert!(!CodeMetadata::from([0, 0]).is_payable()); - assert!(!CodeMetadata::from([0, 0]).is_readable()); + assert!(VMCodeMetadata::from([1, 0]).is_upgradeable()); + assert!(!VMCodeMetadata::from([1, 0]).is_readable()); + assert!(VMCodeMetadata::from([0, 2]).is_payable()); + assert!(VMCodeMetadata::from([4, 0]).is_readable()); + assert!(!VMCodeMetadata::from([4, 0]).is_upgradeable()); + assert!(!VMCodeMetadata::from([0, 0]).is_upgradeable()); + assert!(!VMCodeMetadata::from([0, 0]).is_payable()); + assert!(!VMCodeMetadata::from([0, 0]).is_readable()); } } diff --git a/vm/src/types/vm_h256.rs b/vm/src/types/vm_h256.rs index f85bc621d8..48d15c8553 100644 --- a/vm/src/types/vm_h256.rs +++ b/vm/src/types/vm_h256.rs @@ -14,7 +14,6 @@ impl From<[u8; 32]> for H256 { /// # Note /// /// The given bytes are interpreted in big endian order. - #[inline] fn from(arr: [u8; 32]) -> Self { H256(Box::new(arr)) } @@ -27,7 +26,6 @@ impl<'a> From<&'a [u8; 32]> for H256 { /// # Note /// /// The given bytes are interpreted in big endian order. - #[inline] fn from(bytes: &'a [u8; 32]) -> Self { H256(Box::new(*bytes)) } @@ -40,14 +38,12 @@ impl<'a> From<&'a mut [u8; 32]> for H256 { /// # Note /// /// The given bytes are interpreted in big endian order. - #[inline] fn from(bytes: &'a mut [u8; 32]) -> Self { H256(Box::new(*bytes)) } } impl From> for H256 { - #[inline] fn from(bytes: Box<[u8; 32]>) -> Self { H256(bytes) } @@ -63,21 +59,18 @@ impl H256 { } impl From for [u8; 32] { - #[inline] fn from(s: H256) -> Self { *(s.0) } } impl AsRef<[u8]> for H256 { - #[inline] fn as_ref(&self) -> &[u8] { self.as_bytes() } } impl AsMut<[u8]> for H256 { - #[inline] fn as_mut(&mut self) -> &mut [u8] { self.0.as_mut() } @@ -95,46 +88,19 @@ impl H256 { } } - /// Returns the size of this hash in bytes. - #[inline] - pub fn len_bytes() -> usize { - 32 - } - /// Extracts a byte slice containing the entire fixed hash. - #[inline] pub fn as_bytes(&self) -> &[u8] { self.0.as_ref() } - #[inline] pub fn as_array(&self) -> &[u8; 32] { self.0.as_ref() } - #[inline] - pub fn copy_to_array(&self, target: &mut [u8; 32]) { - target.copy_from_slice(&self.0[..]); - } - - #[inline] pub fn to_vec(&self) -> Vec { self.0[..].to_vec() } - /// Pointer to the data on the heap. - #[inline] - pub fn as_ptr(&self) -> *const u8 { - self.0.as_ptr() - } - - /// Returns an unsafe mutable pointer to the data on the heap. - /// Used by the API to populate data. - #[inline] - pub fn as_mut_ptr(&mut self) -> *mut u8 { - self.0.as_mut_ptr() - } - /// True if all 32 bytes of the hash are zero. pub fn is_zero(&self) -> bool { self.as_bytes() == ZERO_32 diff --git a/vm/src/vm_hooks/vh_debugger_stack.rs b/vm/src/vm_hooks/vh_debugger_stack.rs index 068a183d3d..700b7a2ac2 100644 --- a/vm/src/vm_hooks/vh_debugger_stack.rs +++ b/vm/src/vm_hooks/vh_debugger_stack.rs @@ -11,7 +11,7 @@ use crate::{ async_call_tx_input, AsyncCallTxData, BlockchainUpdate, TxCache, TxContext, TxFunctionName, TxInput, TxManagedTypes, TxPanic, TxResult, }, - types::{CodeMetadata, VMAddress}, + types::{VMAddress, VMCodeMetadata}, vm_err_msg, world_mock::{AccountData, BlockInfo, STORAGE_RESERVED_PREFIX}, }; @@ -139,7 +139,7 @@ impl VMHooksHandlerSource for TxContextWrapper { &self, egld_value: num_bigint::BigUint, contract_code: Vec, - _code_metadata: CodeMetadata, + _code_metadata: VMCodeMetadata, args: Vec>, ) -> (VMAddress, Vec>) { let contract_address = &self.input_ref().to; diff --git a/vm/src/vm_hooks/vh_handler/vh_send.rs b/vm/src/vm_hooks/vh_handler/vh_send.rs index 6aae5fe1b9..6a12ca9cd7 100644 --- a/vm/src/vm_hooks/vh_handler/vh_send.rs +++ b/vm/src/vm_hooks/vh_handler/vh_send.rs @@ -4,7 +4,7 @@ use crate::{ UPGRADE_CONTRACT_FUNC_NAME, }, tx_mock::{AsyncCallTxData, Promise, TxFunctionName, TxTokenTransfer}, - types::{top_encode_big_uint, top_encode_u64, CodeMetadata, RawHandle, VMAddress}, + types::{top_encode_big_uint, top_encode_u64, RawHandle, VMAddress, VMCodeMetadata}, vm_hooks::VMHooksHandlerSource, }; use num_traits::Zero; @@ -107,7 +107,7 @@ pub trait VMHooksSend: VMHooksHandlerSource { to: VMAddress, egld_value: num_bigint::BigUint, contract_code: Vec, - code_metadata: CodeMetadata, + code_metadata: VMCodeMetadata, args: Vec>, ) -> ! { let mut arguments = vec![contract_code, code_metadata.to_vec()]; diff --git a/vm/src/vm_hooks/vh_managed_types_cell.rs b/vm/src/vm_hooks/vh_managed_types_cell.rs index abdd511998..adc5bcf1bd 100644 --- a/vm/src/vm_hooks/vh_managed_types_cell.rs +++ b/vm/src/vm_hooks/vh_managed_types_cell.rs @@ -2,7 +2,7 @@ use std::cell::{Ref, RefCell, RefMut}; use crate::{ tx_mock::{TxFunctionName, TxInput, TxLog, TxManagedTypes, TxResult}, - types::{CodeMetadata, VMAddress}, + types::{VMAddress, VMCodeMetadata}, world_mock::{AccountData, BlockInfo}, }; @@ -96,7 +96,7 @@ impl VMHooksHandlerSource for TxManagedTypesCell { &self, _egld_value: num_bigint::BigUint, _contract_code: Vec, - _code_metadata: CodeMetadata, + _code_metadata: VMCodeMetadata, _args: Vec>, ) -> (VMAddress, Vec>) { panic!("cannot launch contract calls in the StaticApi") diff --git a/vm/src/vm_hooks/vh_source.rs b/vm/src/vm_hooks/vh_source.rs index 367182e67d..028f6bcca4 100644 --- a/vm/src/vm_hooks/vh_source.rs +++ b/vm/src/vm_hooks/vh_source.rs @@ -5,7 +5,7 @@ use std::{ use crate::{ tx_mock::{TxFunctionName, TxInput, TxLog, TxManagedTypes, TxResult}, - types::{CodeMetadata, VMAddress, H256}, + types::{VMAddress, VMCodeMetadata, H256}, world_mock::{AccountData, BlockInfo}, }; @@ -82,7 +82,7 @@ pub trait VMHooksHandlerSource: Debug { &self, egld_value: num_bigint::BigUint, contract_code: Vec, - code_metadata: CodeMetadata, + code_metadata: VMCodeMetadata, args: Vec>, ) -> (VMAddress, Vec>);