Skip to content

Commit

Permalink
Merge pull request #1903 from multiversx/static-flags
Browse files Browse the repository at this point in the history
static api - initialization flags grouped into single bitfield
  • Loading branch information
andrei-marinica authored Dec 20, 2024
2 parents 4bc903f + de2c630 commit 1bac654
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 75 deletions.
2 changes: 2 additions & 0 deletions framework/base/src/api/managed_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod managed_map_api;
mod managed_type_api;
mod managed_type_api_impl;
mod static_var_api;
mod static_var_api_flags;
mod token_identifier_util;

pub use big_float_api::*;
Expand All @@ -19,3 +20,4 @@ pub use managed_map_api::*;
pub use managed_type_api::*;
pub use managed_type_api_impl::*;
pub use static_var_api::*;
pub use static_var_api_flags::StaticVarApiFlags;
24 changes: 16 additions & 8 deletions framework/base/src/api/managed_types/static_var_api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::types::LockableStaticBuffer;

use super::RawHandle;
use super::{RawHandle, StaticVarApiFlags};

pub trait StaticVarApi {
type StaticVarApiImpl: StaticVarApiImpl;
Expand All @@ -24,13 +24,21 @@ pub trait StaticVarApiImpl {

fn get_num_arguments(&self) -> i32;

fn set_call_value_egld_handle(&self, handle: RawHandle);

fn get_call_value_egld_handle(&self) -> RawHandle;

fn set_call_value_multi_esdt_handle(&self, handle: RawHandle);

fn get_call_value_multi_esdt_handle(&self) -> RawHandle;
fn set_flags(&self, flags: StaticVarApiFlags);

fn get_flags(&self) -> StaticVarApiFlags;

/// Returns true if the flag is set, false if is default (false).
///
/// If the flag is unset (false), will set it.
fn flag_is_set_or_update(&self, flag: StaticVarApiFlags) -> bool {
let mut current_flags = self.get_flags();
let contains_flag = current_flags.check_and_set(flag);
if !contains_flag {
self.set_flags(current_flags);
}
contains_flag
}

fn is_scaling_factor_cached(&self, decimals: usize) -> bool;

Expand Down
53 changes: 53 additions & 0 deletions framework/base/src/api/managed_types/static_var_api_flags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use bitflags::bitflags;

bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct StaticVarApiFlags: u8 {
const NONE = 0b00000000;
const CALL_VALUE_EGLD_INITIALIZED = 0b00000001;
const CALL_VALUE_EGLD_MULTI_INITIALIZED = 0b00000010;
const CALL_VALUE_MULTI_ESDT_INITIALIZED = 0b00000100;
const CALL_VALUE_ALL_INITIALIZED = 0b00001000;
}
}

impl StaticVarApiFlags {
pub fn check_and_set(&mut self, other: StaticVarApiFlags) -> bool {
let contains_flag = self.contains(other);
if !contains_flag {
*self |= other;
}
contains_flag
}
}

#[cfg(test)]
pub mod tests {
use super::StaticVarApiFlags;

#[test]
fn test_check_and_set() {
let mut current = StaticVarApiFlags::NONE;

assert!(current.check_and_set(StaticVarApiFlags::NONE));
assert_eq!(current, StaticVarApiFlags::NONE);

assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED));
assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED);
assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED));
assert_eq!(current, StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED);

assert!(!current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED));
assert_eq!(
current,
StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED
| StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED
);
assert!(current.check_and_set(StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED));
assert_eq!(
current,
StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED
| StaticVarApiFlags::CALL_VALUE_ALL_INITIALIZED
);
}
}
14 changes: 3 additions & 11 deletions framework/base/src/api/uncallable/static_var_api_uncallable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
api::{RawHandle, StaticVarApi, StaticVarApiImpl},
api::{RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl},
types::LockableStaticBuffer,
};

Expand Down Expand Up @@ -41,19 +41,11 @@ impl StaticVarApiImpl for UncallableApi {
unreachable!()
}

fn set_call_value_egld_handle(&self, _handle: RawHandle) {
fn set_flags(&self, _flags: StaticVarApiFlags) {
unreachable!()
}

fn get_call_value_egld_handle(&self) -> RawHandle {
unreachable!()
}

fn set_call_value_multi_esdt_handle(&self, _handle: RawHandle) {
unreachable!()
}

fn get_call_value_multi_esdt_handle(&self) -> RawHandle {
fn get_flags(&self) -> StaticVarApiFlags {
unreachable!()
}

Expand Down
22 changes: 10 additions & 12 deletions framework/base/src/contract_base/wrappers/call_value_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::marker::PhantomData;
use crate::{
api::{
const_handles, use_raw_handle, CallValueApi, CallValueApiImpl, ErrorApi, ErrorApiImpl,
HandleConstraints, ManagedTypeApi, StaticVarApiImpl,
ManagedTypeApi, StaticVarApiFlags, StaticVarApiImpl,
},
err_msg,
types::{
Expand Down Expand Up @@ -34,11 +34,10 @@ where
/// Retrieves the EGLD call value from the VM.
/// Will return 0 in case of an ESDT transfer (cannot have both EGLD and ESDT transfer simultaneously).
pub fn egld_value(&self) -> ManagedRef<'static, A, BigUint<A>> {
let mut call_value_handle: A::BigIntHandle =
use_raw_handle(A::static_var_api_impl().get_call_value_egld_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_EGLD);
A::static_var_api_impl().set_call_value_egld_handle(call_value_handle.get_raw_handle());
let call_value_handle: A::BigIntHandle = use_raw_handle(const_handles::CALL_VALUE_EGLD);
if !A::static_var_api_impl()
.flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_EGLD_INITIALIZED)
{
A::call_value_api_impl().load_egld_value(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
Expand All @@ -55,12 +54,11 @@ where
/// Will return 0 results if nothing was transfered, or just EGLD.
/// Fully managed underlying types, very efficient.
pub fn all_esdt_transfers(&self) -> ManagedRef<'static, A, ManagedVec<A, EsdtTokenPayment<A>>> {
let mut call_value_handle: A::ManagedBufferHandle =
use_raw_handle(A::static_var_api_impl().get_call_value_multi_esdt_handle());
if call_value_handle == const_handles::UNINITIALIZED_HANDLE {
call_value_handle = use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT);
A::static_var_api_impl()
.set_call_value_multi_esdt_handle(call_value_handle.get_raw_handle());
let call_value_handle: A::ManagedBufferHandle =
use_raw_handle(const_handles::CALL_VALUE_MULTI_ESDT);
if !A::static_var_api_impl()
.flag_is_set_or_update(StaticVarApiFlags::CALL_VALUE_MULTI_ESDT_INITIALIZED)
{
A::call_value_api_impl().load_all_esdt_transfers(call_value_handle.clone());
}
unsafe { ManagedRef::wrap_handle(call_value_handle) }
Expand Down
26 changes: 5 additions & 21 deletions framework/scenario/src/api/local_api_vh/static_var_api_vh.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::api::{VMHooksApi, VMHooksApiBackend};
use multiversx_sc::{
api::{use_raw_handle, RawHandle, StaticVarApi, StaticVarApiImpl},
api::{RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl},
types::LockableStaticBuffer,
};

Expand Down Expand Up @@ -55,30 +55,14 @@ impl<VHB: VMHooksApiBackend> StaticVarApiImpl for VMHooksApi<VHB> {
self.with_static_data(|data| data.static_vars_cell.borrow().num_arguments)
}

fn set_call_value_egld_handle(&self, handle: RawHandle) {
fn set_flags(&self, flags: StaticVarApiFlags) {
self.with_static_data(|data| {
data.static_vars_cell.borrow_mut().call_value_egld_handle = handle;
data.static_vars_cell.borrow_mut().flags = flags;
})
}

fn get_call_value_egld_handle(&self) -> RawHandle {
self.with_static_data(|data| {
use_raw_handle(data.static_vars_cell.borrow().call_value_egld_handle)
})
}

fn set_call_value_multi_esdt_handle(&self, handle: RawHandle) {
self.with_static_data(|data| {
data.static_vars_cell
.borrow_mut()
.call_value_multi_esdt_handle = handle;
})
}

fn get_call_value_multi_esdt_handle(&self) -> RawHandle {
self.with_static_data(|data| {
use_raw_handle(data.static_vars_cell.borrow().call_value_multi_esdt_handle)
})
fn get_flags(&self) -> StaticVarApiFlags {
self.with_static_data(|data| data.static_vars_cell.borrow().flags)
}

fn is_scaling_factor_cached(&self, decimals: usize) -> bool {
Expand Down
11 changes: 5 additions & 6 deletions framework/scenario/src/debug_executor/tx_static_vars.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use multiversx_sc::api::{const_handles, RawHandle};
use multiversx_sc::api::{const_handles, RawHandle, StaticVarApiFlags};

#[derive(Debug)]
pub struct TxStaticVars {
pub external_view_target_address_handle: RawHandle,
pub next_handle: RawHandle,
pub num_arguments: i32,
pub call_value_egld_handle: RawHandle,
pub call_value_multi_esdt_handle: RawHandle,
//vec of true/false, true if bit from handle = scaling_start + index is not empty
pub flags: StaticVarApiFlags,

/// Vec of true/false, true if bit from handle = scaling_start + index is not empty
pub scaling_factor_init: [bool; const_handles::SCALING_FACTOR_LENGTH],
}

Expand All @@ -17,9 +17,8 @@ impl Default for TxStaticVars {
external_view_target_address_handle: 0,
next_handle: const_handles::NEW_HANDLE_START_FROM,
num_arguments: -1,
call_value_egld_handle: const_handles::UNINITIALIZED_HANDLE,
call_value_multi_esdt_handle: const_handles::UNINITIALIZED_HANDLE,
scaling_factor_init: [false; const_handles::SCALING_FACTOR_LENGTH],
flags: StaticVarApiFlags::NONE,
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use multiversx_sc::{
api::{const_handles, RawHandle, StaticVarApi, StaticVarApiImpl},
api::{const_handles, RawHandle, StaticVarApi, StaticVarApiFlags, StaticVarApiImpl},
types::LockableStaticBuffer,
};

Expand All @@ -9,8 +9,7 @@ static mut STATIC_BUFFER: LockableStaticBuffer = LockableStaticBuffer::new();
static mut EXTERNAL_VIEW_TARGET_ADDRESS_HANDLE: i32 = 0;
static mut NEXT_HANDLE: i32 = const_handles::NEW_HANDLE_START_FROM;
static mut NUM_ARGUMENTS: i32 = 0;
static mut CALL_VALUE_EGLD_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE;
static mut CALL_VALUE_MULTI_ESDT_HANDLE: i32 = const_handles::UNINITIALIZED_HANDLE;
static mut FLAGS: StaticVarApiFlags = StaticVarApiFlags::NONE;
static mut SCALING_FACTOR_INIT: [bool; const_handles::SCALING_FACTOR_LENGTH] =
[false; const_handles::SCALING_FACTOR_LENGTH];

Expand Down Expand Up @@ -62,24 +61,14 @@ impl StaticVarApiImpl for VmApiImpl {
unsafe { NUM_ARGUMENTS }
}

fn set_call_value_egld_handle(&self, handle: RawHandle) {
fn set_flags(&self, flags: StaticVarApiFlags) {
unsafe {
CALL_VALUE_EGLD_HANDLE = handle;
FLAGS = flags;
}
}

fn get_call_value_egld_handle(&self) -> RawHandle {
unsafe { CALL_VALUE_EGLD_HANDLE }
}

fn set_call_value_multi_esdt_handle(&self, handle: RawHandle) {
unsafe {
CALL_VALUE_MULTI_ESDT_HANDLE = handle;
}
}

fn get_call_value_multi_esdt_handle(&self) -> RawHandle {
unsafe { CALL_VALUE_MULTI_ESDT_HANDLE }
fn get_flags(&self) -> StaticVarApiFlags {
unsafe { FLAGS }
}

fn is_scaling_factor_cached(&self, decimals: usize) -> bool {
Expand Down

0 comments on commit 1bac654

Please sign in to comment.