Skip to content

Commit

Permalink
Merge pull request #1400 from multiversx/rust-vm-builtin-function-hook
Browse files Browse the repository at this point in the history
impl for is builtin function rust vm hook
  • Loading branch information
andrei-marinica authored Jan 29, 2024
2 parents d71977d + e0ad2fe commit 2fe5305
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"steps": [
{
"step": "setState",
"accounts": {
"sc:basic-features": {
"nonce": "0",
"balance": "0",
"code": "mxsc:../output/basic-features.mxsc.json",
"codeMetadata": "0x0104"
},
"address:an_account": {
"nonce": "0",
"balance": "0"
}
}
},
{
"step": "scCall",
"id": "is builtin function - true",
"tx": {
"from": "address:an_account",
"to": "sc:basic-features",
"function": "is_builtin_function",
"arguments": [
"str:ESDTTransfer"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
},
"expect": {
"out": [
"0x01"
],
"status": "",
"logs": "*",
"gas": "*",
"refund": "*"
}
},
{
"step": "scCall",
"id": "is builtin function - false",
"tx": {
"from": "address:an_account",
"to": "sc:basic-features",
"function": "is_builtin_function",
"arguments": [
"str:anyFunction"
],
"gasLimit": "50,000,000",
"gasPrice": "0"
},
"expect": {
"out": [
"0x"
],
"status": "",
"logs": "*",
"gas": "*",
"refund": "*"
}
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ pub trait BlockchainApiFeatures {
fn get_code_metadata(&self, address: ManagedAddress) -> CodeMetadata {
self.blockchain().get_code_metadata(&address)
}

#[endpoint]
fn is_builtin_function(&self, function_name: ManagedBuffer) -> bool {
self.blockchain().is_builtin_function(&function_name)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use multiversx_sc_scenario::*;

fn world() -> ScenarioWorld {
let mut blockchain = ScenarioWorld::new();
blockchain.set_current_dir_from_workspace("contracts/feature-tests/basic-features");

blockchain.register_contract(
"mxsc:output/basic-features.mxsc.json",
basic_features::ContractBuilder,
);

blockchain
}

#[test]
fn is_builtin_function_test() {
world().run("scenarios/is_builtin_function.scen.json");
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ fn get_shard_of_address_go() {
world().run("scenarios/get_shard_of_address.scen.json");
}

#[test]
fn is_builtin_function_go() {
world().run("scenarios/is_builtin_function.scen.json");
}

#[test]
fn managed_address_array_go() {
world().run("scenarios/managed_address_array.scen.json");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,11 @@ fn get_shard_of_address_rs() {
world().run("scenarios/get_shard_of_address.scen.json");
}

#[test]
fn is_builtin_function_rs() {
world().run("scenarios/is_builtin_function.scen.json");
}

#[test]
fn managed_address_array_rs() {
world().run("scenarios/managed_address_array.scen.json");
Expand Down
5 changes: 3 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: 374
// Endpoints: 375
// Async Callback: 1
// Total number of exported functions: 376
// Total number of exported functions: 377

#![no_std]
#![allow(internal_features)]
Expand Down Expand Up @@ -130,6 +130,7 @@ multiversx_sc_wasm_adapter::endpoints! {
get_gas_left => get_gas_left
get_cumulated_validator_rewards => get_cumulated_validator_rewards
get_code_metadata => get_code_metadata
is_builtin_function => is_builtin_function
codec_err_finish => codec_err_finish
codec_err_storage_key => codec_err_storage_key
codec_err_storage_get => codec_err_storage_get
Expand Down
2 changes: 2 additions & 0 deletions framework/base/src/api/blockchain_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,6 @@ pub trait BlockchainApiImpl: ManagedTypeApiImpl {
address_handle: Self::ManagedBufferHandle,
response_handle: Self::ManagedBufferHandle,
);

fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool;
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,11 @@ impl BlockchainApiImpl for UncallableApi {
) {
unreachable!()
}

fn managed_is_builtin_function(
&self,
_function_name_handle: Self::ManagedBufferHandle,
) -> bool {
unreachable!()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ where
CodeMetadata::from(buffer)
}

#[inline]
pub fn is_builtin_function(&self, function_name: &ManagedBuffer<A>) -> bool {
A::blockchain_api_impl().managed_is_builtin_function(function_name.get_handle())
}

#[inline]
pub fn get_sc_balance(&self, token: &EgldOrEsdtTokenIdentifier<A>, nonce: u64) -> BigUint<A> {
token.map_ref_or_else(
Expand Down
6 changes: 6 additions & 0 deletions framework/scenario/src/api/core_api_vh/blockchain_api_vh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ impl<VHB: VMHooksApiBackend> BlockchainApiImpl for VMHooksApi<VHB> {
multiversx_sc::types::EsdtLocalRoleFlags::from_bits_retain(result as u64)
}

fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool {
i32_to_bool(self.with_vm_hooks(|vh| {
vh.managed_is_builtin_function(function_name_handle.get_raw_handle_unchecked())
}))
}

fn managed_get_code_metadata(
&self,
address_handle: Self::ManagedBufferHandle,
Expand Down
6 changes: 6 additions & 0 deletions framework/wasm-adapter/src/api/blockchain_api_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ extern "C" {
fn getESDTLocalRoles(tokenhandle: i32) -> i64;

fn managedGetCodeMetadata(addressHandle: i32, resultHandle: i32);

fn managedIsBuiltinFunction(function_name_handle: i32) -> bool;
}

impl BlockchainApi for VmApiImpl {
Expand Down Expand Up @@ -363,6 +365,10 @@ impl BlockchainApiImpl for VmApiImpl {
} as u64)
}

fn managed_is_builtin_function(&self, function_name_handle: Self::ManagedBufferHandle) -> bool {
unsafe { managedIsBuiltinFunction(function_name_handle) }
}

fn managed_get_code_metadata(
&self,
address_handle: Self::ManagedBufferHandle,
Expand Down
5 changes: 4 additions & 1 deletion vm/src/vm_hooks/vh_dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,10 @@ impl VMHooks for VMHooksDispatcher {
}

fn managed_is_builtin_function(&self, function_name_handle: i32) -> i32 {
panic!("Unavailable: managed_is_builtin_function")
bool_to_i32(
self.handler
.managed_is_builtin_function(function_name_handle),
)
}

fn big_float_new_from_parts(
Expand Down
28 changes: 28 additions & 0 deletions vm/src/vm_hooks/vh_handler/vh_blockchain.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{
tx_execution::vm_builtin_function_names::*,
types::{EsdtLocalRole, EsdtLocalRoleFlags, RawHandle, VMAddress},
vm_hooks::VMHooksHandlerSource,
world_mock::{EsdtData, EsdtInstance},
Expand All @@ -8,6 +9,24 @@ use num_traits::Zero;

// The Go VM doesn't do it, but if we change that, we can enable it easily here too via this constant.
const ESDT_TOKEN_DATA_FUNC_RESETS_VALUES: bool = false;
const VM_BUILTIN_FUNCTION_NAMES: [&str; 16] = [
ESDT_LOCAL_MINT_FUNC_NAME,
ESDT_LOCAL_BURN_FUNC_NAME,
ESDT_MULTI_TRANSFER_FUNC_NAME,
ESDT_NFT_TRANSFER_FUNC_NAME,
ESDT_NFT_CREATE_FUNC_NAME,
ESDT_NFT_ADD_QUANTITY_FUNC_NAME,
ESDT_NFT_ADD_URI_FUNC_NAME,
ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME,
ESDT_NFT_BURN_FUNC_NAME,
ESDT_TRANSFER_FUNC_NAME,
CHANGE_OWNER_BUILTIN_FUNC_NAME,
CLAIM_DEVELOPER_REWARDS_FUNC_NAME,
SET_USERNAME_FUNC_NAME,
MIGRATE_USERNAME_FUNC_NAME,
DELETE_USERNAME_FUNC_NAME,
UPGRADE_CONTRACT_FUNC_NAME,
];

pub trait VMHooksBlockchain: VMHooksHandlerSource {
fn is_contract_address(&self, address_bytes: &[u8]) -> bool {
Expand Down Expand Up @@ -151,6 +170,15 @@ pub trait VMHooksBlockchain: VMHooksHandlerSource {
.mb_set(response_handle, code_metadata_bytes.to_vec())
}

fn managed_is_builtin_function(&self, function_name_handle: i32) -> bool {
VM_BUILTIN_FUNCTION_NAMES.contains(
&self
.m_types_lock()
.mb_to_function_name(function_name_handle)
.as_str(),
)
}

#[allow(clippy::too_many_arguments)]
fn managed_get_esdt_token_data(
&self,
Expand Down

0 comments on commit 2fe5305

Please sign in to comment.