Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

static api - initialization flags grouped into single bitfield #1903

Merged
merged 2 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading