Skip to content

Commit

Permalink
custom encode/decode
Browse files Browse the repository at this point in the history
  • Loading branch information
dorin-iancu committed Feb 27, 2024
1 parent 7acf6fc commit e46f95f
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 20 deletions.
2 changes: 1 addition & 1 deletion bridge-proxy/tests/bridge_proxy_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use multiversx_sc_scenario::{
};

use eth_address::*;
use transaction::{CallData, EthTransaction, EthTransactionPayment};
use transaction::{call_data::CallData, EthTransaction, EthTransactionPayment};

const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456";
const GAS_LIMIT: u64 = 1_000_000;
Expand Down
74 changes: 74 additions & 0 deletions common/transaction/src/call_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use multiversx_sc::codec::{DefaultErrorHandler, NestedEncodeOutput};

use crate::custom_buffer::AlwaysTopEncodedBuffer;

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[derive(TypeAbi, Clone, ManagedVecItem, Default)]
pub struct CallData<M: ManagedTypeApi> {
pub endpoint: ManagedBuffer<M>,
pub gas_limit: u64,
pub args: ManagedVec<M, ManagedBuffer<M>>,
}

impl<M: ManagedTypeApi> TopEncode for CallData<M> {
fn top_encode<O>(&self, output: O) -> Result<(), codec::EncodeError>
where
O: codec::TopEncodeOutput,
{
let mut nested_encode_output = output.start_nested_encode();
self.dep_encode(&mut nested_encode_output)
}
}

impl<M: ManagedTypeApi> NestedEncode for CallData<M> {
fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), codec::EncodeError> {
let endpoint_len_u8 = self.endpoint.len() as u8;
dest.push_byte(endpoint_len_u8);

let endpoint_buffer = AlwaysTopEncodedBuffer::new(self.endpoint.clone());
endpoint_buffer.dep_encode(dest)?;

let gas_limit_u32 = self.gas_limit as u32;
gas_limit_u32.dep_encode(dest)?;

let args_len_u8 = self.args.len() as u8;
dest.push_byte(args_len_u8);

for arg in &self.args {
arg.dep_encode(dest)?;
}

Result::Ok(())
}
}

impl<M: ManagedTypeApi> NestedDecode for CallData<M> {
fn dep_decode<I: codec::NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
let mut temp_buffer = [0u8; u8::MAX as usize + 1];
let endpoint_len_u8 = u8::dep_decode(input)?;
input.read_into(
&mut temp_buffer[0..endpoint_len_u8 as usize],
DefaultErrorHandler,
)?;
let endpoint_name =
ManagedBuffer::new_from_bytes(&temp_buffer[0..endpoint_len_u8 as usize]);

let gas_limit_u32 = u32::dep_decode(input)?;
let gas_limit = gas_limit_u32 as u64;

let args_len_u8 = u8::dep_decode(input)?;
let mut args = ManagedVec::new();
for _ in 0..args_len_u8 {
let arg = ManagedBuffer::dep_decode(input)?;
args.push(arg);
}

core::result::Result::Ok(Self {
endpoint: endpoint_name,
gas_limit,
args,
})
}
}
38 changes: 38 additions & 0 deletions common/transaction/src/custom_buffer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

pub struct AlwaysTopEncodedBuffer<M: ManagedTypeApi> {
buffer: ManagedBuffer<M>,
}

impl<M: ManagedTypeApi> AlwaysTopEncodedBuffer<M> {
#[inline(always)]
pub fn new(buffer: ManagedBuffer<M>) -> Self {
Self { buffer }
}
}

impl<M: ManagedTypeApi> TopEncode for AlwaysTopEncodedBuffer<M> {
fn top_encode<O>(&self, output: O) -> Result<(), codec::EncodeError>
where
O: codec::TopEncodeOutput,
{
self.buffer.top_encode(output)
}
}

impl<M: ManagedTypeApi> NestedEncode for AlwaysTopEncodedBuffer<M> {
fn dep_encode<O: codec::NestedEncodeOutput>(
&self,
dest: &mut O,
) -> Result<(), codec::EncodeError> {
let mut output_buffer = ManagedBuffer::<M>::new();
self.buffer.top_encode(&mut output_buffer)?;

let mut output_buffer_bytes = [0u8; u8::MAX as usize + 1];
let slice_ref = output_buffer.load_to_byte_array(&mut output_buffer_bytes);
dest.write(slice_ref);

Result::Ok(())
}
}
23 changes: 5 additions & 18 deletions common/transaction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use call_data::CallData;
use eth_address::EthAddress;

pub mod call_data;
pub mod custom_buffer;
pub mod transaction_status;

// revert protection
Expand All @@ -25,24 +29,7 @@ pub type TxAsMultiValue<M> = MultiValue6<
pub type PaymentsVec<M> = ManagedVec<M, EsdtTokenPayment<M>>;
pub type TxBatchSplitInFields<M> = MultiValue2<u64, MultiValueEncoded<M, TxAsMultiValue<M>>>;

#[derive(NestedEncode, NestedDecode, TypeAbi, Clone, ManagedVecItem)]
pub struct CallData<M: ManagedTypeApi> {
pub endpoint: ManagedBuffer<M>,
pub gas_limit: u64,
pub args: ManagedVec<M, ManagedBuffer<M>>,
}

impl<M: ManagedTypeApi> Default for CallData<M> {
#[inline]
fn default() -> Self {
Self {
endpoint: ManagedBuffer::new(),
gas_limit: 0,
args: ManagedVec::new(),
}
}
}
#[derive(TopDecode, TopEncode, NestedEncode, NestedDecode, TypeAbi, Clone, ManagedVecItem)]
#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone, ManagedVecItem)]
pub struct EthTransaction<M: ManagedTypeApi> {
pub from: EthAddress<M>,
pub to: ManagedAddress<M>,
Expand Down
2 changes: 1 addition & 1 deletion multi-transfer-esdt/tests/multi_transfer_blackbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use multiversx_sc_scenario::{

use eth_address::*;
use token_module::ProxyTrait as _;
use transaction::{CallData, EthTransaction, EthTransactionPayment};
use transaction::{call_data::CallData, EthTransaction, EthTransactionPayment};

const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456";
const BRIDGE_TOKEN_ID_EXPR: &str = "str:BRIDGE-123456";
Expand Down

0 comments on commit e46f95f

Please sign in to comment.