diff --git a/Cargo.lock b/Cargo.lock index 8e4e5b7044..d613ef7151 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -138,11 +138,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "3.0.6" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", + "once_cell", "windows-sys 0.59.0", ] @@ -408,9 +409,9 @@ checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.2.7" +version = "1.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" +checksum = "c8293772165d9345bdaaa39b45b2109591e63fe5e6fbc23c6ff930a048aa310b" dependencies = [ "shlex", ] @@ -474,9 +475,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.24" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" +checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" dependencies = [ "clap_builder", "clap_derive", @@ -484,9 +485,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.24" +version = "4.5.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" +checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" dependencies = [ "anstream", "anstyle", @@ -2061,9 +2062,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "js-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ "once_cell", "wasm-bindgen", @@ -2238,9 +2239,9 @@ checksum = "9374ef4228402d4b7e403e5838cb880d9ee663314b0a900d5a6aabf0c213552e" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "lottery-erc20" @@ -2323,9 +2324,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" dependencies = [ "adler2", ] @@ -2439,8 +2440,7 @@ dependencies = [ [[package]] name = "multiversx-chain-vm-executor" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51cce7ae386960fbf5e85afe40ca16d63f926f0620ed1a36b019212b28e17219" +source = "git+https://github.com/multiversx/mx-vm-executor-rs?rev=45ad48765e9e2eaa446fe32327a414a3b4599820#45ad48765e9e2eaa446fe32327a414a3b4599820" [[package]] name = "multiversx-price-aggregator-sc" @@ -3290,7 +3290,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.10", + "thiserror 2.0.11", "tokio", "tracing", ] @@ -3309,7 +3309,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.10", + "thiserror 2.0.11", "tinyvec", "tracing", "web-time", @@ -3626,9 +3626,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.20" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "once_cell", "ring", @@ -4203,11 +4203,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.10", + "thiserror-impl 2.0.11", ] [[package]] @@ -4223,9 +4223,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", @@ -4557,9 +4557,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" dependencies = [ "getrandom", ] @@ -4636,20 +4636,21 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", @@ -4661,9 +4662,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.49" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", @@ -4674,9 +4675,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4684,9 +4685,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -4697,9 +4698,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.99" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-encoder" @@ -4759,9 +4763,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.76" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -4909,9 +4913,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.22" +version = "0.6.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" +checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" dependencies = [ "memchr", ] @@ -5113,7 +5117,7 @@ dependencies = [ "flate2", "indexmap 2.7.0", "memchr", - "thiserror 2.0.10", + "thiserror 2.0.11", "zopfli", ] diff --git a/chain/vm/Cargo.toml b/chain/vm/Cargo.toml index baaa3411c4..391c1d24a1 100644 --- a/chain/vm/Cargo.toml +++ b/chain/vm/Cargo.toml @@ -39,4 +39,6 @@ version = "=0.12.0" path = "../core" [dependencies.multiversx-chain-vm-executor] -version = "0.3.0" +# version = "0.3.0" +git = "https://github.com/multiversx/mx-vm-executor-rs" +rev = "45ad48765e9e2eaa446fe32327a414a3b4599820" diff --git a/chain/vm/src/tx_mock/tx_managed_types.rs b/chain/vm/src/tx_mock/tx_managed_types.rs index d95f05b562..dd65cd9947 100644 --- a/chain/vm/src/tx_mock/tx_managed_types.rs +++ b/chain/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/chain/vm/src/tx_mock/tx_managed_types/tx_big_int.rs b/chain/vm/src/tx_mock/tx_managed_types/tx_big_int.rs index 510dee9a51..886e2c84da 100644 --- a/chain/vm/src/tx_mock/tx_managed_types/tx_big_int.rs +++ b/chain/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/chain/vm/src/vm_err_msg.rs b/chain/vm/src/vm_err_msg.rs index 4356223a5e..f262fbedaf 100644 --- a/chain/vm/src/vm_err_msg.rs +++ b/chain/vm/src/vm_err_msg.rs @@ -15,4 +15,7 @@ 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"; + pub const PROMISES_TOKENIZE_FAILED: &str = "tokenize failed"; diff --git a/chain/vm/src/vm_hooks/vh_dispatcher.rs b/chain/vm/src/vm_hooks/vh_dispatcher.rs index 1af9bfbb6a..100c52ff94 100644 --- a/chain/vm/src/vm_hooks/vh_dispatcher.rs +++ b/chain/vm/src/vm_hooks/vh_dispatcher.rs @@ -1884,6 +1884,24 @@ impl VMHooks for VMHooksDispatcher { 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, @@ -1908,4 +1926,20 @@ impl VMHooks for VMHooksDispatcher { ) -> i32 { panic!("Unavailable: managed_verify_blsaggregated_signature") } + + fn get_round_time(&self) -> i64 { + panic!("Unavailable: get_round_time") + } + + fn epoch_start_block_time_stamp(&self) -> i64 { + panic!("Unavailable: epoch_start_block_time_stamp") + } + + fn epoch_start_block_nonce(&self) -> i64 { + panic!("Unavailable: epoch_start_block_nonce") + } + + fn epoch_start_block_round(&self) -> i64 { + panic!("Unavailable: epoch_start_block_round") + } } diff --git a/chain/vm/src/vm_hooks/vh_handler/vh_managed_types.rs b/chain/vm/src/vm_hooks/vh_handler/vh_managed_types.rs index 45bb412d8b..3c51553701 100644 --- a/chain/vm/src/vm_hooks/vh_handler/vh_managed_types.rs +++ b/chain/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(); 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 81ff2d7fda..8cece38bc1 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": "25,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/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/base/src/err_msg.rs b/framework/base/src/err_msg.rs index 77f6a8bad3..e2e481e327 100644 --- a/framework/base/src/err_msg.rs +++ b/framework/base/src/err_msg.rs @@ -19,6 +19,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 3cd6324aae..f70295787f 100644 --- a/framework/base/src/storage/storage_get.rs +++ b/framework/base/src/storage/storage_get.rs @@ -96,7 +96,6 @@ where .into_max_size_buffer_align_right(buffer, h) } - #[inline] fn into_i64(self, h: H) -> Result where H: DecodeErrorHandler, @@ -104,6 +103,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 8907b2abbf..598b74f06e 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 = unsafe { 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 = unsafe { 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 01f26277c8..7cdaf200c1 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, RawHandle, StaticVarApiImpl, + ManagedTypeApi, ManagedTypeApiImpl, RawHandle, StaticVarApiImpl, }, codec::{ DecodeErrorHandler, Empty, EncodeErrorHandler, NestedDecode, NestedDecodeInput, @@ -359,23 +359,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())) } } diff --git a/framework/scenario/Cargo.toml b/framework/scenario/Cargo.toml index ee8abe58a9..06de4fefcd 100644 --- a/framework/scenario/Cargo.toml +++ b/framework/scenario/Cargo.toml @@ -50,7 +50,9 @@ version = "0.23.0" path = "../../sdk/scenario-format" [dependencies.multiversx-chain-vm-executor] -version = "0.3.0" +# version = "0.3.0" +git = "https://github.com/multiversx/mx-vm-executor-rs" +rev = "45ad48765e9e2eaa446fe32327a414a3b4599820" [dependencies.multiversx-chain-vm] version = "=0.12.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,