Skip to content

Commit

Permalink
Merge pull request #1137 from multiversx/vm-separation
Browse files Browse the repository at this point in the history
VM separated from framework
  • Loading branch information
andrei-marinica committed Jun 28, 2023
2 parents 3d87e44 + 13af92e commit dbabe3c
Show file tree
Hide file tree
Showing 89 changed files with 1,054 additions and 457 deletions.
14 changes: 0 additions & 14 deletions framework/base/src/err_msg.rs
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -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 =
Expand All @@ -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 =
Expand Down
1 change: 1 addition & 0 deletions framework/scenario/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions framework/scenario/src/display_util.rs
Original file line number Diff line number Diff line change
@@ -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<M: ManagedTypeApi> {
pub value: BigUint<M>,
}

impl<M: ManagedTypeApi> fmt::Debug for BigUintPrinter<M> {
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()
}
}
7 changes: 3 additions & 4 deletions framework/scenario/src/facade/scenario_world_steps.rs
Original file line number Diff line number Diff line change
@@ -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},
};

Expand Down
7 changes: 6 additions & 1 deletion framework/scenario/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
#![feature(exhaustive_patterns)]

pub mod api;
pub mod bech32;
pub mod debug_executor;
pub mod display_util;
mod facade;
pub mod managed_test_util;
pub mod scenario;
Expand All @@ -16,7 +18,10 @@ 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;

/// Re-exporting for convenience.
pub use num_bigint;

pub use multiversx_sc;

Expand Down
4 changes: 4 additions & 0 deletions framework/scenario/src/scenario/model/value/address_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions framework/scenario/src/scenario/model/value/address_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion framework/scenario/src/scenario/run_vm/check_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: {}",
Expand Down
4 changes: 2 additions & 2 deletions framework/scenario/src/scenario/run_vm/sc_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
11 changes: 6 additions & 5 deletions framework/scenario/src/scenario/run_vm/sc_deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand All @@ -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,
Expand All @@ -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(
Expand All @@ -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)
}
4 changes: 2 additions & 2 deletions framework/scenario/src/scenario/run_vm/sc_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
21 changes: 12 additions & 9 deletions framework/scenario/src/scenario/run_vm/set_state.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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()
Expand All @@ -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()
Expand All @@ -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 {
Expand Down Expand Up @@ -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()
Expand Down
6 changes: 3 additions & 3 deletions framework/scenario/src/scenario/run_vm/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ 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,
);
}
}

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,
Expand Down
Loading

0 comments on commit dbabe3c

Please sign in to comment.