diff --git a/contracts/feature-tests/basic-features/src/storage_direct_load.rs b/contracts/feature-tests/basic-features/src/storage_direct_load.rs index efdd51a20f..7d19f83eb5 100644 --- a/contracts/feature-tests/basic-features/src/storage_direct_load.rs +++ b/contracts/feature-tests/basic-features/src/storage_direct_load.rs @@ -1,7 +1,5 @@ multiversx_sc::imports!(); -use multiversx_sc::api::{use_raw_handle, HandleTypeInfo}; - use crate::types::*; /// Storage tests: direct load. @@ -78,16 +76,15 @@ pub trait StorageLoadFeatures { #[endpoint] fn load_from_address_raw(&self, address: ManagedAddress, key: ManagedBuffer) -> ManagedBuffer { // TODO: maybe wrap this kind of functionality in a StorageRawWrapper - use multiversx_sc::api::{ - StaticVarApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, - }; - let value_handle: <::Api as HandleTypeInfo>::ManagedBufferHandle = - use_raw_handle(Self::Api::static_var_api_impl().next_handle()); - Self::Api::storage_read_api_impl().storage_load_from_address( - address.get_handle(), - key.get_handle(), - value_handle.clone(), - ); - ManagedBuffer::from_handle(value_handle) + use multiversx_sc::api::{StorageReadApi, StorageReadApiImpl}; + unsafe { + let value = ManagedBuffer::new_uninit(); + Self::Api::storage_read_api_impl().storage_load_from_address( + address.get_handle(), + key.get_handle(), + value.get_handle(), + ); + value + } } } diff --git a/contracts/modules/src/esdt.rs b/contracts/modules/src/esdt.rs index ea977f53be..42314e9608 100644 --- a/contracts/modules/src/esdt.rs +++ b/contracts/modules/src/esdt.rs @@ -84,7 +84,9 @@ pub trait EsdtModule { fn nft_create(&self, amount: &BigUint, attributes: &T) -> u64 { let token_id = self.token_id().get(); let empty_buffer = ManagedBuffer::new(); - let empty_vec = ManagedVec::from_handle(empty_buffer.get_handle()); + + // sneakily reuses the same handle + let empty_vec = unsafe { ManagedRef::wrap_handle(empty_buffer.get_handle()) }; self.send().esdt_nft_create( &token_id, diff --git a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs index c499c9f663..e769bb69c7 100644 --- a/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/blockchain_wrapper.rs @@ -11,8 +11,8 @@ use crate::{ storage::{self}, types::{ BackTransfers, BigUint, CodeMetadata, EgldOrEsdtTokenIdentifier, EsdtLocalRoleFlags, - EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, ManagedType, - ManagedVec, TokenIdentifier, + EsdtTokenData, EsdtTokenType, ManagedAddress, ManagedBuffer, ManagedByteArray, + ManagedRefMut, ManagedType, ManagedVec, TokenIdentifier, }, }; @@ -49,9 +49,11 @@ where #[inline] pub fn get_caller(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_caller_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_caller_managed(result.get_handle()); + result + } } #[deprecated(since = "0.41.0", note = "Please use method `get_sc_address` instead.")] @@ -63,16 +65,20 @@ where #[inline] pub fn get_sc_address(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_sc_address_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_sc_address_managed(result.get_handle()); + result + } } #[inline] pub fn get_owner_address(&self) -> ManagedAddress { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_owner_address_managed(handle.clone()); - ManagedAddress::from_handle(handle) + unsafe { + let result = ManagedAddress::new_uninit(); + A::blockchain_api_impl().load_owner_address_managed(result.get_handle()); + result + } } pub fn check_caller_is_owner(&self) { @@ -123,16 +129,20 @@ where #[cfg(feature = "alloc")] #[inline] pub fn get_balance_legacy(&self, address: &crate::types::Address) -> BigUint { - let handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_balance_legacy(handle.clone(), address); - BigUint::from_handle(handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_balance_legacy(result.get_handle(), address); + result + } } #[inline] pub fn get_balance(&self, address: &ManagedAddress) -> BigUint { - let handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_balance(handle.clone(), address.get_handle()); - BigUint::from_handle(handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_balance(result.get_handle(), address.get_handle()); + result + } } #[inline] @@ -141,7 +151,10 @@ where A::blockchain_api_impl() .managed_get_code_metadata(address.get_handle(), mbuf_temp_1.clone()); let mut buffer = [0u8; 2]; - ManagedBuffer::::from_handle(mbuf_temp_1).load_to_byte_array(&mut buffer); + unsafe { + ManagedRefMut::<'static, A, ManagedBuffer>::wrap_handle(mbuf_temp_1) + .load_to_byte_array(&mut buffer); + } CodeMetadata::from(buffer) } @@ -173,9 +186,11 @@ where #[inline] pub fn get_state_root_hash(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_state_root_hash_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_state_root_hash_managed(result.get_handle()); + result + } } #[deprecated(since = "0.41.0", note = "Please use method `get_tx_hash` instead.")] @@ -187,9 +202,11 @@ where #[inline] pub fn get_tx_hash(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_tx_hash_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_tx_hash_managed(result.get_handle()); + result + } } #[inline] @@ -229,9 +246,11 @@ where #[inline] pub fn get_block_random_seed(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_block_random_seed_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_block_random_seed_managed(result.get_handle()); + result + } } #[inline] @@ -266,9 +285,11 @@ where #[inline] pub fn get_prev_block_random_seed(&self) -> ManagedByteArray { - let handle: A::ManagedBufferHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_prev_block_random_seed_managed(handle.clone()); - ManagedByteArray::from_handle(handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::blockchain_api_impl().load_prev_block_random_seed_managed(result.get_handle()); + result + } } #[inline] @@ -288,14 +309,16 @@ where token_id: &TokenIdentifier, nonce: u64, ) -> BigUint { - let result_handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); - A::blockchain_api_impl().load_esdt_balance( - address.get_handle(), - token_id.get_handle(), - nonce, - result_handle.clone(), - ); - BigUint::from_handle(result_handle) + unsafe { + let result = BigUint::new_uninit(); + A::blockchain_api_impl().load_esdt_balance( + address.get_handle(), + token_id.get_handle(), + nonce, + result.get_handle(), + ); + result + } } pub fn get_esdt_token_data( @@ -346,16 +369,18 @@ where let _ = managed_api_impl.mb_load_slice(properties_handle, 0, &mut properties_bytes[..]); let frozen = esdt_is_frozen(&properties_bytes); - EsdtTokenData { - token_type, - amount: BigUint::from_raw_handle(value_handle.get_raw_handle()), - frozen, - hash: ManagedBuffer::from_raw_handle(hash_handle.get_raw_handle()), - name: ManagedBuffer::from_raw_handle(name_handle.get_raw_handle()), - attributes: ManagedBuffer::from_raw_handle(attributes_handle.get_raw_handle()), - creator: ManagedAddress::from_raw_handle(creator_handle.get_raw_handle()), - royalties: BigUint::from_raw_handle(royalties_handle.get_raw_handle()), - uris: ManagedVec::from_raw_handle(uris_handle.get_raw_handle()), + unsafe { + EsdtTokenData { + token_type, + amount: BigUint::from_raw_handle(value_handle.get_raw_handle()), + frozen, + hash: ManagedBuffer::from_raw_handle(hash_handle.get_raw_handle()), + name: ManagedBuffer::from_raw_handle(name_handle.get_raw_handle()), + attributes: ManagedBuffer::from_raw_handle(attributes_handle.get_raw_handle()), + creator: ManagedAddress::from_raw_handle(creator_handle.get_raw_handle()), + royalties: BigUint::from_raw_handle(royalties_handle.get_raw_handle()), + uris: ManagedVec::from_raw_handle(uris_handle.get_raw_handle()), + } } } @@ -375,9 +400,13 @@ where call_value_handle.get_raw_handle(), ); - BackTransfers { - total_egld_amount: BigUint::from_raw_handle(call_value_handle.get_raw_handle()), - esdt_payments: ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), + unsafe { + BackTransfers { + total_egld_amount: BigUint::from_raw_handle(call_value_handle.get_raw_handle()), + esdt_payments: ManagedVec::from_raw_handle( + esdt_transfer_value_handle.get_raw_handle(), + ), + } } } @@ -441,13 +470,11 @@ where // load value A::storage_read_api_impl() .storage_load_managed_buffer_raw(temp_handle_1, temp_handle_2.clone()); - let result_handle: A::BigIntHandle = use_raw_handle(A::static_var_api_impl().next_handle()); // convert value to BigUint - A::managed_type_impl().mb_to_big_int_unsigned(temp_handle_2, result_handle.clone()); - - //wrap - BigUint::from_handle(result_handle) + let result = unsafe { BigUint::new_uninit() }; + A::managed_type_impl().mb_to_big_int_unsigned(temp_handle_2, result.get_handle()); + result } } diff --git a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs index 369cca1a63..3731d4a964 100644 --- a/framework/base/src/contract_base/wrappers/crypto_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/crypto_wrapper.rs @@ -1,10 +1,7 @@ use core::marker::PhantomData; use crate::{ - api::{ - use_raw_handle, CryptoApi, CryptoApiImpl, StaticVarApiImpl, KECCAK256_RESULT_LEN, - SHA256_RESULT_LEN, - }, + api::{CryptoApi, CryptoApiImpl, KECCAK256_RESULT_LEN, SHA256_RESULT_LEN}, types::{ManagedBuffer, ManagedByteArray, ManagedType, ManagedVec, MessageHashType}, }; @@ -30,30 +27,33 @@ where &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().sha256_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().sha256_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn keccak256>>( &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().keccak256_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().keccak256_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn ripemd160>>( &self, data: B, ) -> ManagedByteArray { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().ripemd160_managed(new_handle.clone(), data.borrow().get_handle()); - ManagedByteArray::from_handle(new_handle) + unsafe { + let result = ManagedByteArray::new_uninit(); + A::crypto_api_impl().ripemd160_managed(result.get_handle(), data.borrow().get_handle()); + result + } } pub fn verify_bls( @@ -122,14 +122,15 @@ where r: &ManagedBuffer, s: &ManagedBuffer, ) -> ManagedBuffer { - let new_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::crypto_api_impl().encode_secp256k1_der_signature_managed( - r.get_handle(), - s.get_handle(), - new_handle.clone(), - ); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::crypto_api_impl().encode_secp256k1_der_signature_managed( + r.get_handle(), + s.get_handle(), + result.get_handle(), + ); + result + } } /// Calls the Vm to verify secp256r1 signature. diff --git a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs index 5d290369df..07466ac234 100644 --- a/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_raw_wrapper.rs @@ -192,10 +192,12 @@ where new_address_handle, result_handle, ); - ( - ManagedAddress::from_raw_handle(new_address_handle), - ManagedVec::from_raw_handle(result_handle), - ) + unsafe { + ( + ManagedAddress::from_raw_handle(new_address_handle), + ManagedVec::from_raw_handle(result_handle), + ) + } } /// Deploys a new contract in the same shard by re-using the code of an already deployed source contract. @@ -222,10 +224,12 @@ where new_address_handle, result_handle, ); - ( - ManagedAddress::from_raw_handle(new_address_handle), - ManagedVec::from_raw_handle(result_handle), - ) + unsafe { + ( + ManagedAddress::from_raw_handle(new_address_handle), + ManagedVec::from_raw_handle(result_handle), + ) + } } pub fn upgrade_from_source_contract( @@ -291,7 +295,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } pub fn execute_on_same_context_raw( @@ -311,7 +315,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } /// Same shard, in-line execution of another contract. @@ -330,7 +334,7 @@ where arg_buffer.get_handle().get_raw_handle(), result_handle, ); - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } /// Allows synchronously calling a local function by name. Execution is resumed afterwards. @@ -357,8 +361,7 @@ where ); self.clean_return_data(); - - ManagedVec::from_raw_handle(result_handle) + unsafe { ManagedVec::from_raw_handle(result_handle) } } pub fn clean_return_data(&self) { diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs index 3a11bde247..0c23b67cd4 100644 --- a/framework/base/src/contract_base/wrappers/send_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs @@ -2,6 +2,7 @@ use core::marker::PhantomData; use crate::codec::Empty; +use crate::types::ManagedRef; use crate::{ api::{BlockchainApi, CallTypeApi, StorageReadApi}, codec, @@ -589,7 +590,9 @@ where ) -> u64 { let big_zero = BigUint::zero(); let empty_buffer = ManagedBuffer::new(); - let empty_vec = ManagedVec::from_handle(empty_buffer.get_handle()); + + // sneakily reuses the same handle + let empty_vec = unsafe { ManagedRef::wrap_handle(empty_buffer.get_handle()) }; self.esdt_nft_create( token, diff --git a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs index 7417d6ca52..9fd49e115b 100644 --- a/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs +++ b/framework/base/src/contract_base/wrappers/storage_raw_wrapper.rs @@ -59,7 +59,8 @@ where V: TopDecode, { let key: StorageKey = storage_key.into(); - let result_buffer = ManagedBuffer::::from_handle(use_raw_handle(MBUF_TEMPORARY_1)); + let result_buffer = + unsafe { ManagedBuffer::::from_handle(use_raw_handle(MBUF_TEMPORARY_1)) }; A::storage_read_api_impl().storage_load_from_address( address.get_handle(), key.get_handle(), diff --git a/framework/base/src/io/arg_de_input.rs b/framework/base/src/io/arg_de_input.rs index 98faef2899..7c84d9cbb9 100644 --- a/framework/base/src/io/arg_de_input.rs +++ b/framework/base/src/io/arg_de_input.rs @@ -1,10 +1,7 @@ use core::marker::PhantomData; use crate::{ - api::{ - use_raw_handle, EndpointArgumentApi, EndpointArgumentApiImpl, ManagedTypeApi, - StaticVarApiImpl, - }, + api::{EndpointArgumentApi, EndpointArgumentApiImpl, ManagedTypeApi}, codec::{ try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast, }, @@ -43,22 +40,34 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: AA::ManagedBufferHandle = - use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_managed_buffer(self.arg_index, mbuf_handle.clone()); - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + AA::argument_api_impl() + .load_argument_managed_buffer(self.arg_index, result.get_handle()); + result + } } fn to_big_int(&self) -> BigInt { - let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_big_int_signed(self.arg_index, bi_handle.clone()); - BigInt::from_handle(bi_handle) + unsafe { + let result = BigInt::new_uninit(); + AA::argument_api_impl() + .load_argument_big_int_signed(self.arg_index, result.get_handle()); + result + } } fn to_big_uint(&self) -> BigUint { - let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); - AA::argument_api_impl().load_argument_big_int_unsigned(self.arg_index, bi_handle.clone()); - BigUint::from_handle(bi_handle) + unsafe { + let result = BigUint::new_uninit(); + AA::argument_api_impl() + .load_argument_big_int_unsigned(self.arg_index, result.get_handle()); + result + } + + // let bi_handle: AA::BigIntHandle = use_raw_handle(AA::static_var_api_impl().next_handle()); + // AA::argument_api_impl().load_argument_big_int_unsigned(self.arg_index, bi_handle.clone()); + // BigUint::from_handle(bi_handle) } } diff --git a/framework/base/src/io/arg_nested_tuple.rs b/framework/base/src/io/arg_nested_tuple.rs index fca34c9886..1a0eaace7a 100644 --- a/framework/base/src/io/arg_nested_tuple.rs +++ b/framework/base/src/io/arg_nested_tuple.rs @@ -198,13 +198,15 @@ fn callback_closure_args_loader() -> ManagedResultArgLoader where AA: VMApi, { - AA::argument_api_impl() - .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); - let cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); - let mut cb_closure_args_buffer = - ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); - cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); - - ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) + unsafe { + AA::argument_api_impl() + .load_callback_closure_buffer(use_raw_handle(const_handles::MBUF_TEMPORARY_1)); + let cb_closure_args_serialized = + ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + let mut cb_closure_args_buffer = + ManagedArgBuffer::::from_raw_handle(const_handles::CALLBACK_CLOSURE_ARGS_BUFFER); + cb_closure_args_buffer.deserialize_overwrite(cb_closure_args_serialized); + + ManagedResultArgLoader::new(cb_closure_args_buffer.into_vec_of_buffers()) + } } diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index 85107896dd..b33b5e1dcb 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -3,7 +3,7 @@ use core::{convert::Infallible, marker::PhantomData}; use crate::{ api::{ const_handles, use_raw_handle, ErrorApi, ErrorApiImpl, HandleConstraints, - ManagedBufferApiImpl, ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + ManagedBufferApiImpl, ManagedTypeApi, StorageReadApi, StorageReadApiImpl, }, codec::*, err_msg, @@ -33,11 +33,12 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::storage_read_api_impl() - .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), mbuf_handle.clone()); - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl() + .storage_load_managed_buffer_raw(self.key.buffer.get_handle(), result.get_handle()); + result + } } fn to_big_uint(&self) -> BigUint { diff --git a/framework/base/src/storage/storage_get_from_address.rs b/framework/base/src/storage/storage_get_from_address.rs index 2b40987bd3..13a467d2f0 100644 --- a/framework/base/src/storage/storage_get_from_address.rs +++ b/framework/base/src/storage/storage_get_from_address.rs @@ -1,7 +1,7 @@ use crate::{ api::{ const_handles, use_raw_handle, ErrorApi, HandleConstraints, ManagedBufferApiImpl, - ManagedTypeApi, StaticVarApiImpl, StorageReadApi, StorageReadApiImpl, + ManagedTypeApi, StorageReadApi, StorageReadApiImpl, }, codec::*, types::{ @@ -35,15 +35,15 @@ where } fn to_managed_buffer(&self) -> ManagedBuffer { - let mbuf_handle: A::ManagedBufferHandle = - use_raw_handle(A::static_var_api_impl().next_handle()); - A::storage_read_api_impl().storage_load_from_address( - self.addr.get_handle(), - self.key.buffer.get_handle(), - mbuf_handle.clone(), - ); - - ManagedBuffer::from_handle(mbuf_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + A::storage_read_api_impl().storage_load_from_address( + self.addr.get_handle(), + self.key.buffer.get_handle(), + result.get_handle(), + ); + result + } } fn to_big_uint(&self) -> BigUint { diff --git a/framework/base/src/storage/storage_key.rs b/framework/base/src/storage/storage_key.rs index f692dd5266..b3a35643e1 100644 --- a/framework/base/src/storage/storage_key.rs +++ b/framework/base/src/storage/storage_key.rs @@ -22,7 +22,7 @@ where type OwnHandle = A::ManagedBufferHandle; #[inline] - fn from_handle(handle: A::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: A::ManagedBufferHandle) -> Self { StorageKey { buffer: ManagedBuffer::from_handle(handle), } diff --git a/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs index ee3726c0eb..f2d091e2b3 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/async_call_promises.rs @@ -1,5 +1,7 @@ +use core::ops::DerefMut; + use crate::{ - api::CallTypeApi, + api::{const_handles, CallTypeApi}, contract_base::SendRawWrapper, types::{BigUint, CallbackClosure, FunctionCall, ManagedAddress, ManagedBuffer}, }; @@ -41,16 +43,14 @@ where } pub fn register_promise(self) { - use crate::{api::const_handles, types::ManagedType}; - let mut cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + unsafe { ManagedBuffer::temp_const_ref_mut(const_handles::MBUF_TEMPORARY_1) }; let callback_name; if let Some(callback_call) = self.callback_call { callback_name = callback_call.callback_name; callback_call .closure_args - .serialize_overwrite(&mut cb_closure_args_serialized); + .serialize_overwrite(cb_closure_args_serialized.deref_mut()); } else { callback_name = ""; cb_closure_args_serialized.overwrite(&[]); diff --git a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs index 427218f1c8..f0f1722f24 100644 --- a/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs +++ b/framework/base/src/types/interaction/contract_call_legacy/contract_call_exec.rs @@ -36,10 +36,12 @@ where call_value_handle.get_raw_handle(), ); - ( - BigUint::from_raw_handle(call_value_handle.get_raw_handle()), - ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), - ) + unsafe { + ( + BigUint::from_raw_handle(call_value_handle.get_raw_handle()), + ManagedVec::from_raw_handle(esdt_transfer_value_handle.get_raw_handle()), + ) + } } pub fn to_call_data_string(&self) -> ManagedBuffer { diff --git a/framework/base/src/types/interaction/managed_arg_buffer.rs b/framework/base/src/types/interaction/managed_arg_buffer.rs index bd98c40931..009ad74e3a 100644 --- a/framework/base/src/types/interaction/managed_arg_buffer.rs +++ b/framework/base/src/types/interaction/managed_arg_buffer.rs @@ -33,7 +33,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedArgBuffer { data: ManagedVec::from_handle(handle), } diff --git a/framework/base/src/types/interaction/markers/to_caller.rs b/framework/base/src/types/interaction/markers/to_caller.rs index f24191ce9f..9066a16239 100644 --- a/framework/base/src/types/interaction/markers/to_caller.rs +++ b/framework/base/src/types/interaction/markers/to_caller.rs @@ -1,5 +1,5 @@ use crate::{ - api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + api::{const_handles, BlockchainApi, BlockchainApiImpl, CallTypeApi}, contract_base::BlockchainWrapper, types::{ AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, @@ -25,9 +25,11 @@ where where F: FnOnce(&ManagedAddress) -> R, { - let caller_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER); - Api::blockchain_api_impl().load_caller_managed(caller_handle.clone()); - f(&ManagedAddress::from_handle(caller_handle)) + unsafe { + let temp = ManagedAddress::temp_const_ref(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_caller_managed(temp.get_handle()); + f(&temp) + } } } diff --git a/framework/base/src/types/interaction/markers/to_self.rs b/framework/base/src/types/interaction/markers/to_self.rs index f339a448e2..8a78e13d6d 100644 --- a/framework/base/src/types/interaction/markers/to_self.rs +++ b/framework/base/src/types/interaction/markers/to_self.rs @@ -1,5 +1,5 @@ use crate::{ - api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi}, + api::{const_handles, BlockchainApi, BlockchainApiImpl, CallTypeApi}, contract_base::BlockchainWrapper, types::{ AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv, TxTo, TxToSpecified, @@ -26,10 +26,11 @@ where where F: FnOnce(&ManagedAddress) -> R, { - let sc_address_handle: Api::ManagedBufferHandle = - use_raw_handle(const_handles::ADDRESS_CALLER); - Api::blockchain_api_impl().load_sc_address_managed(sc_address_handle.clone()); - f(&ManagedAddress::from_handle(sc_address_handle)) + unsafe { + let temp = ManagedAddress::temp_const_ref(const_handles::ADDRESS_CALLER); + Api::blockchain_api_impl().load_sc_address_managed(temp.get_handle()); + f(&temp) + } } } diff --git a/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs index 38e38fcbcd..333bbf9379 100644 --- a/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs +++ b/framework/base/src/types/interaction/tx_exec/tx_exec_async_promises.rs @@ -3,8 +3,8 @@ use crate::{ contract_base::{ErrorHelper, SendRawWrapper}, types::{ interaction::callback_closure::CallbackClosureWithGas, CallbackClosure, ExplicitGas, - FunctionCall, ManagedBuffer, ManagedType, OriginalResultMarker, Tx, TxGas, TxGasValue, - TxPayment, TxResultHandler, TxScEnv, TxToSpecified, + FunctionCall, ManagedBuffer, OriginalResultMarker, Tx, TxGas, TxGasValue, TxPayment, + TxResultHandler, TxScEnv, TxToSpecified, }, }; @@ -160,7 +160,7 @@ where pub fn register_promise(self) { let callback_name = self.result_handler.callback_name(); let mut cb_closure_args_serialized = - ManagedBuffer::::from_raw_handle(const_handles::MBUF_TEMPORARY_1); + unsafe { ManagedBuffer::temp_const_ref_mut(const_handles::MBUF_TEMPORARY_1) }; self.result_handler .overwrite_with_serialized_args(&mut cb_closure_args_serialized); let extra_gas_for_callback = self.result_handler.gas_for_callback(); diff --git a/framework/base/src/types/managed/basic/big_float.rs b/framework/base/src/types/managed/basic/big_float.rs index 802d582e94..8361cb4b79 100644 --- a/framework/base/src/types/managed/basic/big_float.rs +++ b/framework/base/src/types/managed/basic/big_float.rs @@ -27,7 +27,7 @@ pub struct BigFloat { impl ManagedType for BigFloat { type OwnHandle = M::BigFloatHandle; - fn from_handle(handle: M::BigFloatHandle) -> Self { + unsafe fn from_handle(handle: M::BigFloatHandle) -> Self { BigFloat { handle } } @@ -88,7 +88,7 @@ macro_rules! big_float_conv_num { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_i64(new_bf_handle.clone(), value as i64); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } } }; @@ -105,28 +105,28 @@ impl BigFloat { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_neg(new_bf_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn abs(&self) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_abs(new_bf_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn from_big_uint(big_uint: &BigUint) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_uint.value.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn from_big_int(big_int: &BigInt) -> Self { let new_bf_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_set_bi(new_bf_handle.clone(), big_int.handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] @@ -138,42 +138,42 @@ impl BigFloat { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_parts(integral_part_value, fractional_part_value, exponent_value); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] pub fn from_frac(numerator_value: i64, denominator_value: i64) -> Self { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_frac(numerator_value, denominator_value); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } #[inline] pub fn from_sci(significand_value: i64, exponent_value: i32) -> Self { let api = M::managed_type_impl(); let new_bf_handle = api.bf_from_sci(significand_value, exponent_value as i64); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn trunc(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_trunc(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn floor(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_floor(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn ceil(&self) -> BigInt { let result: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let api = M::managed_type_impl(); api.bf_ceil(result.clone(), self.handle.clone()); - BigInt::from_handle(result) + unsafe { BigInt::from_handle(result) } } pub fn to_fixed_point(&self, denominator: &BigFloat) -> BigInt { @@ -254,7 +254,7 @@ impl BigFloat { #[inline] pub fn zero() -> Self { - BigFloat::from_handle(M::managed_type_impl().bf_new_zero()) + unsafe { BigFloat::from_handle(M::managed_type_impl().bf_new_zero()) } } pub fn from_buffer(managed_buffer: &ManagedBuffer) -> Self { @@ -262,14 +262,14 @@ impl BigFloat { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_to_big_float(managed_buffer.handle.clone(), new_bf_handle.clone()); - BigFloat::from_handle(new_bf_handle) + unsafe { BigFloat::from_handle(new_bf_handle) } } pub fn to_buffer(&self) -> ManagedBuffer { let new_man_buf_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_from_big_float(self.handle.clone(), new_man_buf_handle.clone()); - ManagedBuffer::from_handle(new_man_buf_handle) + unsafe { ManagedBuffer::from_handle(new_man_buf_handle) } } } @@ -278,14 +278,14 @@ impl BigFloat { let api = M::managed_type_impl(); let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bf_sqrt(new_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } pub fn pow(&self, exp: i32) -> Self { let api = M::managed_type_impl(); let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bf_pow(new_handle.clone(), self.handle.clone(), exp); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } /// Returns the sign of the `BigFloat` as a `Sign`. @@ -301,7 +301,7 @@ impl BigFloat { pub fn magnitude(&self) -> BigFloat { let result: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_abs(result.clone(), self.handle.clone()); - BigFloat::from_handle(result) + unsafe { BigFloat::from_handle(result) } } /// Convert this `BigFloat` into its `Sign` and its magnitude, @@ -343,7 +343,7 @@ impl Clone for BigFloat { fn clone(&self) -> Self { let new_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_clone(new_handle.clone(), self.handle.clone()); - BigFloat::from_handle(new_handle) + unsafe { BigFloat::from_handle(new_handle) } } } diff --git a/framework/base/src/types/managed/basic/big_float_operators.rs b/framework/base/src/types/managed/basic/big_float_operators.rs index 7874c1ab86..7333a69ebe 100644 --- a/framework/base/src/types/managed/basic/big_float_operators.rs +++ b/framework/base/src/types/managed/basic/big_float_operators.rs @@ -16,7 +16,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigFloat::from_handle(self.handle.clone()) + unsafe { BigFloat::from_handle(self.handle.clone()) } } } @@ -31,7 +31,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigFloat::from_handle(result_handle) + unsafe { BigFloat::from_handle(result_handle) } } } }; @@ -82,6 +82,6 @@ impl Neg for BigFloat { let result_handle: M::BigFloatHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().bf_neg(result_handle.clone(), self.handle); - BigFloat::from_handle(result_handle) + unsafe { BigFloat::from_handle(result_handle) } } } diff --git a/framework/base/src/types/managed/basic/big_int.rs b/framework/base/src/types/managed/basic/big_int.rs index cb52117c32..9727d81dd5 100644 --- a/framework/base/src/types/managed/basic/big_int.rs +++ b/framework/base/src/types/managed/basic/big_int.rs @@ -11,7 +11,9 @@ use crate::{ NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, TryStaticCast, }, formatter::{hex_util::encode_bytes_as_hex, FormatByteReceiver, SCDisplay}, - types::{heap::BoxedBytes, BigUint, ManagedBuffer, ManagedOption, ManagedType, Sign}, + types::{ + heap::BoxedBytes, BigUint, ManagedBuffer, ManagedOption, ManagedRef, ManagedType, Sign, + }, }; use super::cast_to_i64::cast_to_i64; @@ -25,7 +27,7 @@ pub struct BigInt { impl ManagedType for BigInt { type OwnHandle = M::BigIntHandle; - fn from_handle(handle: M::BigIntHandle) -> Self { + unsafe fn from_handle(handle: M::BigIntHandle) -> Self { BigInt { handle, _phantom: PhantomData, @@ -43,7 +45,6 @@ impl ManagedType for BigInt { fn transmute_from_handle_ref_mut(handle_ref: &mut M::BigIntHandle) -> &mut Self { unsafe { core::mem::transmute(handle_ref) } } - } impl Default for BigInt { @@ -68,6 +69,16 @@ impl From> for BigInt { } impl BigInt { + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + let new_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); + BigInt::from_handle(new_handle) + } + pub(crate) fn set_value(handle: M::BigIntHandle, value: T) where T: TryInto, @@ -88,7 +99,7 @@ impl BigInt { impl From> for BigInt { #[inline] fn from(item: BigUint) -> Self { - BigInt::from_handle(item.get_handle()) + item.into_big_int() } } @@ -100,7 +111,7 @@ macro_rules! big_int_conv_num { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); Self::set_value(handle.clone(), value); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } } @@ -157,9 +168,8 @@ impl BigInt { #[inline] pub fn zero() -> Self { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - // TODO: seting 0 will no longer be needed once we fix VM handle error M::managed_type_impl().bi_set_int64(handle.clone(), 0); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -178,7 +188,7 @@ impl BigInt { M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_to_big_int_signed(mb_handle, handle.clone()); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -192,7 +202,7 @@ impl BigInt { pub fn from_signed_bytes_be_buffer(managed_buffer: &ManagedBuffer) -> Self { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_to_big_int_signed(managed_buffer.handle.clone(), handle.clone()); - BigInt::from_handle(handle) + unsafe { BigInt::from_handle(handle) } } #[inline] @@ -200,7 +210,7 @@ impl BigInt { let mb_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl().mb_from_big_int_signed(self.handle.clone(), mb_handle.clone()); - ManagedBuffer::from_handle(mb_handle) + unsafe { ManagedBuffer::from_handle(mb_handle) } } } @@ -214,7 +224,7 @@ impl Clone for BigInt { clone_handle.clone(), self.handle.clone(), ); - BigInt::from_handle(clone_handle) + unsafe { BigInt::from_handle(clone_handle) } } } @@ -224,7 +234,7 @@ impl BigInt { if sign.is_minus() { api.bi_neg(unsigned.value.handle.clone(), unsigned.value.handle.clone()); } - BigInt::from_handle(unsigned.value.handle) + unsafe { BigInt::from_handle(unsigned.value.handle) } } /// Returns the sign of the `BigInt` as a `Sign`. @@ -242,7 +252,7 @@ impl BigInt { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_abs(result_handle.clone(), self.handle.clone()); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } /// Convert this `BigInt` into its `Sign` and `BigUint` magnitude, @@ -335,7 +345,7 @@ impl BigInt { let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); let exp_handle = BigUint::::make_temp(const_handles::BIG_INT_TEMPORARY_1, exp); M::managed_type_impl().bi_pow(result_handle.clone(), self.handle.clone(), exp_handle); - BigInt::from_handle(result_handle) + unsafe { BigInt::from_handle(result_handle) } } } @@ -343,9 +353,9 @@ impl SCDisplay for BigInt { fn fmt(&self, f: &mut F) { let str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().bi_to_string(self.handle.clone(), str_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - str_handle.cast_or_signal_error::(), - )); + let cast_handle = str_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } diff --git a/framework/base/src/types/managed/basic/big_int_operators.rs b/framework/base/src/types/managed/basic/big_int_operators.rs index fed47d5a26..0cf00c66e6 100644 --- a/framework/base/src/types/managed/basic/big_int_operators.rs +++ b/framework/base/src/types/managed/basic/big_int_operators.rs @@ -19,7 +19,7 @@ macro_rules! binary_operator { self.handle.clone(), other.handle.clone(), ); - BigInt::from_handle(self.handle.clone()) + self } } @@ -44,14 +44,15 @@ macro_rules! binary_operator { fn $method(self, other: &BigInt) -> BigInt { let api = M::managed_type_impl(); - let result_handle: M::BigIntHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - api.$api_func( - result_handle.clone(), - self.handle.clone(), - other.handle.clone(), - ); - BigInt::from_handle(result_handle) + unsafe { + let result = BigInt::new_uninit(); + api.$api_func( + result.get_handle(), + self.handle.clone(), + other.handle.clone(), + ); + result + } } } @@ -59,7 +60,7 @@ macro_rules! binary_operator { type Output = BigInt; fn $method(self, other: &BigUint) -> BigInt { - self.$method(&BigInt::from_handle(other.get_handle())) + self.$method(other.as_big_int()) } } @@ -67,7 +68,7 @@ macro_rules! binary_operator { type Output = BigInt; fn $method(self, other: &BigInt) -> BigInt { - (&BigInt::from_handle(self.get_handle())).$method(other) + self.as_big_int().$method(other) } } }; @@ -120,6 +121,6 @@ impl Neg for BigInt { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_neg(result_handle.clone(), self.handle); - BigInt::from_handle(result_handle) + unsafe { BigInt::from_handle(result_handle) } } } diff --git a/framework/base/src/types/managed/basic/elliptic_curve.rs b/framework/base/src/types/managed/basic/elliptic_curve.rs index 8c110f6459..2cc7097a18 100644 --- a/framework/base/src/types/managed/basic/elliptic_curve.rs +++ b/framework/base/src/types/managed/basic/elliptic_curve.rs @@ -35,7 +35,7 @@ pub struct EllipticCurve { impl ManagedType for EllipticCurve { type OwnHandle = M::EllipticCurveHandle; - fn from_handle(handle: M::EllipticCurveHandle) -> Self { + unsafe fn from_handle(handle: M::EllipticCurveHandle) -> Self { EllipticCurve { handle } } @@ -55,12 +55,12 @@ impl ManagedType for EllipticCurve { impl EllipticCurve { pub fn from_name(name: &ManagedBuffer) -> Self { let handle = M::managed_type_impl().ec_create_from_name_mb(name.get_handle()); - EllipticCurve::from_handle(handle) + unsafe { EllipticCurve::from_handle(handle) } } pub fn from_name_str(name: &str) -> Self { let handle = M::managed_type_impl().ec_create_from_name_bytes(name.as_bytes()); - EllipticCurve::from_handle(handle) + unsafe { EllipticCurve::from_handle(handle) } } pub fn from_bitsize(bitsize: u32) -> Option { @@ -88,14 +88,16 @@ impl EllipticCurve { x_base_point_handle.clone(), y_base_point_handle.clone(), ); - ( - BigUint::from_handle(field_order_handle), - BigUint::from_handle(base_point_order_handle), - BigUint::from_handle(eq_constant_handle), - BigUint::from_handle(x_base_point_handle), - BigUint::from_handle(y_base_point_handle), - api.ec_curve_length(self.handle.clone()), - ) + unsafe { + ( + BigUint::from_handle(field_order_handle), + BigUint::from_handle(base_point_order_handle), + BigUint::from_handle(eq_constant_handle), + BigUint::from_handle(x_base_point_handle), + BigUint::from_handle(y_base_point_handle), + api.ec_curve_length(self.handle.clone()), + ) + } } pub fn get_curve_length(&self) -> u32 { @@ -127,10 +129,12 @@ impl EllipticCurve { x_second_point.value.handle, y_second_point.value.handle, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn double(&self, x_point: BigUint, y_point: BigUint) -> (BigUint, BigUint) { @@ -144,10 +148,12 @@ impl EllipticCurve { x_point.value.handle, y_point.value.handle, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn is_on_curve(&self, x_point: BigUint, y_point: BigUint) -> bool { @@ -177,10 +183,12 @@ impl EllipticCurve { y_point.value.handle, data, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn scalar_mult( @@ -200,10 +208,12 @@ impl EllipticCurve { y_point.value.handle, data.get_handle(), ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } #[deprecated( @@ -220,10 +230,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } pub fn scalar_base_mult(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -236,10 +248,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_result_handle), - BigUint::from_handle(y_result_handle), - ) + unsafe { + ( + BigUint::from_handle(x_result_handle), + BigUint::from_handle(y_result_handle), + ) + } } #[deprecated(since = "0.41.0", note = "Please use method `marshal` instead.")] @@ -266,7 +280,7 @@ impl EllipticCurve { y_pair.value.handle, result_handle.clone(), ); - ManagedBuffer::from_handle(result_handle) + unsafe { ManagedBuffer::from_handle(result_handle) } } #[deprecated( @@ -296,7 +310,7 @@ impl EllipticCurve { y_pair.value.handle, result_handle.clone(), ); - ManagedBuffer::from_handle(result_handle) + unsafe { ManagedBuffer::from_handle(result_handle) } } #[deprecated(since = "0.41.0", note = "Please use method `unmarshal` instead.")] @@ -310,10 +324,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } pub fn unmarshal(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -326,10 +342,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } #[deprecated( @@ -346,10 +364,12 @@ impl EllipticCurve { self.handle.clone(), data, ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } pub fn unmarshal_compressed(&self, data: &ManagedBuffer) -> (BigUint, BigUint) { @@ -362,10 +382,12 @@ impl EllipticCurve { self.handle.clone(), data.get_handle(), ); - ( - BigUint::from_handle(x_pair_handle), - BigUint::from_handle(y_pair_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pair_handle), + BigUint::from_handle(y_pair_handle), + ) + } } #[deprecated(since = "0.41.0", note = "Please use method `generate_key` instead.")] @@ -379,11 +401,13 @@ impl EllipticCurve { y_pub_key_handle.clone(), self.handle.clone(), ); - ( - BigUint::from_handle(x_pub_key_handle), - BigUint::from_handle(y_pub_key_handle), - private_key, - ) + unsafe { + ( + BigUint::from_handle(x_pub_key_handle), + BigUint::from_handle(y_pub_key_handle), + private_key, + ) + } } pub fn generate_key(&self) -> (BigUint, BigUint, ManagedBuffer) { @@ -398,11 +422,13 @@ impl EllipticCurve { self.handle.clone(), private_key_handle.clone(), ); - ( - BigUint::from_handle(x_pub_key_handle), - BigUint::from_handle(y_pub_key_handle), - ManagedBuffer::from_handle(private_key_handle), - ) + unsafe { + ( + BigUint::from_handle(x_pub_key_handle), + BigUint::from_handle(y_pub_key_handle), + ManagedBuffer::from_handle(private_key_handle), + ) + } } } diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index 34ba82da14..d1e0b52f9e 100644 --- a/framework/base/src/types/managed/basic/managed_buffer.rs +++ b/framework/base/src/types/managed/basic/managed_buffer.rs @@ -2,7 +2,7 @@ use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, api::{ use_raw_handle, ErrorApiImpl, HandleConstraints, InvalidSliceError, ManagedBufferApiImpl, - ManagedTypeApi, StaticVarApiImpl, + ManagedTypeApi, RawHandle, StaticVarApiImpl, }, codec::{ DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput, @@ -14,7 +14,8 @@ use crate::{ SCLowerHex, }, types::{ - heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedType, StaticBufferRef, + heap::BoxedBytes, ManagedBufferCachedBuilder, ManagedRef, ManagedRefMut, ManagedType, + StaticBufferRef, }, }; @@ -28,7 +29,7 @@ impl ManagedType for ManagedBuffer { type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedBuffer { handle } } @@ -48,29 +49,61 @@ impl ManagedType for ManagedBuffer { impl ManagedBuffer { #[inline] pub fn new() -> Self { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - // TODO: remove after VM no longer crashes with "unknown handle": - M::managed_type_impl().mb_overwrite(new_handle.clone(), &[]); - ManagedBuffer::from_handle(new_handle) + Self::new_from_bytes(&[]) } #[inline] pub fn new_from_bytes(bytes: &[u8]) -> Self { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_overwrite(new_handle.clone(), bytes); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_overwrite(result.get_handle(), bytes); + result + } } #[inline] pub fn new_random(nr_bytes: usize) -> Self { + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_set_random(result.get_handle(), nr_bytes); + result + } + } + + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { let new_handle: M::ManagedBufferHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_set_random(new_handle.clone(), nr_bytes); ManagedBuffer::from_handle(new_handle) } + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + + pub unsafe fn temp_const_ref( + raw_handle: RawHandle, + ) -> ManagedRef<'static, M, ManagedBuffer> { + ManagedRef::wrap_handle(use_raw_handle(raw_handle)) + } + + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + pub unsafe fn temp_const_ref_mut( + raw_handle: RawHandle, + ) -> ManagedRefMut<'static, M, ManagedBuffer> { + ManagedRefMut::wrap_handle(use_raw_handle(raw_handle)) + } + fn load_static_cache(&self) -> StaticBufferRef where M: ManagedTypeApi, @@ -239,7 +272,7 @@ impl ManagedBuffer { result_handle.clone(), ); if err_result.is_ok() { - Some(ManagedBuffer::from_handle(result_handle)) + Some(unsafe { ManagedBuffer::from_handle(result_handle) }) } else { None } @@ -352,7 +385,7 @@ impl Clone for ManagedBuffer { let api = M::managed_type_impl(); let clone_handle = api.mb_new_empty(); api.mb_append(clone_handle.clone(), self.handle.clone()); - ManagedBuffer::from_handle(clone_handle) + unsafe { ManagedBuffer::from_handle(clone_handle) } } } @@ -482,9 +515,9 @@ impl TypeAbi for ManagedBuffer { impl SCDisplay for ManagedBuffer { fn fmt(&self, f: &mut F) { - f.append_managed_buffer(&ManagedBuffer::from_handle( - self.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } @@ -493,18 +526,18 @@ impl SCLowerHex for ManagedBuffer { let hex_handle: M::ManagedBufferHandle = use_raw_handle(crate::api::const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_to_hex(self.handle.clone(), hex_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - hex_handle.cast_or_signal_error::(), - )); + let cast_handle = hex_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } impl SCBinary for ManagedBuffer { fn fmt(&self, f: &mut F) { // TODO: in Rust thr `0b` prefix appears only when writing "{:#x}", not "{:x}" - f.append_managed_buffer_binary(&ManagedBuffer::from_handle( - self.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_binary(&wrap_cast); } } diff --git a/framework/base/src/types/managed/basic/managed_map.rs b/framework/base/src/types/managed/basic/managed_map.rs index ed39011f8d..0d7cc2f1b4 100644 --- a/framework/base/src/types/managed/basic/managed_map.rs +++ b/framework/base/src/types/managed/basic/managed_map.rs @@ -15,7 +15,7 @@ impl ManagedType for ManagedMap { type OwnHandle = M::ManagedMapHandle; #[inline] - fn from_handle(handle: M::ManagedMapHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedMapHandle) -> Self { ManagedMap { handle } } @@ -35,7 +35,7 @@ impl ManagedType for ManagedMap { impl ManagedMap { pub fn new() -> Self { let new_handle = M::managed_type_impl().mm_new(); - ManagedMap::from_handle(new_handle) + unsafe { ManagedMap::from_handle(new_handle) } } } @@ -48,10 +48,15 @@ impl Default for ManagedMap { impl ManagedMap { pub fn get(&self, key: &ManagedBuffer) -> ManagedBuffer { - let new_handle: M::ManagedBufferHandle = - use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mm_get(self.handle.clone(), key.handle.clone(), new_handle.clone()); - ManagedBuffer::from_handle(new_handle) + unsafe { + let result = ManagedBuffer::new_uninit(); + M::managed_type_impl().mm_get( + self.handle.clone(), + key.handle.clone(), + result.get_handle(), + ); + result + } } pub fn put(&mut self, key: &ManagedBuffer, value: &ManagedBuffer) { @@ -70,7 +75,7 @@ impl ManagedMap { key.handle.clone(), new_handle.clone(), ); - ManagedBuffer::from_handle(new_handle) + unsafe { ManagedBuffer::from_handle(new_handle) } } pub fn contains(&self, key: &ManagedBuffer) -> bool { diff --git a/framework/base/src/types/managed/managed_type_trait.rs b/framework/base/src/types/managed/managed_type_trait.rs index e7b97e2ab6..ca9210d594 100644 --- a/framework/base/src/types/managed/managed_type_trait.rs +++ b/framework/base/src/types/managed/managed_type_trait.rs @@ -7,12 +7,12 @@ pub trait ManagedType: Sized { type OwnHandle: HandleConstraints; #[doc(hidden)] - fn from_handle(handle: Self::OwnHandle) -> Self; + unsafe fn from_handle(handle: Self::OwnHandle) -> Self; fn get_handle(&self) -> Self::OwnHandle; #[doc(hidden)] - fn from_raw_handle(handle: RawHandle) -> Self { + unsafe fn from_raw_handle(handle: RawHandle) -> Self { Self::from_handle(Self::OwnHandle::new(handle)) } diff --git a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs index 04dbde9357..31d9a25e64 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_encoded.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_encoded.rs @@ -115,7 +115,7 @@ where M: ManagedTypeApi, { pub fn to_arg_buffer(&self) -> ManagedArgBuffer { - ManagedArgBuffer::from_handle(self.raw_buffers.get_handle()) + unsafe { ManagedArgBuffer::from_handle(self.raw_buffers.get_handle()) } } } diff --git a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs index e628ba8421..6ad36a25e8 100644 --- a/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs +++ b/framework/base/src/types/managed/multi_value/multi_value_managed_vec.rs @@ -46,7 +46,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { Self(ManagedVec::from_handle(handle)) } diff --git a/framework/base/src/types/managed/wrapped/big_uint.rs b/framework/base/src/types/managed/wrapped/big_uint.rs index dfba440073..fc717e70c6 100644 --- a/framework/base/src/types/managed/wrapped/big_uint.rs +++ b/framework/base/src/types/managed/wrapped/big_uint.rs @@ -26,7 +26,7 @@ pub struct BigUint { impl ManagedType for BigUint { type OwnHandle = M::BigIntHandle; - fn from_handle(handle: M::BigIntHandle) -> Self { + unsafe fn from_handle(handle: M::BigIntHandle) -> Self { BigUint { value: BigInt::from_handle(handle), } @@ -66,6 +66,17 @@ impl From<&ManagedBuffer> for BigUint { } impl BigUint { + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + BigUint { + value: BigInt::new_uninit(), + } + } + pub(crate) fn set_value(handle: M::BigIntHandle, value: T) where T: TryInto + num_traits::Unsigned, @@ -77,9 +88,11 @@ impl BigUint { where T: TryInto + num_traits::Unsigned, { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - Self::set_value(handle.clone(), value); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + Self::set_value(result.get_handle(), value); + result + } } pub(crate) fn make_temp(handle: RawHandle, value: T) -> M::BigIntHandle @@ -173,9 +186,11 @@ impl Default for BigUint { impl BigUint { #[inline] pub fn zero() -> Self { - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().bi_set_int64(handle.clone(), 0); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().bi_set_int64(result.get_handle(), 0); + result + } } pub fn zero_ref() -> ManagedRef<'static, M, BigUint> { @@ -199,9 +214,11 @@ impl BigUint { pub fn from_bytes_be(bytes: &[u8]) -> Self { let mb_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().mb_overwrite(mb_handle.clone(), bytes); - let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); - M::managed_type_impl().mb_to_big_int_unsigned(mb_handle, handle.clone()); - BigUint::from_handle(handle) + unsafe { + let result = Self::new_uninit(); + M::managed_type_impl().mb_to_big_int_unsigned(mb_handle, result.get_handle()); + result + } } #[inline] @@ -217,7 +234,7 @@ impl BigUint { let handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_to_big_int_unsigned(managed_buffer.handle.clone(), handle.clone()); - BigUint::from_handle(handle) + unsafe { BigUint::from_handle(handle) } } #[inline] @@ -226,7 +243,7 @@ impl BigUint { use_raw_handle(M::static_var_api_impl().next_handle()); M::managed_type_impl() .mb_from_big_int_unsigned(self.value.handle.clone(), mb_handle.clone()); - ManagedBuffer::from_handle(mb_handle) + unsafe { ManagedBuffer::from_handle(mb_handle) } } } @@ -237,7 +254,7 @@ impl BigUint { let api = M::managed_type_impl(); let result_handle: M::BigIntHandle = use_raw_handle(M::static_var_api_impl().next_handle()); api.bi_sqrt(result_handle.clone(), self.value.handle.clone()); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } #[must_use] @@ -249,7 +266,7 @@ impl BigUint { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } /// The whole part of the base-2 logarithm. @@ -310,7 +327,7 @@ impl Clone for BigUint { clone_handle.clone(), self.value.handle.clone(), ); - BigUint::from_handle(clone_handle) + unsafe { BigUint::from_handle(clone_handle) } } } @@ -376,9 +393,9 @@ impl SCDisplay for BigUint { fn fmt(&self, f: &mut F) { let str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1); M::managed_type_impl().bi_to_string(self.value.handle.clone(), str_handle.clone()); - f.append_managed_buffer(&ManagedBuffer::from_handle( - str_handle.cast_or_signal_error::(), - )); + let cast_handle = str_handle.cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } diff --git a/framework/base/src/types/managed/wrapped/big_uint_operators.rs b/framework/base/src/types/managed/wrapped/big_uint_operators.rs index 934079eef7..a4becdcf10 100644 --- a/framework/base/src/types/managed/wrapped/big_uint_operators.rs +++ b/framework/base/src/types/managed/wrapped/big_uint_operators.rs @@ -18,7 +18,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -33,7 +33,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } @@ -46,7 +46,7 @@ macro_rules! binary_operator { self.value.handle.clone(), other.value.handle.clone(), ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -60,7 +60,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -77,7 +77,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } @@ -91,7 +91,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(self.value.handle.clone()) + self } } @@ -108,7 +108,7 @@ macro_rules! binary_operator { self.value.handle.clone(), big_int_temp_1, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } }; @@ -207,7 +207,7 @@ macro_rules! shift_traits { self.value.handle.clone(), rhs, ); - BigUint::from_handle(result_handle) + unsafe { BigUint::from_handle(result_handle) } } } }; diff --git a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs index 19506645a2..97bf533e69 100644 --- a/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/egld_or_esdt_token_identifier.rs @@ -58,7 +58,7 @@ impl EgldOrEsdtTokenIdentifier { pub fn from_opt_raw_handle(opt_handle: Option) -> Self { match opt_handle { - Some(handle) => Self::esdt(TokenIdentifier::from_handle(handle)), + Some(handle) => Self::esdt(unsafe { TokenIdentifier::from_handle(handle) }), None => Self::egld(), } } @@ -240,9 +240,12 @@ impl TypeAbi for EgldOrEsdtTokenIdentifier { impl SCDisplay for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { if let Some(token_identifier) = self.data.as_option() { - f.append_managed_buffer(&ManagedBuffer::from_handle( - token_identifier.get_handle().cast_or_signal_error::(), - )); + let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); + // f.append_managed_buffer(&ManagedBuffer::from_handle( + // token_identifier.get_handle().cast_or_signal_error::(), + // )); } else { f.append_bytes(Self::EGLD_REPRESENTATION); } @@ -254,9 +257,12 @@ const EGLD_REPRESENTATION_HEX: &[u8] = b"45474C44"; impl SCLowerHex for EgldOrEsdtTokenIdentifier { fn fmt(&self, f: &mut F) { if let Some(token_identifier) = self.data.as_option() { - f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( - token_identifier.get_handle().cast_or_signal_error::(), - )); + let cast_handle = token_identifier.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_lower_hex(&wrap_cast); + // f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( + // token_identifier.get_handle().cast_or_signal_error::(), + // )); } else { f.append_bytes(EGLD_REPRESENTATION_HEX); } diff --git a/framework/base/src/types/managed/wrapped/managed_address.rs b/framework/base/src/types/managed/wrapped/managed_address.rs index 18473419e4..a12200a039 100644 --- a/framework/base/src/types/managed/wrapped/managed_address.rs +++ b/framework/base/src/types/managed/wrapped/managed_address.rs @@ -2,7 +2,7 @@ use core::convert::{TryFrom, TryInto}; use crate::{ abi::{TypeAbi, TypeAbiFrom, TypeName}, - api::ManagedTypeApi, + api::{use_raw_handle, ManagedTypeApi, RawHandle}, codec::{ DecodeError, DecodeErrorHandler, EncodeErrorHandler, NestedDecode, NestedDecodeInput, NestedEncode, NestedEncodeOutput, TopDecode, TopDecodeInput, TopEncode, TopEncodeOutput, @@ -11,6 +11,8 @@ use crate::{ types::{heap::Address, ManagedBuffer, ManagedByteArray, ManagedType}, }; +use super::ManagedRef; + #[repr(transparent)] #[derive(Clone)] pub struct ManagedAddress { @@ -49,6 +51,28 @@ where } } + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + ManagedAddress { + bytes: ManagedByteArray::new_uninit(), + } + } + + /// Creates a shared managed reference to a given raw handle. + /// + /// ## Safety + /// + /// The reference points to a shared value. Make sure the handle is not leaked. + pub unsafe fn temp_const_ref( + raw_handle: RawHandle, + ) -> ManagedRef<'static, M, ManagedAddress> { + ManagedRef::wrap_handle(use_raw_handle(raw_handle)) + } + #[inline] pub fn as_managed_buffer(&self) -> &ManagedBuffer { self.bytes.as_managed_buffer() @@ -133,7 +157,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedAddress { bytes: ManagedByteArray::from_handle(handle), } diff --git a/framework/base/src/types/managed/wrapped/managed_byte_array.rs b/framework/base/src/types/managed/wrapped/managed_byte_array.rs index 9d7b15d2b7..5ef3e661b7 100644 --- a/framework/base/src/types/managed/wrapped/managed_byte_array.rs +++ b/framework/base/src/types/managed/wrapped/managed_byte_array.rs @@ -35,7 +35,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedByteArray { buffer: ManagedBuffer::from_handle(handle), } @@ -85,6 +85,17 @@ where } } + /// Creates a new object, without initializing it. + /// + /// ## Safety + /// + /// The value needs to be initialized after creation, otherwise the VM will halt the first time the value is attempted to be read. + pub unsafe fn new_uninit() -> Self { + ManagedByteArray { + buffer: ManagedBuffer::new_uninit(), + } + } + /// Number of items. #[inline] pub fn len(&self) -> usize { diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs index 41f173a50a..698b2fbbee 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_logarithm.rs @@ -2,7 +2,7 @@ use super::decimals::{ConstDecimals, Decimals}; use super::ManagedDecimalSigned; use super::{ManagedDecimal, NumDecimals}; -use crate::proxy_imports::ManagedType; +use crate::types::ManagedRef; use crate::{ api::ManagedTypeApi, contract_base::ErrorHelper, @@ -104,7 +104,7 @@ impl ManagedDecimalSigned { return None; } - let bu = BigUint::from_handle(self.data.handle.clone()); + let bu = unsafe { ManagedRef::wrap_handle(self.data.handle.clone()) }; compute_ln(&bu, self.decimals.num_decimals()) } @@ -118,7 +118,8 @@ impl ManagedDecimalSigned { return None; } - let bu = BigUint::from_handle(self.data.handle.clone()); + let bu = unsafe { ManagedRef::wrap_handle(self.data.handle.clone()) }; + // let bu = BigUint::from_handle(self.data.handle.clone()); compute_log2(&bu, self.decimals.num_decimals()) } } diff --git a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs index c8ee403f37..0338417f82 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal/managed_decimal_signed.rs @@ -6,7 +6,7 @@ use crate::{ }, err_msg, formatter::{FormatBuffer, FormatByteReceiver, SCDisplay}, - types::{BigFloat, BigInt, BigUint, ManagedBuffer, ManagedType, Sign}, + types::{BigFloat, BigInt, BigUint, Sign}, }; use alloc::string::ToString; @@ -354,15 +354,15 @@ pub(super) fn managed_decimal_fmt( if len > num_dec { let temp_str_handle: M::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_2); + let cast_handle = temp_str_handle.clone().cast_or_signal_error::(); + let temp_str_ref = unsafe { ManagedRef::wrap_handle(cast_handle) }; let _ = M::managed_type_impl().mb_copy_slice( full_str_handle.clone(), 0, len - num_dec, temp_str_handle.clone(), ); - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - temp_str_handle.get_raw_handle(), - )); + f.append_managed_buffer(&temp_str_ref); f.append_bytes(b"."); let _ = M::managed_type_impl().mb_copy_slice( full_str_handle.clone(), @@ -370,17 +370,15 @@ pub(super) fn managed_decimal_fmt( num_dec, temp_str_handle.clone(), ); - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - temp_str_handle.get_raw_handle(), - )); + f.append_managed_buffer(&temp_str_ref); } else { f.append_bytes(b"0."); for _ in len..num_dec { f.append_bytes(b"0"); } - f.append_managed_buffer(&ManagedBuffer::from_raw_handle( - full_str_handle.get_raw_handle(), - )); + let cast_handle = full_str_handle.clone().cast_or_signal_error::(); + let full_str_ref = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&full_str_ref); } } diff --git a/framework/base/src/types/managed/wrapped/managed_option.rs b/framework/base/src/types/managed/wrapped/managed_option.rs index e448ae8e88..e433913835 100644 --- a/framework/base/src/types/managed/wrapped/managed_option.rs +++ b/framework/base/src/types/managed/wrapped/managed_option.rs @@ -143,7 +143,7 @@ where F: FnOnce(Context, &T) -> R, { if self.is_some() { - f(context, &T::from_handle(self.handle.clone())) + f(context, unsafe { &T::from_handle(self.handle.clone()) }) } else { default(context) } @@ -158,7 +158,7 @@ where #[allow(clippy::redundant_clone)] // the clone is not redundant fn clone(&self) -> Self { if self.is_some() { - Self::some(T::from_handle(self.handle.clone()).clone()) + Self::some(unsafe { T::from_handle(self.handle.clone()) }.clone()) } else { Self::none() } @@ -177,7 +177,10 @@ where return true; } if self.is_some() && other.is_some() { - return T::from_handle(self.handle.clone()) == T::from_handle(other.handle.clone()); + unsafe { + return ManagedRef::<'_, _, T>::wrap_handle(self.handle.clone()) + == ManagedRef::<'_, _, T>::wrap_handle(other.handle.clone()); + } } false } @@ -327,7 +330,7 @@ where fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { if self.is_some() { f.debug_tuple("ManagedOption::Some") - .field(&T::from_handle(self.handle.clone())) + .field(unsafe { &T::from_handle(self.handle.clone()) }) .finish() } else { f.write_str("ManagedOption::None") diff --git a/framework/base/src/types/managed/wrapped/managed_ref.rs b/framework/base/src/types/managed/wrapped/managed_ref.rs index 143d79e1d4..ef0e20fb9f 100644 --- a/framework/base/src/types/managed/wrapped/managed_ref.rs +++ b/framework/base/src/types/managed/wrapped/managed_ref.rs @@ -34,7 +34,7 @@ where /// Will completely disregard lifetimes, use with care. #[doc(hidden)] - pub(crate) unsafe fn wrap_handle(handle: T::OwnHandle) -> Self { + pub unsafe fn wrap_handle(handle: T::OwnHandle) -> Self { Self { _phantom_m: PhantomData, _phantom_t: PhantomData, diff --git a/framework/base/src/types/managed/wrapped/managed_vec.rs b/framework/base/src/types/managed/wrapped/managed_vec.rs index eb79ffebcd..582054e6ec 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec.rs @@ -45,7 +45,7 @@ where type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { ManagedVec { buffer: ManagedBuffer::from_handle(handle), _phantom: PhantomData, @@ -768,4 +768,3 @@ where } } } - diff --git a/framework/base/src/types/managed/wrapped/managed_vec_item.rs b/framework/base/src/types/managed/wrapped/managed_vec_item.rs index 8e7dc5512a..8e88624d75 100644 --- a/framework/base/src/types/managed/wrapped/managed_vec_item.rs +++ b/framework/base/src/types/managed/wrapped/managed_vec_item.rs @@ -192,7 +192,7 @@ macro_rules! impl_managed_type { fn from_byte_reader(reader: Reader) -> Self { let handle = <$ty as ManagedType>::OwnHandle::from_byte_reader(reader); - $ty::from_handle(handle) + unsafe { $ty::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -226,7 +226,7 @@ where fn from_byte_reader(reader: Reader) -> Self { let handle = >::OwnHandle::from_byte_reader(reader); - Self::from_handle(handle) + unsafe { Self::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( @@ -255,7 +255,7 @@ where fn from_byte_reader(reader: Reader) -> Self { let handle = M::ManagedBufferHandle::from_byte_reader(reader); - Self::from_handle(handle) + unsafe { Self::from_handle(handle) } } unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>( diff --git a/framework/base/src/types/managed/wrapped/token_identifier.rs b/framework/base/src/types/managed/wrapped/token_identifier.rs index 69481772e0..10c92475a3 100644 --- a/framework/base/src/types/managed/wrapped/token_identifier.rs +++ b/framework/base/src/types/managed/wrapped/token_identifier.rs @@ -9,7 +9,7 @@ use crate::{ types::{ManagedBuffer, ManagedType}, }; -use super::EgldOrEsdtTokenIdentifier; +use super::{EgldOrEsdtTokenIdentifier, ManagedRef}; /// Specialized type for handling token identifiers. /// It wraps a BoxedBytes with the full ASCII name of the token. @@ -26,7 +26,7 @@ impl ManagedType for TokenIdentifier { type OwnHandle = M::ManagedBufferHandle; #[inline] - fn from_handle(handle: M::ManagedBufferHandle) -> Self { + unsafe fn from_handle(handle: M::ManagedBufferHandle) -> Self { TokenIdentifier { buffer: ManagedBuffer::from_handle(handle), } @@ -194,17 +194,17 @@ impl TypeAbi for TokenIdentifier { impl SCDisplay for TokenIdentifier { fn fmt(&self, f: &mut F) { - f.append_managed_buffer(&ManagedBuffer::from_handle( - self.buffer.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer(&wrap_cast); } } impl SCLowerHex for TokenIdentifier { fn fmt(&self, f: &mut F) { - f.append_managed_buffer_lower_hex(&ManagedBuffer::from_handle( - self.buffer.get_handle().cast_or_signal_error::(), - )); + let cast_handle = self.buffer.get_handle().cast_or_signal_error::(); + let wrap_cast = unsafe { ManagedRef::wrap_handle(cast_handle) }; + f.append_managed_buffer_lower_hex(&wrap_cast); } }