Skip to content

Commit

Permalink
Merge pull request #1863 from multiversx/multi-value-mvi
Browse files Browse the repository at this point in the history
Conversions MultiValueEncodedCounted <-> MultiValueManagedVecCounted, test & support
  • Loading branch information
andrei-marinica authored Nov 15, 2024
2 parents 8758061 + a53d908 commit 2748192
Show file tree
Hide file tree
Showing 9 changed files with 278 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,76 @@
"gas": "*",
"refund": "*"
}
},
{
"step": "scCall",
"id": "convert1",
"tx": {
"from": "address:an_account",
"to": "sc:basic-features",
"function": "convert_varags_vec_with_counted_pairs_1",
"arguments": [
"0x68d79a75b4aa11395dd08994855bd1d90b6b7583d7296dca31c2f8f59e0e7a68",
"0x0f",
"2",
"5",
"5",
"4",
"4"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
},
"expect": {
"out": [
"0x68d79a75b4aa11395dd08994855bd1d90b6b7583d7296dca31c2f8f59e0e7a68",
"0x0f",
"2",
"5",
"5",
"4",
"4"
],
"status": "",
"logs": "*",
"gas": "*",
"refund": "*"
}
},
{
"step": "scCall",
"id": "convert2",
"tx": {
"from": "address:an_account",
"to": "sc:basic-features",
"function": "convert_varags_vec_with_counted_pairs_2",
"arguments": [
"0x68d79a75b4aa11395dd08994855bd1d90b6b7583d7296dca31c2f8f59e0e7a68",
"0x0f",
"2",
"5",
"5",
"4",
"4"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
},
"expect": {
"out": [
"0x68d79a75b4aa11395dd08994855bd1d90b6b7583d7296dca31c2f8f59e0e7a68",
"0x0f",
"2",
"5",
"5",
"4",
"4"
],
"status": "",
"logs": "*",
"gas": "*",
"refund": "*"
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,4 @@
}
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,4 @@
}
}
]
}
}
47 changes: 47 additions & 0 deletions contracts/feature-tests/basic-features/src/echo_managed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,51 @@ pub trait EchoManagedTypes {
> {
m
}

#[endpoint]
fn convert_varags_vec_with_counted_pairs_1(
&self,
address_number_pairs: MultiValueEncoded<
MultiValue3<ManagedAddress, usize, MultiValueEncodedCounted<MultiValue2<usize, usize>>>,
>,
) -> MultiValueManagedVec<
MultiValue3<ManagedAddress, usize, MultiValueManagedVecCounted<MultiValue2<usize, usize>>>,
> {
let mut result = MultiValueManagedVec::new();
for triple in address_number_pairs {
let (address, num, counted_lazy) = triple.into_tuple();
let mut counted_list = MultiValueManagedVecCounted::new();
for pair in counted_lazy {
counted_list.push(pair);
}
result.push((address, num, counted_list).into());
}
result
}

#[endpoint]
fn convert_varags_vec_with_counted_pairs_2(
&self,
address_number_pairs: MultiValueManagedVec<
MultiValue3<
ManagedAddress,
usize,
MultiValueManagedVecCounted<MultiValue2<usize, usize>>,
>,
>,
) -> MultiValueEncoded<
MultiValue3<ManagedAddress, usize, MultiValueEncodedCounted<MultiValue2<usize, usize>>>,
> {
let mut result = MultiValueEncoded::new();
for triple in address_number_pairs.into_iter() {
let (address, x, counted_list) = triple.into_tuple();
let mut counted_lazy = MultiValueEncodedCounted::new();
let v = counted_list.into_vec();
for pair in &v {
counted_lazy.push(pair);
}
result.push((address, x, counted_lazy).into());
}
result
}
}
6 changes: 4 additions & 2 deletions contracts/feature-tests/basic-features/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
////////////////////////////////////////////////////

// Init: 1
// Endpoints: 411
// Endpoints: 413
// Async Callback: 1
// Total number of exported functions: 413
// Total number of exported functions: 415

#![no_std]

Expand Down Expand Up @@ -181,6 +181,8 @@ multiversx_sc_wasm_adapter::endpoints! {
echo_varags_managed_sum => echo_varags_managed_sum
echo_varags_vec_with_counted => echo_varags_vec_with_counted
echo_varags_vec_with_counted_pairs => echo_varags_vec_with_counted_pairs
convert_varags_vec_with_counted_pairs_1 => convert_varags_vec_with_counted_pairs_1
convert_varags_vec_with_counted_pairs_2 => convert_varags_vec_with_counted_pairs_2
compute_get_values => compute_get_values
compute_create_ec => compute_create_ec
compute_get_ec_length => compute_get_ec_length
Expand Down
8 changes: 6 additions & 2 deletions data/codec/src/multi_types/multi_value_tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,13 @@ macro_rules! multi_value_impls {

impl<$($name),+ > TopDecodeMultiLength for $mv_struct<$($name,)+>
where
$($name: TopDecodeMulti,)+
$($name: TopDecodeMulti + TopDecodeMultiLength,)+
{
const LEN: usize = $len;
const LEN: usize = 0
$(
+ <$name as TopDecodeMultiLength>::LEN
)+
;
}

impl<$($name),+ > TopDecodeMulti for $mv_struct<$($name,)+>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,30 @@ where
}
}

impl<M, T> ManagedVecItem for MultiValueManagedVecCounted<M, T>
where
M: ManagedTypeApi,
T: ManagedVecItem,
{
type PAYLOAD = <ManagedVec<M, T> as ManagedVecItem>::PAYLOAD;
const SKIPS_RESERIALIZATION: bool = false;
type Ref<'a> = Self;

fn from_byte_reader<Reader: FnMut(&mut [u8])>(reader: Reader) -> Self {
Self::from(ManagedVec::<M, T>::from_byte_reader(reader))
}

unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(
reader: Reader,
) -> Self::Ref<'a> {
Self::from_byte_reader(reader)
}

fn into_byte_writer<R, Writer: FnMut(&[u8]) -> R>(self, writer: Writer) -> R {
self.contents.into_byte_writer(writer)
}
}

impl<M, T> TopEncodeMulti for MultiValueManagedVecCounted<M, T>
where
M: ManagedTypeApi,
Expand Down
124 changes: 124 additions & 0 deletions framework/base/src/types/managed/wrapped/managed_vec_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::borrow::Borrow;

use multiversx_chain_core::types::{EsdtLocalRole, EsdtTokenType};
use multiversx_sc_codec::multi_types::{MultiValue2, MultiValue3};

use crate::{
api::ManagedTypeApi,
Expand Down Expand Up @@ -311,3 +312,126 @@ impl ManagedVecItem for EsdtLocalRole {
<u16 as ManagedVecItem>::into_byte_writer(self.as_u16(), writer)
}
}

impl<T1, T2> ManagedVecItem for MultiValue2<T1, T2>
where
T1: ManagedVecItem,
T2: ManagedVecItem,
(T1, (T2, ())): ManagedVecItemNestedTuple,
{
type PAYLOAD = <(T1, (T2, ())) as ManagedVecItemNestedTuple>::PAYLOAD;
const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION;
type Ref<'a> = Self;

fn from_byte_reader<Reader: FnMut(&mut [u8])>(mut reader: Reader) -> Self {
let mut payload = <Self::PAYLOAD as ManagedVecItemPayload>::new_buffer();
let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload);
reader(payload_slice);
let mut index = 0;

(
T1::from_byte_reader(|bytes| {
let next_index = index + T1::payload_size();
bytes.copy_from_slice(&payload_slice[index..next_index]);
index = next_index;
}),
T2::from_byte_reader(|bytes| {
let next_index = index + T2::payload_size();
bytes.copy_from_slice(&payload_slice[index..next_index]);
index = next_index;
}),
)
.into()
}

unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(
reader: Reader,
) -> Self::Ref<'a> {
Self::from_byte_reader(reader)
}

fn into_byte_writer<R, Writer: FnMut(&[u8]) -> R>(self, mut writer: Writer) -> R {
let mut payload = Self::PAYLOAD::new_buffer();
let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload);
let mut index = 0;
let (t1, t2) = self.into_tuple();
T1::into_byte_writer(t1, |bytes| {
let next_index = index + T1::payload_size();
payload_slice[index..next_index].copy_from_slice(bytes);
index = next_index;
});
T2::into_byte_writer(t2, |bytes| {
let next_index = index + T2::payload_size();
payload_slice[index..next_index].copy_from_slice(bytes);
index = next_index;
});
writer(payload_slice)
}
}

impl<T1, T2, T3> ManagedVecItem for MultiValue3<T1, T2, T3>
where
T1: ManagedVecItem,
T2: ManagedVecItem,
T3: ManagedVecItem,
(T1, (T2, (T3, ()))): ManagedVecItemNestedTuple,
{
type PAYLOAD = <(T1, (T2, (T3, ()))) as ManagedVecItemNestedTuple>::PAYLOAD;
const SKIPS_RESERIALIZATION: bool = T1::SKIPS_RESERIALIZATION && T2::SKIPS_RESERIALIZATION;
type Ref<'a> = Self;

fn from_byte_reader<Reader: FnMut(&mut [u8])>(mut reader: Reader) -> Self {
let mut payload = <Self::PAYLOAD as ManagedVecItemPayload>::new_buffer();
let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload);
reader(payload_slice);
let mut index = 0;

(
T1::from_byte_reader(|bytes| {
let next_index = index + T1::payload_size();
bytes.copy_from_slice(&payload_slice[index..next_index]);
index = next_index;
}),
T2::from_byte_reader(|bytes| {
let next_index = index + T2::payload_size();
bytes.copy_from_slice(&payload_slice[index..next_index]);
index = next_index;
}),
T3::from_byte_reader(|bytes| {
let next_index = index + T3::payload_size();
bytes.copy_from_slice(&payload_slice[index..next_index]);
index = next_index;
}),
)
.into()
}

unsafe fn from_byte_reader_as_borrow<'a, Reader: FnMut(&mut [u8])>(
reader: Reader,
) -> Self::Ref<'a> {
Self::from_byte_reader(reader)
}

fn into_byte_writer<R, Writer: FnMut(&[u8]) -> R>(self, mut writer: Writer) -> R {
let mut payload = Self::PAYLOAD::new_buffer();
let payload_slice = ManagedVecItemPayload::payload_slice_mut(&mut payload);
let mut index = 0;
let (t1, t2, t3) = self.into_tuple();
T1::into_byte_writer(t1, |bytes| {
let next_index = index + T1::payload_size();
payload_slice[index..next_index].copy_from_slice(bytes);
index = next_index;
});
T2::into_byte_writer(t2, |bytes| {
let next_index = index + T2::payload_size();
payload_slice[index..next_index].copy_from_slice(bytes);
index = next_index;
});
T3::into_byte_writer(t3, |bytes| {
let next_index = index + T2::payload_size();
payload_slice[index..next_index].copy_from_slice(bytes);
index = next_index;
});
writer(payload_slice)
}
}
2 changes: 1 addition & 1 deletion framework/derive/src/managed_vec_item_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ fn struct_derive(data_struct: &syn::DataStruct, ast: &syn::DeriveInput) -> Token

#(#to_byte_writer_snippets)*

writer(&payload_slice[..])
writer(payload_slice)
}
}
};
Expand Down

0 comments on commit 2748192

Please sign in to comment.