Skip to content

Commit

Permalink
Merge pull request #1156 from multiversx/scenario-static-api-3
Browse files Browse the repository at this point in the history
SingleTxApi
  • Loading branch information
andrei-marinica committed Jul 12, 2023
2 parents d16b362 + 09970d5 commit 5d878bb
Show file tree
Hide file tree
Showing 23 changed files with 426 additions and 116 deletions.
6 changes: 2 additions & 4 deletions contracts/examples/adder/tests/adder_test.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use adder::*;
use multiversx_sc::types::BigUint;
use multiversx_sc_scenario::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

#[test]
fn test_add() {
let _ = DebugApi::dummy();

let adder = adder::contract_obj::<DebugApi>();
let adder = adder::contract_obj::<SingleTxApi>();

adder.init(BigUint::from(5u32));
assert_eq!(BigUint::from(5u32), adder.sum().get());
Expand Down
9 changes: 9 additions & 0 deletions framework/base/src/storage/storage_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ impl<M: ManagedTypeApi> From<ManagedBuffer<M>> for StorageKey<M> {
}
}

impl<M: ManagedTypeApi> From<&str> for StorageKey<M> {
#[inline]
fn from(s: &str) -> Self {
StorageKey {
buffer: ManagedBuffer::from(s),
}
}
}

impl<M, const N: usize> From<ManagedByteArray<M, N>> for StorageKey<M>
where
M: ManagedTypeApi + ErrorApi,
Expand Down
2 changes: 1 addition & 1 deletion framework/scenario/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ mod managed_type_api_vh;
mod vm_api_vh;

pub(crate) use impl_vh::i32_to_bool;
pub use impl_vh::{DebugApi, DebugHandle, StaticApi, VMHooksApi, VMHooksApiBackend};
pub use impl_vh::{DebugApi, DebugHandle, SingleTxApi, StaticApi, VMHooksApi, VMHooksApiBackend};
2 changes: 2 additions & 0 deletions framework/scenario/src/api/impl_vh.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
mod debug_api;
mod debug_handle_vh;
mod single_tx_api;
mod static_api;
mod vm_hooks_api;
mod vm_hooks_backend;

pub use debug_api::DebugApi;
pub use debug_handle_vh::DebugHandle;
pub use single_tx_api::SingleTxApi;
pub use static_api::StaticApi;
pub(crate) use vm_hooks_api::i32_to_bool;
pub use vm_hooks_api::VMHooksApi;
Expand Down
6 changes: 3 additions & 3 deletions framework/scenario/src/api/impl_vh/debug_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::rc::Rc;
use multiversx_chain_vm::{
executor::{BreakpointValue, VMHooks},
tx_mock::{TxContext, TxContextRef, TxContextStack, TxPanic},
vm_hooks::{TxContextWrapper, VMHooksDispatcher},
vm_hooks::{DebugApiVMHooksHandler, VMHooksDispatcher},
};
use multiversx_sc::err_msg;

Expand All @@ -22,7 +22,7 @@ impl VMHooksApiBackend for DebugApiBackend {
F: FnOnce(&dyn VMHooks) -> R,
{
let top_context = TxContextStack::static_peek();
let wrapper = TxContextWrapper::new(top_context);
let wrapper = DebugApiVMHooksHandler::new(top_context);
let dispatcher = VMHooksDispatcher::new(Box::new(wrapper));
f(&dispatcher)
}
Expand All @@ -31,7 +31,7 @@ impl VMHooksApiBackend for DebugApiBackend {
where
F: FnOnce(&dyn VMHooks) -> R,
{
let wrapper = TxContextWrapper::new(handle.context);
let wrapper = DebugApiVMHooksHandler::new(handle.context);
let dispatcher = VMHooksDispatcher::new(Box::new(wrapper));
f(&dispatcher)
}
Expand Down
78 changes: 78 additions & 0 deletions framework/scenario/src/api/impl_vh/single_tx_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::cell::RefCell;

use multiversx_chain_vm::{
executor::VMHooks,
types::VMAddress,
vm_hooks::{SingleTxApiData, SingleTxApiVMHooksHandler, VMHooksDispatcher},
world_mock::AccountData,
};
use multiversx_sc::api::RawHandle;

use crate::debug_executor::StaticVarData;

use super::{VMHooksApi, VMHooksApiBackend};

thread_local! {
static SINGLE_TX_API_VH_CELL: RefCell<SingleTxApiVMHooksHandler> = RefCell::default();

static SINGLE_TX_API_STATIC_CELL: StaticVarData = StaticVarData::default();
}

#[derive(Clone)]
pub struct SingleTxApiBackend;

impl VMHooksApiBackend for SingleTxApiBackend {
type HandleType = RawHandle;

fn with_vm_hooks<R, F>(f: F) -> R
where
F: FnOnce(&dyn VMHooks) -> R,
{
SINGLE_TX_API_VH_CELL.with(|cell| {
let handler = cell.borrow().clone();
let dispatcher = VMHooksDispatcher::new(Box::new(handler));
f(&dispatcher)
})
}

fn with_static_data<R, F>(f: F) -> R
where
F: FnOnce(&StaticVarData) -> R,
{
SINGLE_TX_API_STATIC_CELL.with(|data| f(data))
}
}

/// Similar to the `StaticApi`, but offers allows calls to storage, input, and even creating results.
pub type SingleTxApi = VMHooksApi<SingleTxApiBackend>;

impl SingleTxApi {
pub fn clear_global() {
SINGLE_TX_API_VH_CELL.with(|cell| {
let _ = cell.take();
})
}

pub fn with_global<F, R>(f: F) -> R
where
F: FnOnce(&mut SingleTxApiData) -> R,
{
SINGLE_TX_API_VH_CELL.with(|cell| {
let mut handler = cell.borrow_mut();
handler.with_mut_data(f)
})
}

pub fn with_global_default_account<F, R>(f: F) -> R
where
F: FnOnce(&mut AccountData) -> R,
{
Self::with_global(|data| data.with_account_mut(&VMAddress::zero(), f))
}
}

impl std::fmt::Debug for SingleTxApi {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("SingleTxApi").finish()
}
}
18 changes: 8 additions & 10 deletions framework/scenario/src/api/impl_vh/static_api.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
use std::ops::Deref;

use multiversx_chain_vm::{
executor::VMHooks,
vm_hooks::{TxManagedTypesCell, VMHooksDispatcher, VMHooksHandler},
vm_hooks::{StaticApiVMHooksHandler, VMHooksDispatcher, VMHooksHandler},
};
use multiversx_sc::api::RawHandle;

use crate::debug_executor::StaticVarData;

use super::{VMHooksApi, VMHooksApiBackend};

fn new_vh_dispatcher_managed_types_cell() -> Box<dyn VMHooks> {
let vh_handler: Box<dyn VMHooksHandler> = Box::<TxManagedTypesCell>::default();
Box::new(VMHooksDispatcher::new(vh_handler))
fn new_static_api_vh() -> VMHooksDispatcher {
let vh_handler: Box<dyn VMHooksHandler> = Box::<StaticApiVMHooksHandler>::default();
VMHooksDispatcher::new(vh_handler)
}

thread_local! {
static MANAGED_TYPES_CELL: Box<dyn VMHooks> = new_vh_dispatcher_managed_types_cell();
static STATIC_API_VH_CELL: VMHooksDispatcher = new_static_api_vh();

static STATIC_VAR_DATA_CELL: StaticVarData = StaticVarData::default();
static STATIC_API_STATIC_CELL: StaticVarData = StaticVarData::default();
}

#[derive(Clone)]
Expand All @@ -31,14 +29,14 @@ impl VMHooksApiBackend for StaticApiBackend {
where
F: FnOnce(&dyn VMHooks) -> R,
{
MANAGED_TYPES_CELL.with(|vh| f(vh.deref()))
STATIC_API_VH_CELL.with(|vh| f(vh))
}

fn with_static_data<R, F>(f: F) -> R
where
F: FnOnce(&StaticVarData) -> R,
{
STATIC_VAR_DATA_CELL.with(|data| f(data))
STATIC_API_STATIC_CELL.with(|data| f(data))
}
}

Expand Down
8 changes: 3 additions & 5 deletions framework/scenario/tests/contract_without_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use multiversx_sc::{
contract_base::ProxyObjBase,
types::{BigInt, ManagedAddress},
};
use multiversx_sc_scenario::DebugApi;
use multiversx_sc_scenario::api::{SingleTxApi, StaticApi};

use crate::module_1::VersionModule;

Expand Down Expand Up @@ -413,9 +413,7 @@ mod sample_adder {
fn contract_without_macros_basic() {
use sample_adder::{Adder, EndpointWrappers, ProxyTrait};

let _ = DebugApi::dummy();

let adder = sample_adder::contract_obj::<DebugApi>();
let adder = sample_adder::contract_obj::<SingleTxApi>();

adder.init(&BigInt::from(5));
assert_eq!(BigInt::from(5), adder.get_sum());
Expand All @@ -436,7 +434,7 @@ fn contract_without_macros_basic() {
assert!(adder.call("version"));

let mut own_proxy =
sample_adder::Proxy::<DebugApi>::new_proxy_obj().contract(ManagedAddress::zero());
sample_adder::Proxy::<StaticApi>::new_proxy_obj().contract(ManagedAddress::zero());
let _ = own_proxy.get_sum();

let _ = multiversx_sc_meta::abi_json::contract_abi::<sample_adder::AbiProvider>();
Expand Down
47 changes: 47 additions & 0 deletions framework/scenario/tests/single_tx_api_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use multiversx_sc::contract_base::StorageRawWrapper;
use multiversx_sc_scenario::api::SingleTxApi;

#[test]
fn single_tx_api_test() {
let storage_raw = StorageRawWrapper::<SingleTxApi>::new();
let storage_key = "test-num";

// unitialized, we get the default
let x: i32 = storage_raw.read(storage_key);
assert_eq!(x, 0);

// write, as if from a contract
storage_raw.write(storage_key, &5i32);
let x: i32 = storage_raw.read(storage_key);
assert_eq!(x, 5);

// check directly in storage
SingleTxApi::with_global_default_account(|account| {
let value = account.storage.get(storage_key.as_bytes()).unwrap();
assert_eq!(value, &vec![5u8]);

// change value directly in storage
account
.storage
.insert(storage_key.as_bytes().to_vec(), vec![7u8]);
});

// read again
let x: i32 = storage_raw.read(storage_key);
assert_eq!(x, 7);

// clear everything, globally
SingleTxApi::clear_global();
let x: i32 = storage_raw.read(storage_key);
assert_eq!(x, 0);

// checking directly in storage
SingleTxApi::with_global_default_account(|account| {
let value = account
.storage
.get(storage_key.as_bytes())
.cloned()
.unwrap_or_default();
assert!(value.is_empty());
});
}
7 changes: 3 additions & 4 deletions framework/scenario/tests/test_hash_bi_di_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use multiversx_sc::storage::{
mappers::{BiDiMapper, StorageMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_set_1() -> BiDiMapper<DebugApi, u64, u32> {
let _ = DebugApi::dummy();
fn create_set_1() -> BiDiMapper<SingleTxApi, u64, u32> {
let base_key = StorageKey::new(&b"my_bidi_set"[..]);
BiDiMapper::new(base_key)
}

fn check_set_1(set: &BiDiMapper<DebugApi, u64, u32>, ids: Vec<u64>, values: Vec<u32>) {
fn check_set_1(set: &BiDiMapper<SingleTxApi, u64, u32>, ids: Vec<u64>, values: Vec<u32>) {
assert_eq!(values.len(), ids.len());
assert_eq!(set.len(), ids.len());

Expand Down
5 changes: 2 additions & 3 deletions framework/scenario/tests/test_hash_map_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use multiversx_sc::storage::{
mappers::{MapMapper, StorageClearable, StorageMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_map() -> MapMapper<DebugApi, u64, u64> {
let _ = DebugApi::dummy();
fn create_map() -> MapMapper<SingleTxApi, u64, u64> {
let base_key = StorageKey::new(&b"my_map"[..]);
MapMapper::new(base_key)
}
Expand Down
5 changes: 2 additions & 3 deletions framework/scenario/tests/test_hash_map_storage_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use multiversx_sc::storage::{
mappers::{MapMapper, MapStorageMapper, StorageClearable, StorageMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_map_storage() -> MapStorageMapper<DebugApi, u64, MapMapper<DebugApi, u64, u64>> {
let _ = DebugApi::dummy();
fn create_map_storage() -> MapStorageMapper<SingleTxApi, u64, MapMapper<SingleTxApi, u64, u64>> {
let base_key = StorageKey::new(&b"my_map_storage"[..]);
MapStorageMapper::new(base_key)
}
Expand Down
7 changes: 3 additions & 4 deletions framework/scenario/tests/test_hash_set_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use multiversx_sc::storage::{
mappers::{SetMapper, StorageClearable, StorageMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_set() -> SetMapper<DebugApi, u64> {
let _ = DebugApi::dummy();
fn create_set() -> SetMapper<SingleTxApi, u64> {
let base_key = StorageKey::new(&b"my_set"[..]);
SetMapper::new(base_key)
}

fn check_set(set: &SetMapper<DebugApi, u64>, expected: Vec<u64>) {
fn check_set(set: &SetMapper<SingleTxApi, u64>, expected: Vec<u64>) {
assert_eq!(set.len(), expected.len());
assert!(set.check_internal_consistency());
let actual: Vec<u64> = set.iter().collect();
Expand Down
7 changes: 3 additions & 4 deletions framework/scenario/tests/test_hash_unordered_set_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use multiversx_sc::storage::{
mappers::{StorageClearable, StorageMapper, UnorderedSetMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_set() -> UnorderedSetMapper<DebugApi, u64> {
let _ = DebugApi::dummy();
fn create_set() -> UnorderedSetMapper<SingleTxApi, u64> {
let base_key = StorageKey::new(&b"my_unordered_set"[..]);
UnorderedSetMapper::new(base_key)
}

fn check_set(set: &UnorderedSetMapper<DebugApi, u64>, expected: Vec<u64>) {
fn check_set(set: &UnorderedSetMapper<SingleTxApi, u64>, expected: Vec<u64>) {
assert_eq!(set.len(), expected.len());
let actual: Vec<u64> = set.iter().collect();
assert_eq!(actual, expected);
Expand Down
7 changes: 3 additions & 4 deletions framework/scenario/tests/test_linked_list_mapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ use multiversx_sc::storage::{
mappers::{LinkedListMapper, StorageClearable, StorageMapper},
StorageKey,
};
use multiversx_sc_scenario::api::DebugApi;
use multiversx_sc_scenario::api::SingleTxApi;

fn create_list() -> LinkedListMapper<DebugApi, u64> {
let _ = DebugApi::dummy();
fn create_list() -> LinkedListMapper<SingleTxApi, u64> {
let base_key = StorageKey::new(&b"my_list"[..]);
LinkedListMapper::new(base_key)
}
Expand Down Expand Up @@ -33,7 +32,7 @@ fn test_list_simple() {
assert!(list.check_internal_consistency());
}

fn check_list(list: &LinkedListMapper<DebugApi, u64>, expected: Vec<u64>) {
fn check_list(list: &LinkedListMapper<SingleTxApi, u64>, expected: Vec<u64>) {
assert_eq!(list.len(), expected.len());
let vec: Vec<u64> = list.iter().map(|x| x.into_value()).collect();
assert_eq!(vec, expected);
Expand Down
Loading

0 comments on commit 5d878bb

Please sign in to comment.