diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index 58ea9e80c6..380b818db2 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -16,7 +16,7 @@ jobs: name: Contracts uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@4ec1f927bd99ed90a816ded805daa75fd2040258 with: - rust-toolchain: stable + rust-toolchain: 1.82 path-to-sc-meta: framework/meta mx-scenario-go-version: v2.1.0-alpha coverage-args: --ignore-filename-regex='meta/src' --ignore-filename-regex='wasm-adapter' --ignore-filename-regex='benchmarks/' --ignore-filename-regex='tests/' --output ./coverage.md diff --git a/.github/workflows/lldb-formatter-tests.yml b/.github/workflows/lldb-formatter-tests.yml index 257476c191..78edce381f 100644 --- a/.github/workflows/lldb-formatter-tests.yml +++ b/.github/workflows/lldb-formatter-tests.yml @@ -16,7 +16,7 @@ jobs: - uses: actions-rs/toolchain@v1 with: default: true - toolchain: stable + toolchain: 1.82 - name: Download vscode-lldb uses: robinraju/release-downloader@v1.5 diff --git a/.github/workflows/plotter-test.yml b/.github/workflows/plotter-test.yml index d509759003..a6b948361d 100644 --- a/.github/workflows/plotter-test.yml +++ b/.github/workflows/plotter-test.yml @@ -21,7 +21,7 @@ jobs: - name: Install rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: stable + toolchain: 1.82 target: wasm32-unknown-unknown - name: Run plotter tests diff --git a/.github/workflows/proxy-compare.yml b/.github/workflows/proxy-compare.yml index 3eef6460d6..231e13a051 100644 --- a/.github/workflows/proxy-compare.yml +++ b/.github/workflows/proxy-compare.yml @@ -18,7 +18,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: stable + toolchain: 1.82 target: wasm32-unknown-unknown - name: Install prerequisites diff --git a/.github/workflows/template-test-current.yml b/.github/workflows/template-test-current.yml index 56382850fe..d496bb7856 100644 --- a/.github/workflows/template-test-current.yml +++ b/.github/workflows/template-test-current.yml @@ -22,7 +22,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: stable + toolchain: 1.82 target: wasm32-unknown-unknown - name: Install prerequisites diff --git a/.github/workflows/template-test-released.yml b/.github/workflows/template-test-released.yml index e6227765db..5a7ad019e3 100644 --- a/.github/workflows/template-test-released.yml +++ b/.github/workflows/template-test-released.yml @@ -22,7 +22,7 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: default: true - toolchain: stable + toolchain: 1.82 target: wasm32-unknown-unknown - name: Install prerequisites diff --git a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json index 628270457c..686fb5e6eb 100644 --- a/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json +++ b/contracts/feature-tests/abi-tester/abi_tester_expected_main.abi.json @@ -247,6 +247,21 @@ } ] }, + { + "name": "process_managed_decimal", + "mutability": "mutable", + "inputs": [ + { + "name": "input", + "type": "ManagedDecimal<10>" + } + ], + "outputs": [ + { + "type": "ManagedDecimal" + } + ] + }, { "name": "esdt_local_role", "mutability": "mutable", diff --git a/contracts/feature-tests/abi-tester/src/abi_proxy.rs b/contracts/feature-tests/abi-tester/src/abi_proxy.rs index 69fdfb2319..65611c277e 100644 --- a/contracts/feature-tests/abi-tester/src/abi_proxy.rs +++ b/contracts/feature-tests/abi-tester/src/abi_proxy.rs @@ -236,6 +236,19 @@ where .original_result() } + pub fn process_managed_decimal< + Arg0: ProxyArg>>, + >( + self, + input: Arg0, + ) -> TxTypedCall> { + self.wrapped_tx + .payment(NotPayable) + .raw_call("process_managed_decimal") + .argument(&input) + .original_result() + } + pub fn esdt_local_role( self, ) -> TxTypedCall { diff --git a/contracts/feature-tests/abi-tester/src/abi_tester.rs b/contracts/feature-tests/abi-tester/src/abi_tester.rs index 9405fa28a0..ff1c0bcd96 100644 --- a/contracts/feature-tests/abi-tester/src/abi_tester.rs +++ b/contracts/feature-tests/abi-tester/src/abi_tester.rs @@ -110,6 +110,14 @@ pub trait AbiTester { (address, byte_array).into() } + #[endpoint] + fn process_managed_decimal( + &self, + input: ManagedDecimal>, + ) -> ManagedDecimal { + input.into() + } + #[endpoint] fn esdt_local_role(&self) -> EsdtLocalRole { EsdtLocalRole::None diff --git a/contracts/feature-tests/abi-tester/wasm/src/lib.rs b/contracts/feature-tests/abi-tester/wasm/src/lib.rs index 96d934bfa2..ca7cdc2925 100644 --- a/contracts/feature-tests/abi-tester/wasm/src/lib.rs +++ b/contracts/feature-tests/abi-tester/wasm/src/lib.rs @@ -6,9 +6,9 @@ // Init: 1 // Upgrade: 1 -// Endpoints: 29 +// Endpoints: 30 // Async Callback (empty): 1 -// Total number of exported functions: 32 +// Total number of exported functions: 33 #![no_std] @@ -31,6 +31,7 @@ multiversx_sc_wasm_adapter::endpoints! { optional_result => optional_result address_vs_h256 => address_vs_h256 managed_address_vs_byte_array => managed_address_vs_byte_array + process_managed_decimal => process_managed_decimal esdt_local_role => esdt_local_role esdt_token_payment => esdt_token_payment esdt_token_data => esdt_token_data diff --git a/framework/base/src/types/managed/wrapped/managed_decimal.rs b/framework/base/src/types/managed/wrapped/managed_decimal.rs index d5811031d9..943dc3445c 100644 --- a/framework/base/src/types/managed/wrapped/managed_decimal.rs +++ b/framework/base/src/types/managed/wrapped/managed_decimal.rs @@ -77,7 +77,7 @@ impl ManagedDecimal { Ordering::Greater => { let delta_decimals = from_num_decimals - scale_to_num_decimals; let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); - &self.data * scaling_factor + &self.data / scaling_factor }, } } @@ -128,6 +128,14 @@ impl ManagedDecimal + From>> for ManagedDecimal +{ + fn from(value: ManagedDecimal>) -> Self { + value.into_var_decimals() + } +} + impl TopEncode for ManagedDecimal> { @@ -252,6 +260,10 @@ impl TypeAbi for ManagedDecimal { TypeName::from("ManagedDecimal") } + fn type_name_rust() -> TypeName { + TypeName::from("ManagedDecimal<$API, usize>") + } + fn is_variadic() -> bool { false } 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..f76bb84414 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 @@ -66,7 +66,7 @@ impl ManagedDecimalSigned { Ordering::Greater => { let delta_decimals = from_num_decimals - scale_to_num_decimals; let scaling_factor: &BigUint = &delta_decimals.scaling_factor(); - &self.data * &scaling_factor.value + &self.data / &scaling_factor.value }, } } diff --git a/framework/scenario/tests/managed_decimal_test.rs b/framework/scenario/tests/managed_decimal_test.rs index 96cfcbf182..8342c9e1fe 100644 --- a/framework/scenario/tests/managed_decimal_test.rs +++ b/framework/scenario/tests/managed_decimal_test.rs @@ -2,7 +2,8 @@ use multiversx_sc::{ codec::test_util::{check_dep_encode_decode, check_top_encode_decode}, derive::{debug_const_managed_decimal, debug_managed_decimal}, types::{ - BigFloat, BigInt, BigUint, ConstDecimals, ManagedDecimal, ManagedDecimalSigned, NumDecimals, + BigFloat, BigInt, BigUint, ConstDecimals, Decimals, ManagedDecimal, ManagedDecimalSigned, + NumDecimals, }, }; use multiversx_sc_scenario::api::StaticApi; @@ -38,33 +39,83 @@ pub fn test_managed_decimal() { division, ManagedDecimal::>::from(BigUint::from(5u64)) ); +} + +fn assert_exact(dec: &ManagedDecimal, raw_u64: u64, scale: usize) { + let raw_units = BigUint::from(raw_u64); + assert_eq!(dec.scale(), scale); + assert_eq!(dec.into_raw_units(), &raw_units); + assert_eq!(dec, &ManagedDecimal::from_raw_units(raw_units, scale)); +} - let fixed_4: ManagedDecimal = +#[test] +pub fn test_managed_decimal_rescale_unchanged() { + let dec: ManagedDecimal = ManagedDecimal::from_raw_units(BigUint::from(100u64), 2usize); - let fixed_5 = fixed_4.rescale(2usize); + assert_exact(&dec, 100u64, 2); + let rescaled = dec.rescale(2usize); + assert_exact(&rescaled, 100u64, 2); assert_eq!( - fixed_5, + rescaled, ManagedDecimal::from_raw_units(BigUint::from(100000000u64), 8usize) ); +} - let fixed_6: ManagedDecimal> = - ManagedDecimal::from(BigUint::from(1500u64)); - let fixed_7 = fixed_6.rescale(ConstDecimals::<8>); +#[test] +pub fn test_managed_decimal_rescale_up() { + let uint_value = 1500u64; + let dec: ManagedDecimal> = + ManagedDecimal::from(BigUint::from(uint_value)); + assert_exact(&dec, uint_value * 100, 2); + let rescaled = dec.rescale(ConstDecimals::<8>); + assert_exact(&rescaled, uint_value * 100000000, 8); assert_eq!( - fixed_7, - ManagedDecimal::>::from(BigUint::from(1500u64)) + rescaled, + ManagedDecimal::>::from(BigUint::from(uint_value)) ); +} - let fixed_8: ManagedDecimal = - ManagedDecimal::from_raw_units(BigUint::from(5u64), 5usize); - let fixed_9 = fixed_8.rescale(ConstDecimals::<3>); +#[test] +pub fn test_managed_decimal_rescale_down_1() { + // 1234.0000000 -> 1234. + let uint_value = 1234u64; + let dec: ManagedDecimal> = + ManagedDecimal::from(BigUint::from(uint_value)); + assert_exact(&dec, uint_value * 10000000, 7); + let rescaled = dec.rescale(ConstDecimals::<3>); + assert_exact(&rescaled, uint_value * 1000, 3); +} + +#[test] +pub fn test_managed_decimal_rescale_down_2() { + // 0.00009 -> 0.0000 + let dec: ManagedDecimal = + ManagedDecimal::from_raw_units(BigUint::from(9u64), 5usize); + assert_exact(&dec, 9, 5); + let rescaled = dec.rescale(ConstDecimals::<4>); + assert_exact(&rescaled, 0, 4); assert_eq!( - fixed_9, - ManagedDecimal::>::const_decimals_from_raw(BigUint::from( - 500u64 - )) + rescaled, + ManagedDecimal::>::from(BigUint::zero()) ); +} +#[test] +pub fn test_managed_decimal_rescale_down_3() { + // 1.00009 -> 1.0000 + let dec: ManagedDecimal = + ManagedDecimal::from_raw_units(BigUint::from(100009u64), 5usize); + assert_exact(&dec, 100009, 5); + let rescaled = dec.rescale(ConstDecimals::<4>); + assert_exact(&rescaled, 10000, 4); + assert_eq!( + rescaled, + ManagedDecimal::>::from(BigUint::from(1u64)) + ); +} + +#[test] +pub fn test_managed_decimal_from_big_float() { let float_1 = BigFloat::::from_frac(3i64, 2i64); let fixed_float_1 = ManagedDecimalSigned::>::from_big_float( &float_1, @@ -166,6 +217,83 @@ pub fn test_addition_managed_decimal_signed() { assert_eq!(addition_4.trunc(), BigInt::from(1i64)); } +fn assert_exact_signed( + dec: &ManagedDecimalSigned, + raw_u64: i64, + scale: usize, +) { + let raw_units = BigInt::from(raw_u64); + assert_eq!(dec.scale(), scale); + assert_eq!(dec.into_raw_units(), &raw_units); + assert_eq!(dec, &ManagedDecimalSigned::from_raw_units(raw_units, scale)); +} + +#[test] +pub fn test_managed_decimal_signed_rescale_unchanged() { + let dec: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(100), 2usize); + assert_exact_signed(&dec, 100, 2); + let rescaled = dec.rescale(2usize); + assert_exact_signed(&rescaled, 100, 2); + assert_eq!( + rescaled, + ManagedDecimalSigned::from_raw_units(BigInt::from(100000000), 8usize) + ); +} + +#[test] +pub fn test_managed_decimal_signed_rescale_up() { + let uint_value = -1500i64; + let dec: ManagedDecimalSigned> = + ManagedDecimalSigned::from(BigInt::from(uint_value)); + assert_exact_signed(&dec, uint_value * 100, 2); + let rescaled = dec.rescale(ConstDecimals::<8>); + assert_exact_signed(&rescaled, uint_value * 100000000, 8); + assert_eq!( + rescaled, + ManagedDecimalSigned::>::from(BigInt::from(uint_value)) + ); +} + +#[test] +pub fn test_managed_decimal_signed_rescale_down_1() { + // -1234.0000000 -> -1234. + let uint_value = -1234; + let dec: ManagedDecimalSigned> = + ManagedDecimalSigned::from(BigInt::from(uint_value)); + assert_exact_signed(&dec, uint_value * 10000000, 7); + let rescaled = dec.rescale(ConstDecimals::<3>); + assert_exact_signed(&rescaled, uint_value * 1000, 3); +} + +#[test] +pub fn test_managed_decimal_signed_rescale_down_2() { + // 0.00009 -> 0.0000 + let dec: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(-9), 5usize); + assert_exact_signed(&dec, -9, 5); + let rescaled = dec.rescale(ConstDecimals::<4>); + assert_exact_signed(&rescaled, 0, 4); + assert_eq!( + rescaled, + ManagedDecimalSigned::>::from(BigInt::zero()) + ); +} + +#[test] +pub fn test_managed_decimal_signed_rescale_down_3() { + // -1.00009 -> -1.0000 + let dec: ManagedDecimalSigned = + ManagedDecimalSigned::from_raw_units(BigInt::from(-100009), 5usize); + assert_exact_signed(&dec, -100009, 5); + let rescaled = dec.rescale(ConstDecimals::<4>); + assert_exact_signed(&rescaled, -10000, 4); + assert_eq!( + rescaled, + ManagedDecimalSigned::>::from(BigInt::from(-1)) + ); +} + #[test] pub fn test_substraction_managed_decimal_signed() { let fixed_1 = ManagedDecimalSigned::>::from(BigInt::from(1i64)); @@ -260,30 +388,6 @@ pub fn test_devision_managed_decimal_signed() { #[test] pub fn test_rescale_managed_decimal_signed() { - let fixed_1: ManagedDecimalSigned = - ManagedDecimalSigned::from_raw_units(BigInt::from(-10000i64), 2usize); - - let fixed_2 = fixed_1.rescale(3usize); - assert_eq!( - fixed_2, - ManagedDecimalSigned::from_raw_units(BigInt::from(-100000000i64), 6usize) - ); - - let fixed_3: ManagedDecimalSigned> = - ManagedDecimalSigned::from(BigInt::from(-1500i64)); - let fixed_4 = fixed_3.rescale(ConstDecimals::<8>); - assert_eq!(fixed_4.into_raw_units(), &BigInt::from(-150000000000i64)); - - let fixed_5: ManagedDecimalSigned = - ManagedDecimalSigned::from_raw_units(BigInt::from(-5i64), 5usize); - let fixed_6 = fixed_5.rescale(ConstDecimals::<3>); - assert_eq!( - fixed_6, - ManagedDecimalSigned::>::const_decimals_from_raw(BigInt::from( - -500i64 - )) - ); - let float_1 = BigFloat::::from_frac(-3i64, 2i64); let fixed_float_1 = ManagedDecimalSigned::>::from_big_float( &float_1, diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 292fe499e3..7c6b99a03c 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "stable" +channel = "1.82" # TODO: clippy fixes performed in rc/v0.55, revert to latest stable after merging