Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integration of managedMultiTransferESDTNFTExecuteByUser #1711

Draft
wants to merge 4 commits into
base: feat/vm-1.7.next1
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions framework/base/src/api/send_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ pub trait SendApiImpl: ManagedTypeApiImpl {
arg_buffer_handle: RawHandle,
) -> Result<(), &'static [u8]>;

fn multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: RawHandle,
dst_handle: RawHandle,
token_transfer_handle: RawHandle,
gas_limit: u64,
function_name_handle: RawHandle,
arguments_handle: RawHandle,
) -> Result<(), &'static [u8]>;

/// Sends an asynchronous call to another contract.
/// Calling this method immediately terminates tx execution.
/// Using it directly is generally discouraged.
Expand Down
12 changes: 12 additions & 0 deletions framework/base/src/api/uncallable/send_api_uncallable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,16 @@ impl SendApiImpl for UncallableApi {
fn delete_from_return_data(&self, _index: usize) {
unreachable!()
}

fn multi_transfer_esdt_nft_execute_by_user(
&self,
_user_handle: RawHandle,
_dst_handle: RawHandle,
_token_transfer_handle: RawHandle,
_gas_limit: u64,
_function_name_handle: RawHandle,
_arguments_handle: RawHandle,
) -> Result<(), &'static [u8]> {
unreachable!()
}
}
19 changes: 19 additions & 0 deletions framework/base/src/contract_base/wrappers/send_raw_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,25 @@ where
)
}

pub fn multi_esdt_transfer_execute_by_user(
&self,
from: &ManagedAddress<A>,
to: &ManagedAddress<A>,
payments: &ManagedVec<A, EsdtTokenPayment<A>>,
gas_limit: u64,
endpoint_name: &ManagedBuffer<A>,
arg_buffer: &ManagedArgBuffer<A>,
) -> Result<(), &'static [u8]> {
A::send_api_impl().multi_transfer_esdt_nft_execute_by_user(
from.get_handle().get_raw_handle(),
to.get_handle().get_raw_handle(),
payments.get_handle().get_raw_handle(),
gas_limit,
endpoint_name.get_handle().get_raw_handle(),
arg_buffer.get_handle().get_raw_handle(),
)
}

pub fn async_call_raw(
&self,
to: &ManagedAddress<A>,
Expand Down
26 changes: 26 additions & 0 deletions framework/scenario/src/api/core_api_vh/send_api_vh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ impl<VHB: VMHooksApiBackend> SendApiImpl for VMHooksApi<VHB> {
}
}

fn multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: RawHandle,
dst_handle: RawHandle,
token_transfer_handle: RawHandle,
gas_limit: u64,
function_name_handle: RawHandle,
arguments_handle: RawHandle,
) -> Result<(), &'static [u8]> {
let result = self.with_vm_hooks(|vh| {
vh.managed_multi_transfer_esdt_nft_execute_by_user(
user_handle,
dst_handle,
token_transfer_handle,
gas_limit as i64,
function_name_handle,
arguments_handle,
)
});
if result == 0 {
Ok(())
} else {
Err(b"multiTransferESDTNFTExecuteByUser failed")
}
}

fn async_call_raw(
&self,
to_handle: RawHandle,
Expand Down
35 changes: 35 additions & 0 deletions framework/wasm-adapter/src/api/send_api_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ extern "C" {
argumentsHandle: i32,
) -> i32;

fn managedMultiTransferESDTNFTExecuteByUser(
userHandle: i32,
dstHandle: i32,
tokenTransfersHandle: i32,
gasLimit: i64,
functionHandle: i32,
argumentsHandle: i32,
) -> i32;

fn managedTransferValueExecute(
dstHandle: i32,
valueHandle: i32,
Expand Down Expand Up @@ -171,6 +180,32 @@ impl SendApiImpl for VmApiImpl {
}
}

fn multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: RawHandle,
dst_handle: RawHandle,
token_transfer_handle: RawHandle,
gas_limit: u64,
function_name_handle: RawHandle,
arguments_handle: RawHandle,
) -> Result<(), &'static [u8]> {
unsafe {
let result = managedMultiTransferESDTNFTExecuteByUser(
user_handle,
dst_handle,
token_transfer_handle,
gas_limit as i64,
function_name_handle,
arguments_handle,
);
if result == 0 {
Ok(())
} else {
Err(b"multiTransferESDTNFTExecuteByUser failed")
}
}
}

fn async_call_raw(
&self,
to_handle: RawHandle,
Expand Down
2 changes: 2 additions & 0 deletions vm/src/tx_mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod tx_managed_types;
mod tx_panic;
mod tx_result;
mod tx_result_calls;
mod tx_transfer_by_user_data;

pub use blockchain_update::BlockchainUpdate;
pub use tx_async_call_data::*;
Expand All @@ -36,6 +37,7 @@ pub use tx_managed_types::*;
pub use tx_panic::*;
pub use tx_result::*;
pub use tx_result_calls::*;
pub use tx_transfer_by_user_data::*;

#[cfg(feature = "wasm-incopatible")]
mod blockchain_rng;
Expand Down
45 changes: 45 additions & 0 deletions vm/src/tx_mock/tx_transfer_by_user_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::{
tx_mock::TxInput,
types::{VMAddress, H256},
};

use super::{CallType, TxFunctionName, TxTokenTransfer};

#[derive(Debug, Clone)]
pub struct TranferByUserData {
pub from: VMAddress,
pub to: VMAddress,
pub token_transfers: Vec<TxTokenTransfer>,
pub func_name: TxFunctionName,
pub arguments: Vec<Vec<u8>>,
pub tx_hash: H256,
}

pub fn transfer_by_user_tx_input(
transfer_by_user_call: &TranferByUserData,
call_type: CallType,
) -> TxInput {
let mut egld_value = num_bigint::BigUint::default();
let mut esdt_values = Vec::new();

for transfer in &transfer_by_user_call.token_transfers {
if transfer.token_identifier.is_empty() && transfer.nonce == 0 {
egld_value += &transfer.value;
} else {
esdt_values.push(transfer.clone());
}
}
TxInput {
from: transfer_by_user_call.from.clone(),
to: transfer_by_user_call.to.clone(),
egld_value,
esdt_values,
func_name: transfer_by_user_call.func_name.clone(),
args: transfer_by_user_call.arguments.clone(),
call_type,
gas_limit: 1000,
gas_price: 0,
tx_hash: transfer_by_user_call.tx_hash.clone(),
..Default::default()
}
}
33 changes: 21 additions & 12 deletions vm/src/vm_hooks/vh_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
}

#[allow(unused)]
impl VMHooks for VMHooksDispatcher {

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Contracts (nightly) / Test Coverage

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Contracts (nightly) / Wasm tests

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Contracts / Test Coverage

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Proxy compare - newly generated vs present in file tree

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Template tool test - released templates

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Template tool test - current (unreleased) templates

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`

Check failure on line 30 in vm/src/vm_hooks/vh_dispatcher.rs

View workflow job for this annotation

GitHub Actions / Contracts / Wasm tests

not all trait items implemented, missing: `get_round_time`, `epoch_start_block_time_stamp`, `epoch_start_block_nonce`, `epoch_start_block_round`, `mbuffer_to_small_int_unsigned`, `mbuffer_to_small_int_signed`, `mbuffer_from_small_int_unsigned`, `mbuffer_from_small_int_signed`
fn set_vm_hooks_ptr(&mut self, _vm_hooks_ptr: *mut c_void) {}

fn get_gas_left(&self) -> i64 {
Expand Down Expand Up @@ -901,6 +901,26 @@
0
}

fn managed_multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: i32,
dst_handle: i32,
token_transfers_handle: i32,
gas_limit: i64,
function_handle: i32,
arguments_handle: i32,
) -> i32 {
self.handler.multi_transfer_esdt_nft_execute_by_user(
user_handle,
dst_handle,
token_transfers_handle,
gas_limit as u64,
function_handle,
arguments_handle,
);
0
}

fn managed_transfer_value_execute(
&self,
dst_handle: i32,
Expand Down Expand Up @@ -1872,18 +1892,6 @@
panic!("Unavailable: managed_get_relayer_addr")
}

fn managed_multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: i32,
dst_handle: i32,
token_transfers_handle: i32,
gas_limit: i64,
function_handle: i32,
arguments_handle: i32,
) -> i32 {
panic!("Unavailable: managed_multi_transfer_esdt_nft_execute_by_user")
}

fn managed_verify_secp256r1(
&self,
key_handle: i32,
Expand All @@ -1892,6 +1900,7 @@
) -> i32 {
panic!("Unavailable: managed_verify_secp256r1")
}

fn managed_verify_blssignature_share(
&self,
key_handle: i32,
Expand Down
12 changes: 12 additions & 0 deletions vm/src/vm_hooks/vh_handler/vh_blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,18 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource {
);
}

fn managed_multi_transfer_esdt_nft_execute_by_user(
&self,
_user_handle: RawHandle,
_dst_handle: RawHandle,
_token_transfer_handle: RawHandle,
_gas_limit: i64,
_function_name_handle: RawHandle,
_arguments_handle: RawHandle,
) -> RawHandle {
todo!()
}

fn check_esdt_frozen(
&self,
address_handle: RawHandle,
Expand Down
26 changes: 26 additions & 0 deletions vm/src/vm_hooks/vh_handler/vh_send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,32 @@ pub trait VMHooksSend: VMHooksHandlerSource {
}
}

fn multi_transfer_esdt_nft_execute_by_user(
&self,
user_handle: RawHandle,
dst_handle: RawHandle,
token_transfer_handle: RawHandle,
_gas_limit: u64,
function_name_handle: RawHandle,
arguments_handle: RawHandle,
) {
let from = self.m_types_lock().mb_to_address(user_handle);
let to = self.m_types_lock().mb_to_address(dst_handle);
let payments = self
.m_types_lock()
.mb_get_vec_of_esdt_payments(token_transfer_handle);
let endpoint_name = self
.m_types_lock()
.mb_to_function_name(function_name_handle);
let arg_buffer = self.m_types_lock().mb_get_vec_of_bytes(arguments_handle);

let _sender = self.current_address();
if to.is_smart_contract_address() {
// && sender.shard == to.shard ?
self.perform_transfer_execute_by_user(from, to, payments, endpoint_name, arg_buffer);
}
}

fn async_call_raw(
&self,
to_handle: RawHandle,
Expand Down
59 changes: 57 additions & 2 deletions vm/src/vm_hooks/vh_impl/vh_debug_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
use crate::{
tx_execution::execute_current_tx_context_input,
tx_mock::{
async_call_tx_input, AsyncCallTxData, BackTransfers, BlockchainUpdate, CallType, TxCache,
TxContext, TxFunctionName, TxInput, TxManagedTypes, TxPanic, TxResult,
async_call_tx_input, transfer_by_user_tx_input, AsyncCallTxData, BackTransfers,
BlockchainUpdate, CallType, TranferByUserData, TxCache, TxContext, TxFunctionName, TxInput,
TxManagedTypes, TxPanic, TxResult, TxTokenTransfer,
},
types::{VMAddress, VMCodeMetadata},
vm_err_msg,
Expand Down Expand Up @@ -207,6 +208,41 @@
_ => self.vm_error(vm_err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT),
}
}

fn perform_transfer_execute_by_user(
&self,
from: VMAddress,
to: VMAddress,
token_transfers: Vec<TxTokenTransfer>,
func_name: TxFunctionName,
arguments: Vec<Vec<u8>>,
) {
let transfer_by_user_data =
self.create_transfer_by_user_data(from, to, token_transfers, func_name, arguments);
let mut tx_input =
transfer_by_user_tx_input(&transfer_by_user_data, CallType::TransferExecute);

if self.is_back_transfer(&tx_input) {
tx_input.call_type = CallType::BackTransfer;
}

let tx_cache = TxCache::new(self.0.blockchain_cache_arc());
let (tx_result, blockchain_updates) = self.0.vm_ref.execute_builtin_function_or_default(
tx_input,
tx_cache,
execute_current_tx_context_input,
);

match tx_result.result_status {
0 => {
self.0.result_lock().all_calls.push(transfer_by_user_data);

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts (nightly) / Rust tests

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts (nightly) / Test Coverage

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] vm/src/vm_hooks/vh_impl/vh_debug_api.rs#L238

error[E0308]: mismatched types --> vm/src/vm_hooks/vh_impl/vh_debug_api.rs:238:53 | 238 | self.0.result_lock().all_calls.push(transfer_by_user_data); | ---- ^^^^^^^^^^^^^^^^^^^^^ expected `AsyncCallTxData`, found `TranferByUserData` | | | arguments to this method are incorrect | note: method defined here --> /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/alloc/src/vec/mod.rs:1993:12
Raw output
vm/src/vm_hooks/vh_impl/vh_debug_api.rs:238:53:e:error[E0308]: mismatched types
   --> vm/src/vm_hooks/vh_impl/vh_debug_api.rs:238:53
    |
238 |                 self.0.result_lock().all_calls.push(transfer_by_user_data);
    |                                                ---- ^^^^^^^^^^^^^^^^^^^^^ expected `AsyncCallTxData`, found `TranferByUserData`
    |                                                |
    |                                                arguments to this method are incorrect
    |
note: method defined here
   --> /rustc/051478957371ee0084a7c0913941d2a8c4757bb9/library/alloc/src/vec/mod.rs:1993:12


__END__

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts / Rust tests

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts (nightly) / Wasm tests

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts / Test Coverage

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Proxy compare - newly generated vs present in file tree

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Template tool test - released templates

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Template tool test - current (unreleased) templates

mismatched types

Check failure on line 238 in vm/src/vm_hooks/vh_impl/vh_debug_api.rs

View workflow job for this annotation

GitHub Actions / Contracts / Wasm tests

mismatched types

let _ = self.sync_call_post_processing(tx_result, blockchain_updates);
},
10 => self.vm_error(&tx_result.result_message), // TODO: not sure it's the right condition, it catches insufficient funds
_ => self.vm_error(vm_err_msg::ERROR_SIGNALLED_BY_SMARTCONTRACT),
}
}
}

impl DebugApiVMHooksHandler {
Expand All @@ -229,6 +265,25 @@
}
}

fn create_transfer_by_user_data(
&self,
from: VMAddress,
to: VMAddress,
token_transfers: Vec<TxTokenTransfer>,
func_name: TxFunctionName,
arguments: Vec<Vec<u8>>,
) -> TranferByUserData {
let tx_hash = self.tx_hash();
TranferByUserData {
from,
to,
token_transfers,
func_name,
arguments,
tx_hash,
}
}

fn sync_call_post_processing(
&self,
tx_result: TxResult,
Expand Down
Loading
Loading