Skip to content

Commit

Permalink
small int VM hooks - framework, test
Browse files Browse the repository at this point in the history
  • Loading branch information
andrei-marinica committed Jul 19, 2024
1 parent e14812d commit 6351bc7
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"arguments": [
"23,000000000"
],
"gasLimit": "9,000,000",
"gasLimit": "50,000,000",
"gasPrice": "0"
},
"expect": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"expect": {
"out": [],
"status": "*",
"message": "str:storage decode error (key: i64): argument out of range",
"message": "str:storage decode error (key: i64): value too long",
"logs": "*",
"gas": "*",
"refund": "*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"expect": {
"out": [],
"status": "4",
"message": "str:storage decode error (key: u64): input too long",
"message": "str:storage decode error (key: u64): value too long",
"logs": "*",
"gas": "*",
"refund": "*"
Expand Down
1 change: 1 addition & 0 deletions framework/base/src/err_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub const ARG_ASYNC_RETURN_WRONG_NUMBER: &str = "wrong number of arguments retur
pub const ARG_CALLBACK_TOO_FEW: &str = "too few callback arguments provided";
pub const ARG_CALLBACK_TOO_MANY: &str = "too many callback arguments provided";

pub const VALUE_TOO_LONG: &str = "value too long";
pub const ARG_OUT_OF_RANGE: &str = "argument out of range";
pub const ARG_BAD_LENGTH: &str = "argument has wrong length";
pub const ARG_BAD_LENGTH_32: &str = "argument has wrong length: 32 bytes expected";
Expand Down
8 changes: 7 additions & 1 deletion framework/base/src/storage/storage_get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,20 @@ where
.into_max_size_buffer_align_right(buffer, h)
}

#[inline]
fn into_i64<H>(self, h: H) -> Result<i64, H::HandledErr>
where
H: DecodeErrorHandler,
{
self.to_managed_buffer().into_i64(h)
}

fn into_u64<H>(self, h: H) -> Result<u64, H::HandledErr>
where
H: DecodeErrorHandler,
{
self.to_managed_buffer().into_u64(h)
}

#[inline]
fn supports_specialized_type<T: TryStaticCast>() -> bool {
T::type_eq::<ManagedBuffer<A>>() || T::type_eq::<BigUint<A>>() || T::type_eq::<BigInt<A>>()
Expand Down
16 changes: 15 additions & 1 deletion framework/base/src/storage/storage_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use unwrap_infallible::UnwrapInfallible;
use crate::{
api::{
const_handles, use_raw_handle, ErrorApi, ManagedBufferApiImpl, ManagedTypeApi,
StorageWriteApi, StorageWriteApiImpl,
ManagedTypeApiImpl, StorageWriteApi, StorageWriteApiImpl,
},
codec::*,
contract_base::ExitCodecErrorHandler,
Expand Down Expand Up @@ -47,6 +47,20 @@ where
self.set_managed_buffer(&bytes.into())
}

fn set_u64(self, value: u64) {
let handle: A::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1);
A::managed_type_impl().mb_from_small_int_unsigned(handle.clone(), value as i64);
let managed_buffer = ManagedBuffer::from_handle(handle);
self.set_managed_buffer(&managed_buffer);
}

fn set_i64(self, value: i64) {
let handle: A::ManagedBufferHandle = use_raw_handle(const_handles::MBUF_TEMPORARY_1);
A::managed_type_impl().mb_from_small_int_signed(handle.clone(), value);
let managed_buffer = ManagedBuffer::from_handle(handle);
self.set_managed_buffer(&managed_buffer);
}

#[inline]
fn supports_specialized_type<T: TryStaticCast>() -> bool {
T::type_eq::<ManagedBuffer<A>>() || T::type_eq::<BigUint<A>>() || T::type_eq::<BigInt<A>>()
Expand Down
24 changes: 13 additions & 11 deletions framework/base/src/types/managed/basic/managed_buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
abi::{TypeAbi, TypeAbiFrom, TypeName},
api::{
use_raw_handle, ErrorApiImpl, HandleConstraints, InvalidSliceError, ManagedBufferApiImpl,
ManagedTypeApi, StaticVarApiImpl,
ManagedTypeApi, ManagedTypeApiImpl, StaticVarApiImpl,
},
codec::{
DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput,
Expand Down Expand Up @@ -313,23 +313,25 @@ impl<M: ManagedTypeApi> ManagedBuffer<M> {
}

/// Convenience method for quickly getting a top-decoded u64 from the managed buffer.
///
/// TODO: remove this method once TopDecodeInput is implemented for ManagedBuffer reference.
pub fn parse_as_u64(&self) -> Option<u64> {
const U64_NUM_BYTES: usize = 8;
let l = self.len();
if l > U64_NUM_BYTES {
return None;
}
let mut bytes = [0u8; U64_NUM_BYTES];
if M::managed_type_impl()
.mb_load_slice(self.handle.clone(), 0, &mut bytes[U64_NUM_BYTES - l..])
.is_err()
{
None
} else {
Some(u64::from_be_bytes(bytes))
let value = M::managed_type_impl().mb_to_small_int_unsigned(self.handle.clone());
Some(value as u64)
}

/// Convenience method for quickly getting a top-decoded i64 from the managed buffer.
pub fn parse_as_i64(&self) -> Option<i64> {
const I64_NUM_BYTES: usize = 8;
let l = self.len();
if l > I64_NUM_BYTES {
return None;
}
let value = M::managed_type_impl().mb_to_small_int_signed(self.handle.clone());
Some(value)
}

/// Produces a hex expression in another managed buffer,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::{
api::{
const_handles, managed_types::BigIntApiImpl, use_raw_handle, ManagedTypeApi,
ManagedTypeApiImpl,
},
api::ManagedTypeApi,
codec::{
try_execute_then_cast, DecodeError, DecodeErrorHandler, TopDecodeInput, TryStaticCast,
},
Expand Down Expand Up @@ -67,12 +64,21 @@ where
where
H: DecodeErrorHandler,
{
let big_int_temp: M::BigIntHandle = use_raw_handle(const_handles::BIG_INT_TEMPORARY_1);
M::managed_type_impl().mb_to_big_int_signed(self.handle.clone(), big_int_temp.clone());
if let Some(value) = M::managed_type_impl().bi_to_i64(big_int_temp) {
if let Some(value) = self.parse_as_i64() {
Ok(value)
} else {
Err(h.handle_error(err_msg::VALUE_TOO_LONG.into()))
}
}

fn into_u64<H>(self, h: H) -> Result<u64, H::HandledErr>
where
H: DecodeErrorHandler,
{
if let Some(value) = self.parse_as_u64() {
Ok(value)
} else {
Err(h.handle_error(err_msg::ARG_OUT_OF_RANGE.into()))
Err(h.handle_error(err_msg::VALUE_TOO_LONG.into()))
}
}

Expand Down

0 comments on commit 6351bc7

Please sign in to comment.