From e14812ddb6f2a6c08b4cba91116e13939fee3e11 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 19 Jul 2024 15:32:27 +0300 Subject: [PATCH 1/2] small int VM hooks - api, Rust VM --- Cargo.lock | 6 ++-- .../managed_types/managed_type_api_impl.rs | 8 +++++ .../uncallable/managed_type_api_uncallable.rs | 16 ++++++++++ framework/scenario/Cargo.toml | 3 +- .../scenario/src/api/managed_type_api_vh.rs | 24 ++++++++++++++ .../managed_types/managed_type_api_node.rs | 26 ++++++++++++++++ vm/Cargo.toml | 2 +- vm/src/tx_mock/tx_managed_types.rs | 4 ++- vm/src/tx_mock/tx_managed_types/tx_big_int.rs | 31 ++++++++++++++++--- vm/src/vm_err_msg.rs | 3 ++ vm/src/vm_hooks/vh_dispatcher.rs | 20 +++++++++++- .../vm_hooks/vh_handler/vh_managed_types.rs | 30 +++++++++++++++++- 12 files changed, 160 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a348bfd06..d9305f4b3e 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,9 +384,9 @@ checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "cc" -version = "1.1.5" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "5208975e568d83b6b05cc0a063c8e7e9acc2b43bee6da15616a5b73e109d7437" [[package]] name = "cfg-if" @@ -1916,7 +1916,7 @@ dependencies = [ [[package]] name = "multiversx-chain-vm-executor" version = "0.2.0" -source = "git+https://github.com/multiversx/mx-vm-executor-rs?branch=rc/v1.7.next1#95acf80fb611fb51a8b7e20f5e7086e4aae68539" +source = "git+https://github.com/multiversx/mx-vm-executor-rs?branch=convert-small-int#3459261051bd4cc1f7d084a503c4b601963964e2" [[package]] name = "multiversx-price-aggregator-sc" diff --git a/framework/base/src/api/managed_types/managed_type_api_impl.rs b/framework/base/src/api/managed_types/managed_type_api_impl.rs index 1d2ead32ec..7cdb901f91 100644 --- a/framework/base/src/api/managed_types/managed_type_api_impl.rs +++ b/framework/base/src/api/managed_types/managed_type_api_impl.rs @@ -37,6 +37,14 @@ pub trait ManagedTypeApiImpl: dest: Self::ManagedBufferHandle, ); + fn mb_to_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle) -> i64; + + fn mb_to_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle) -> i64; + + fn mb_from_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle, value: i64); + + fn mb_from_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle, value: i64); + fn mb_to_big_float(&self, buffer_handle: Self::ManagedBufferHandle, dest: Self::BigFloatHandle); fn mb_from_big_float( diff --git a/framework/base/src/api/uncallable/managed_type_api_uncallable.rs b/framework/base/src/api/uncallable/managed_type_api_uncallable.rs index bb121b60a1..90f7166851 100644 --- a/framework/base/src/api/uncallable/managed_type_api_uncallable.rs +++ b/framework/base/src/api/uncallable/managed_type_api_uncallable.rs @@ -43,6 +43,22 @@ impl ManagedTypeApiImpl for UncallableApi { unreachable!() } + fn mb_to_small_int_unsigned(&self, _buffer_handle: Self::ManagedBufferHandle) -> i64 { + unreachable!() + } + + fn mb_to_small_int_signed(&self, _buffer_handle: Self::ManagedBufferHandle) -> i64 { + unreachable!() + } + + fn mb_from_small_int_unsigned(&self, _buffer_handle: Self::ManagedBufferHandle, _value: i64) { + unreachable!() + } + + fn mb_from_small_int_signed(&self, _buffer_handle: Self::ManagedBufferHandle, _value: i64) { + unreachable!() + } + fn mb_to_big_float( &self, _buffer_handle: Self::ManagedBufferHandle, diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index 25e43afdef..fcf9fffa84 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -52,7 +52,8 @@ path = "../../sdk/scenario-format" [dependencies.multiversx-chain-vm-executor] # version = "0.2.0" git = "https://github.com/multiversx/mx-vm-executor-rs" -branch = "rc/v1.7.next1" +branch = "convert-small-int" +# path = "/Users/andreim/multiversx/vm/mx-vm-executor-rs/vm-executor" [dependencies.multiversx-chain-vm] version = "=0.9.0" diff --git a/framework/scenario/src/api/managed_type_api_vh.rs b/framework/scenario/src/api/managed_type_api_vh.rs index e7f28ea8b7..e19d339135 100644 --- a/framework/scenario/src/api/managed_type_api_vh.rs +++ b/framework/scenario/src/api/managed_type_api_vh.rs @@ -69,6 +69,30 @@ impl ManagedTypeApiImpl for VMHooksApi { }); } + fn mb_to_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle) -> i64 { + self.with_vm_hooks_ctx_1(&buffer_handle, |vh| { + vh.mbuffer_to_small_int_unsigned(buffer_handle.get_raw_handle_unchecked()) + }) + } + + fn mb_to_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle) -> i64 { + self.with_vm_hooks_ctx_1(&buffer_handle, |vh| { + vh.mbuffer_to_small_int_signed(buffer_handle.get_raw_handle_unchecked()) + }) + } + + fn mb_from_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle, value: i64) { + self.with_vm_hooks_ctx_1(&buffer_handle, |vh| { + vh.mbuffer_from_small_int_unsigned(buffer_handle.get_raw_handle_unchecked(), value) + }) + } + + fn mb_from_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle, value: i64) { + self.with_vm_hooks_ctx_1(&buffer_handle, |vh| { + vh.mbuffer_from_small_int_signed(buffer_handle.get_raw_handle_unchecked(), value) + }) + } + fn mb_to_big_float( &self, buffer_handle: Self::ManagedBufferHandle, diff --git a/framework/wasm-adapter/src/api/managed_types/managed_type_api_node.rs b/framework/wasm-adapter/src/api/managed_types/managed_type_api_node.rs index 443c629211..78a503ca0c 100644 --- a/framework/wasm-adapter/src/api/managed_types/managed_type_api_node.rs +++ b/framework/wasm-adapter/src/api/managed_types/managed_type_api_node.rs @@ -6,6 +6,12 @@ extern "C" { fn mBufferToBigIntSigned(mBufferHandle: i32, bigIntHandle: i32) -> i32; fn mBufferFromBigIntUnsigned(mBufferHandle: i32, bigIntHandle: i32) -> i32; fn mBufferFromBigIntSigned(mBufferHandle: i32, bigIntHandle: i32) -> i32; + + fn mBufferToSmallIntUnsigned(mBufferHandle: i32) -> i64; + fn mBufferToSmallIntSigned(mBufferHandle: i32) -> i64; + fn mBufferFromSmallIntUnsigned(mBufferHandle: i32, value: i64); + fn mBufferFromSmallIntSigned(mBufferHandle: i32, value: i64); + fn mBufferToBigFloat(mBufferHandle: i32, bigFloatHandle: i32) -> i32; fn mBufferFromBigFloat(mBufferHandle: i32, bigFloatHandle: i32) -> i32; @@ -65,6 +71,26 @@ impl ManagedTypeApiImpl for VmApiImpl { } } + fn mb_to_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle) -> i64 { + unsafe { mBufferToSmallIntUnsigned(buffer_handle) } + } + + fn mb_to_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle) -> i64 { + unsafe { mBufferToSmallIntSigned(buffer_handle) } + } + + fn mb_from_small_int_unsigned(&self, buffer_handle: Self::ManagedBufferHandle, value: i64) { + unsafe { + mBufferFromSmallIntUnsigned(buffer_handle, value); + } + } + + fn mb_from_small_int_signed(&self, buffer_handle: Self::ManagedBufferHandle, value: i64) { + unsafe { + mBufferFromSmallIntSigned(buffer_handle, value); + } + } + #[inline] fn mb_to_big_float( &self, diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 2da432d240..de3a87d2b4 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -37,4 +37,4 @@ ed25519-dalek = { version = "1.0.1" , optional = true } [dependencies.multiversx-chain-vm-executor] # version = "0.2.0" git = "https://github.com/multiversx/mx-vm-executor-rs" -branch = "rc/v1.7.next1" +branch = "convert-small-int" diff --git a/vm/src/tx_mock/tx_managed_types.rs b/vm/src/tx_mock/tx_managed_types.rs index d95f05b562..dd65cd9947 100644 --- a/vm/src/tx_mock/tx_managed_types.rs +++ b/vm/src/tx_mock/tx_managed_types.rs @@ -6,7 +6,9 @@ mod tx_managed_map; pub use handle_map::HandleMap; use num_bigint::BigInt; -pub use tx_big_int::big_int_to_i64; +pub use tx_big_int::{ + big_int_signed_bytes, big_int_to_i64, big_uint_to_u64, big_uint_unsigned_bytes, +}; use std::collections::HashMap; diff --git a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs index 510dee9a51..886e2c84da 100644 --- a/vm/src/tx_mock/tx_managed_types/tx_big_int.rs +++ b/vm/src/tx_mock/tx_managed_types/tx_big_int.rs @@ -47,11 +47,7 @@ impl TxManagedTypes { pub fn bi_get_signed_bytes(&self, handle: RawHandle) -> Vec { let bi = self.bi_get(handle); - if bi.is_zero() { - Vec::new() - } else { - bi.to_signed_bytes_be() - } + big_int_signed_bytes(&bi) } pub fn bi_set_signed_bytes(&mut self, destination: RawHandle, bytes: &[u8]) { @@ -90,3 +86,28 @@ pub fn big_int_to_i64(bi: &num_bigint::BigInt) -> Option { }, } } + +pub fn big_uint_to_u64(bu: &num_bigint::BigUint) -> Option { + let digits = bu.to_u64_digits(); + match digits.len() { + 0 => Some(0), + 1 => Some(digits[0]), + _ => None, + } +} + +pub fn big_uint_unsigned_bytes(bu: &num_bigint::BigUint) -> Vec { + if bu.is_zero() { + Vec::new() + } else { + bu.to_bytes_be() + } +} + +pub fn big_int_signed_bytes(bi: &num_bigint::BigInt) -> Vec { + if bi.is_zero() { + Vec::new() + } else { + bi.to_signed_bytes_be() + } +} diff --git a/vm/src/vm_err_msg.rs b/vm/src/vm_err_msg.rs index 339e926f4f..17052e4d37 100644 --- a/vm/src/vm_err_msg.rs +++ b/vm/src/vm_err_msg.rs @@ -14,3 +14,6 @@ pub const ERROR_SIGNALLED_BY_SMARTCONTRACT: &str = "error signalled by smartcont pub const ERROR_NO_CALLBACK_CLOSURE: &str = "no callback for closure, cannot call callback directly"; + +pub const ERROR_BYTES_EXCEED_INT64: &str = "bytes cannot be parsed as int64"; +pub const ERROR_BYTES_EXCEED_UINT64: &str = "bytes cannot be parsed as uint64"; diff --git a/vm/src/vm_hooks/vh_dispatcher.rs b/vm/src/vm_hooks/vh_dispatcher.rs index 46c5153819..8985743fc3 100644 --- a/vm/src/vm_hooks/vh_dispatcher.rs +++ b/vm/src/vm_hooks/vh_dispatcher.rs @@ -1883,7 +1883,25 @@ impl VMHooks for VMHooksDispatcher { ) -> i32 { panic!("Unavailable: managed_multi_transfer_esdt_nft_execute_by_user") } - + + fn mbuffer_to_small_int_unsigned(&self, m_buffer_handle: i32) -> i64 { + self.handler.mb_to_small_int_unsigned(m_buffer_handle) as i64 + } + + fn mbuffer_to_small_int_signed(&self, m_buffer_handle: i32) -> i64 { + self.handler.mb_to_small_int_signed(m_buffer_handle) + } + + fn mbuffer_from_small_int_unsigned(&self, m_buffer_handle: i32, value: i64) { + self.handler + .mb_from_small_int_unsigned(m_buffer_handle, value as u64); + } + + fn mbuffer_from_small_int_signed(&self, m_buffer_handle: i32, value: i64) { + self.handler + .mb_from_small_int_signed(m_buffer_handle, value); + } + fn managed_verify_secp256r1( &self, key_handle: i32, diff --git a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs index 45bb412d8b..3c51553701 100644 --- a/vm/src/vm_hooks/vh_handler/vh_managed_types.rs +++ b/vm/src/vm_hooks/vh_handler/vh_managed_types.rs @@ -10,7 +10,11 @@ pub use vh_managed_map::VMHooksManagedMap; use std::fmt::Debug; -use crate::types::RawHandle; +use crate::{ + tx_mock::{big_int_signed_bytes, big_int_to_i64, big_uint_to_u64, big_uint_unsigned_bytes}, + types::RawHandle, + vm_err_msg, +}; use super::VMHooksError; @@ -42,6 +46,30 @@ pub trait VMHooksManagedTypes: self.m_types_lock().mb_set(buffer_handle, bi_bytes); } + fn mb_to_small_int_unsigned(&self, buffer_handle: RawHandle) -> u64 { + let bytes = self.m_types_lock().mb_to_bytes(buffer_handle); + let bu = num_bigint::BigUint::from_bytes_be(&bytes); + big_uint_to_u64(&bu).unwrap_or_else(|| self.vm_error(vm_err_msg::ERROR_BYTES_EXCEED_UINT64)) + } + + fn mb_to_small_int_signed(&self, buffer_handle: RawHandle) -> i64 { + let bytes = self.m_types_lock().mb_to_bytes(buffer_handle); + let bi = num_bigint::BigInt::from_bytes_be(num_bigint::Sign::Plus, &bytes); + big_int_to_i64(&bi).unwrap_or_else(|| self.vm_error(vm_err_msg::ERROR_BYTES_EXCEED_INT64)) + } + + fn mb_from_small_int_unsigned(&self, buffer_handle: RawHandle, value: u64) { + let bu = num_bigint::BigUint::from(value); + let bytes = big_uint_unsigned_bytes(&bu); + self.m_types_lock().mb_set(buffer_handle, bytes); + } + + fn mb_from_small_int_signed(&self, buffer_handle: RawHandle, value: i64) { + let bi = num_bigint::BigInt::from(value); + let bytes = big_int_signed_bytes(&bi); + self.m_types_lock().mb_set(buffer_handle, bytes); + } + fn bi_to_string(&self, bi_handle: RawHandle, str_handle: RawHandle) { let bi = self.m_types_lock().bi_get(bi_handle); let s = bi.to_string(); From 6351bc7119c4e03fd927cf9df83fa055d6f06298 Mon Sep 17 00:00:00 2001 From: Andrei Marinica Date: Fri, 19 Jul 2024 15:40:17 +0300 Subject: [PATCH 2/2] small int VM hooks - framework, test --- .../managed_decimal_logarithm.scen.json | 2 +- .../scenarios/storage_i64_bad.scen.json | 2 +- .../scenarios/storage_u64_bad.scen.json | 2 +- framework/base/src/err_msg.rs | 1 + framework/base/src/storage/storage_get.rs | 8 ++++++- framework/base/src/storage/storage_set.rs | 16 ++++++++++++- .../src/types/managed/basic/managed_buffer.rs | 24 ++++++++++--------- .../codec_util/managed_buffer_top_de_input.rs | 22 ++++++++++------- 8 files changed, 53 insertions(+), 24 deletions(-) diff --git a/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json b/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json index da54f8ccec..191c2bb60b 100644 --- a/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/managed_decimal_logarithm.scen.json @@ -24,7 +24,7 @@ "arguments": [ "23,000000000" ], - "gasLimit": "9,000,000", + "gasLimit": "50,000,000", "gasPrice": "0" }, "expect": { diff --git a/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json index 6fb3ab0c59..dff181e2d0 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_i64_bad.scen.json @@ -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": "*" diff --git a/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json b/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json index c7597fd010..e0ccba911e 100644 --- a/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json +++ b/contracts/feature-tests/basic-features/scenarios/storage_u64_bad.scen.json @@ -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": "*" diff --git a/framework/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 361775d5f9..0c08099d90 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -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"; diff --git a/framework/base/src/storage/storage_get.rs b/framework/base/src/storage/storage_get.rs index 85107896dd..153103452e 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -95,7 +95,6 @@ where .into_max_size_buffer_align_right(buffer, h) } - #[inline] fn into_i64(self, h: H) -> Result where H: DecodeErrorHandler, @@ -103,6 +102,13 @@ where self.to_managed_buffer().into_i64(h) } + fn into_u64(self, h: H) -> Result + where + H: DecodeErrorHandler, + { + self.to_managed_buffer().into_u64(h) + } + #[inline] fn supports_specialized_type() -> bool { T::type_eq::>() || T::type_eq::>() || T::type_eq::>() diff --git a/framework/base/src/storage/storage_set.rs b/framework/base/src/storage/storage_set.rs index a2f3c3b722..28284b9b7e 100644 --- a/framework/base/src/storage/storage_set.rs +++ b/framework/base/src/storage/storage_set.rs @@ -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, @@ -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() -> bool { T::type_eq::>() || T::type_eq::>() || T::type_eq::>() diff --git a/framework/base/src/types/managed/basic/managed_buffer.rs b/framework/base/src/types/managed/basic/managed_buffer.rs index de2dc63bb8..e52ef628a7 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, ManagedTypeApiImpl, StaticVarApiImpl, }, codec::{ DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput, @@ -313,23 +313,25 @@ impl ManagedBuffer { } /// 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 { 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 { + 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, diff --git a/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs b/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs index fb091781a2..d4ee079723 100644 --- a/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs +++ b/framework/base/src/types/managed/codec_util/managed_buffer_top_de_input.rs @@ -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, }, @@ -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(self, h: H) -> Result + 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())) } }