Skip to content

Commit

Permalink
Refactor EthTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
CostinCarabas committed Feb 15, 2024
1 parent dd30da5 commit b1c2fb6
Show file tree
Hide file tree
Showing 22 changed files with 625 additions and 162 deletions.
20 changes: 13 additions & 7 deletions bridge-proxy/src/bridge-proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ pub mod config;
use transaction::{EthTransaction, EthTransactionPayment};

#[multiversx_sc::contract]
pub trait BridgeProxyContract:
config::ConfigModule
+ multiversx_sc_modules::pause::PauseModule {
pub trait BridgeProxyContract:
config::ConfigModule + multiversx_sc_modules::pause::PauseModule
{
#[init]
fn init(&self, opt_multi_transfer_address: OptionalValue<ManagedAddress>) {
self.set_multi_transfer_contract_address(opt_multi_transfer_address);
Expand Down Expand Up @@ -38,11 +38,17 @@ pub trait BridgeProxyContract:
.unwrap_or_else(|| sc_panic!("Invalid ETH transaction!"));
let tx = tx_node.get_value_as_ref();

require!(tx.eth_tx.call_data.is_some(), "There is no data for a SC call!");

let call_data = unsafe { tx.eth_tx.call_data.clone().unwrap_unchecked() };
self.send()
.contract_call::<IgnoreValue>(tx.eth_tx.to.clone(), tx.eth_tx.data.clone())
.with_raw_arguments(tx.eth_tx.args.clone().into())
.contract_call::<IgnoreValue>(
tx.eth_tx.to.clone(),
call_data.endpoint.clone(),
)
.with_raw_arguments(call_data.args.clone().into())
.with_esdt_transfer((tx.token_id.clone(), tx.nonce, tx.amount.clone()))
.with_gas_limit(tx.eth_tx.gas_limit)
.with_gas_limit(call_data.gas_limit)
.async_call()
.with_callback(self.callbacks().failed_execution_callback(tx))
.call_and_exit();
Expand All @@ -56,7 +62,7 @@ pub trait BridgeProxyContract:
) {
if result.is_err() {
self.eth_failed_transaction_list().push_back(tx.clone());
}
}
}

#[endpoint(refundTransactions)]
Expand Down
26 changes: 16 additions & 10 deletions 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::{EthTransaction, EthTransactionPayment};
use transaction::{CallData, EthTransaction, EthTransactionPayment};

const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456";
const GAS_LIMIT: u64 = 1_000_000;
Expand Down Expand Up @@ -131,9 +131,11 @@ fn deploy_deposit_test() {
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args,
call_data: Some(CallData {
endpoint: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args,
}),
};

test.world.set_state_step(SetStateStep::new().put_account(
Expand Down Expand Up @@ -188,9 +190,11 @@ fn multiple_deposit_test() {
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args1,
call_data: Some(CallData {
endpoint: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args1,
}),
};

let mut args2 = ManagedVec::new();
Expand All @@ -202,9 +206,11 @@ fn multiple_deposit_test() {
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::zero(),
tx_nonce: 1u64,
data: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args2,
call_data: Some(CallData {
endpoint: ManagedBuffer::from(b"add"),
gas_limit: GAS_LIMIT,
args: args2,
}),
};

test.world.set_state_step(SetStateStep::new().put_account(
Expand Down
4 changes: 1 addition & 3 deletions bridge-proxy/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
// Total number of exported functions: 13

#![no_std]

// Configuration that works with rustc < 1.73.0.
// TODO: Recommended rustc version: 1.73.0 or newer.
#![allow(internal_features)]
#![feature(lang_items)]

multiversx_sc_wasm_adapter::allocator!();
Expand Down
98 changes: 19 additions & 79 deletions common/transaction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use eth_address::EthAddress;
use multiversx_sc::codec::{EncodeErrorHandler, NestedDecodeInput, TopEncodeOutput};

pub mod transaction_status;

// revert protection
Expand All @@ -28,97 +26,39 @@ 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 EthTransaction<M: ManagedTypeApi> {
pub from: EthAddress<M>,
pub to: ManagedAddress<M>,
pub token_id: TokenIdentifier<M>,
pub amount: BigUint<M>,
pub tx_nonce: TxNonce,
pub data: ManagedBuffer<M>,
pub struct CallData<M: ManagedTypeApi> {
pub endpoint: ManagedBuffer<M>,
pub gas_limit: u64,
pub args: ManagedVec<M, ManagedBuffer<M>>,
}

impl<M: ManagedTypeApi> TopEncode for EthTransaction<M> {
fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
where
O: TopEncodeOutput,
H: EncodeErrorHandler,
{
let mut nested_buffer = output.start_nested_encode();
self.from.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.to.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.token_id
.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.amount
.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.tx_nonce
.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.data.dep_encode_or_handle_err(&mut nested_buffer, h)?;
self.gas_limit
.dep_encode_or_handle_err(&mut nested_buffer, h)?;
for arg in &self.args {
arg.dep_encode_or_handle_err(&mut nested_buffer, h)?;
impl<M: ManagedTypeApi> Default for CallData<M> {
#[inline]
fn default() -> Self {
Self {
endpoint: ManagedBuffer::new(),
gas_limit: 0,
args: ManagedVec::new(),
}
output.finalize_nested_encode(nested_buffer);
Result::Ok(())
}
}

impl<M: ManagedTypeApi> TopDecode for EthTransaction<M> {
fn top_decode_or_handle_err<I, H>(input: I, h: H) -> Result<Self, H::HandledErr>
where
I: codec::TopDecodeInput,
H: codec::DecodeErrorHandler,
{
let mut nested_buffer = input.into_nested_buffer();
let from = EthAddress::dep_decode_or_handle_err(&mut nested_buffer, h)?;
let to = ManagedAddress::dep_decode_or_handle_err(&mut nested_buffer, h)?;
let token_id = TokenIdentifier::dep_decode_or_handle_err(&mut nested_buffer, h)?;
let amount = BigUint::dep_decode_or_handle_err(&mut nested_buffer, h)?;
let tx_nonce = TxNonce::dep_decode_or_handle_err(&mut nested_buffer, h)?;

let mut data = ManagedBuffer::new();
let mut gas_limit = 0u64;
let mut args = ManagedVec::new();

if !nested_buffer.is_depleted() {
data = ManagedBuffer::dep_decode_or_handle_err(&mut nested_buffer, h)?;
gas_limit = u64::dep_decode_or_handle_err(&mut nested_buffer, h)?;
args = ManagedVec::new();

while !nested_buffer.is_depleted() {
args.push(ManagedBuffer::dep_decode_or_handle_err(
&mut nested_buffer,
h,
)?);
}

}


Result::Ok(EthTransaction {
from,
to,
token_id,
amount,
tx_nonce,
data,
gas_limit,
args,
})
}
#[derive(TopDecode, TopEncode, NestedEncode, NestedDecode, TypeAbi, Clone, ManagedVecItem)]
pub struct EthTransaction<M: ManagedTypeApi> {
pub from: EthAddress<M>,
pub to: ManagedAddress<M>,
pub token_id: TokenIdentifier<M>,
pub amount: BigUint<M>,
pub tx_nonce: TxNonce,
pub call_data: Option<CallData<M>>,
}

pub type EthTxAsMultiValue<M> = MultiValue8<
pub type EthTxAsMultiValue<M> = MultiValue6<
EthAddress<M>,
ManagedAddress<M>,
TokenIdentifier<M>,
BigUint<M>,
TxNonce,
ManagedBuffer<M>,
u64,
ManagedVec<M, ManagedBuffer<M>>,
Option<CallData<M>>,
>;

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000",
"0x0102030405060708091011121314151617181920|address:user2|nested:str:WRAPPED-123456|biguint:500|u64:2|nested:str:data|u64:10000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|address:user2|nested:str:WRAPPED-123456|biguint:500|u64:2|0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:2000000",
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:100,500|u64:2|nested:str:data|u64:2000000"
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x0",
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:100,500|u64:2||0x01|nested:str:data|u64:90|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:1000000",
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:500|u64:2|nested:str:data|u64:1000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|sc:multi_transfer_esdt|nested:str:WRAPPED-123456|biguint:500|u64:2||0x0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000",
"0x0102030405060708091011121314151617181920|address:frozen_user|nested:str:BRIDGE-123456|biguint:500|u64:2|nested:str:data|u64:10000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|address:frozen_user|nested:str:BRIDGE-123456|biguint:500|u64:2||0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:2000000",
"0x0102030405060708091011121314151617181920|address:user2|nested:str:USDC-aaaaaa|biguint:500,000,000,000,000|u64:2|nested:str:data|u64:2000000",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:USDC-cccccc|biguint:1,000,000,000,000,000|u64:3|nested:str:data|u64:2000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|address:user2|nested:str:USDC-aaaaaa|biguint:500,000,000,000,000|u64:2||0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:USDC-cccccc|biguint:1,000,000,000,000,000|u64:3||0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
2 changes: 1 addition & 1 deletion multi-transfer-esdt/scenarios/transfer_ok.scen.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"function": "batchTransferEsdtToken",
"arguments": [
"1",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1|nested:str:data|u64:10000000",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:2|nested:str:data|u64:10000000"
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:1||0x01|nested:str:data|u64:10000000|u32:0",
"0x0102030405060708091011121314151617181920|address:user1|nested:str:BRIDGE-123456|biguint:100,200|u64:2||0x01|nested:str:data|u64:10000000|u32:0"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
Expand Down
11 changes: 9 additions & 2 deletions multi-transfer-esdt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub trait MultiTransferEsdt:

for eth_tx in transfers {
let mut must_refund = false;

if eth_tx.to.is_zero() {
self.transfer_failed_invalid_destination(batch_id, eth_tx.tx_nonce);
must_refund = true;
Expand All @@ -63,9 +64,15 @@ pub trait MultiTransferEsdt:
self.transfer_failed_frozen_destination_account(batch_id, eth_tx.tx_nonce);
must_refund = true;
} else if self.blockchain().is_smart_contract(&eth_tx.to)
&& (eth_tx.data.is_empty() || eth_tx.gas_limit < MIN_GAS_LIMIT_FOR_SC_CALL)
{
must_refund = true;
match &eth_tx.call_data {
Some(call_data) => {
if call_data.gas_limit < MIN_GAS_LIMIT_FOR_SC_CALL {
must_refund = true;
}
}
None => must_refund = true,
}
}

if must_refund {
Expand Down
18 changes: 11 additions & 7 deletions 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::{EthTransaction, EthTransactionPayment};
use transaction::{CallData, EthTransaction, EthTransactionPayment};

const BRIDGE_TOKEN_ID: &[u8] = b"BRIDGE-123456";
const BRIDGE_TOKEN_ID_EXPR: &str = "str:BRIDGE-123456";
Expand Down Expand Up @@ -277,9 +277,11 @@ fn basic_setup_test() {
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: BigUint::from(500u64),
tx_nonce: 1u64,
data: ManagedBuffer::from("data"),
gas_limit: GAS_LIMIT,
args: ManagedVec::new(),
call_data: Some(CallData {
endpoint: ManagedBuffer::from("data"),
gas_limit: GAS_LIMIT,
args: ManagedVec::new(),
}),
};

test.world.check_state_step(
Expand Down Expand Up @@ -314,9 +316,11 @@ fn basic_transfer_test() {
token_id: TokenIdentifier::from_esdt_bytes(BRIDGE_TOKEN_ID),
amount: token_amount.clone(),
tx_nonce: 1u64,
data: ManagedBuffer::from("data"),
gas_limit: GAS_LIMIT,
args: ManagedVec::new(),
call_data: Some(CallData {
endpoint: ManagedBuffer::from("data"),
gas_limit: GAS_LIMIT,
args: ManagedVec::new(),
}),
};

test.world.check_state_step(
Expand Down
Loading

0 comments on commit b1c2fb6

Please sign in to comment.