iota_move_natives_latest/
object.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::collections::VecDeque;
6
7use move_binary_format::errors::PartialVMResult;
8use move_core_types::{account_address::AccountAddress, gas_algebra::InternalGas};
9use move_vm_runtime::{native_charge_gas_early_exit, native_functions::NativeContext};
10use move_vm_types::{
11    loaded_data::runtime_types::Type,
12    natives::function::NativeResult,
13    pop_arg,
14    values::{StructRef, Value},
15};
16use smallvec::smallvec;
17
18use crate::{NativesCostTable, object_runtime::ObjectRuntime};
19
20#[derive(Clone)]
21pub struct BorrowUidCostParams {
22    pub object_borrow_uid_cost_base: InternalGas,
23}
24/// ****************************************************************************
25/// ********************* native fun borrow_uid
26/// Implementation of the Move native function `borrow_uid<T: key>(obj: &T):
27/// &UID`   gas cost: object_borrow_uid_cost_base                | this is hard
28/// to calculate as it's very sensitive to `borrow_field` impl. Making it flat
29/// ****************************************************************************
30/// *******************
31pub fn borrow_uid(
32    context: &mut NativeContext,
33    ty_args: Vec<Type>,
34    mut args: VecDeque<Value>,
35) -> PartialVMResult<NativeResult> {
36    debug_assert!(ty_args.len() == 1);
37    debug_assert!(args.len() == 1);
38
39    let borrow_uid_cost_params = context
40        .extensions_mut()
41        .get::<NativesCostTable>()
42        .borrow_uid_cost_params
43        .clone();
44
45    // Charge base fee
46    native_charge_gas_early_exit!(context, borrow_uid_cost_params.object_borrow_uid_cost_base);
47
48    let obj = pop_arg!(args, StructRef);
49    let id_field = obj.borrow_field(0)?;
50
51    Ok(NativeResult::ok(context.gas_used(), smallvec![id_field]))
52}
53
54#[derive(Clone)]
55pub struct DeleteImplCostParams {
56    pub object_delete_impl_cost_base: InternalGas,
57}
58/// ****************************************************************************
59/// ********************* native fun delete_impl
60/// Implementation of the Move native function `delete_impl(id: address)`
61///   gas cost: cost_base                | this is a simple ID deletion
62/// ****************************************************************************
63/// *******************
64pub fn delete_impl(
65    context: &mut NativeContext,
66    ty_args: Vec<Type>,
67    mut args: VecDeque<Value>,
68) -> PartialVMResult<NativeResult> {
69    debug_assert!(ty_args.is_empty());
70    debug_assert!(args.len() == 1);
71
72    let delete_impl_cost_params = context
73        .extensions_mut()
74        .get::<NativesCostTable>()
75        .delete_impl_cost_params
76        .clone();
77
78    // Charge base fee
79    native_charge_gas_early_exit!(
80        context,
81        delete_impl_cost_params.object_delete_impl_cost_base
82    );
83
84    // unwrap safe because the interface of native function guarantees it.
85    let uid_bytes = pop_arg!(args, AccountAddress);
86
87    let obj_runtime: &mut ObjectRuntime = context.extensions_mut().get_mut();
88    obj_runtime.delete_id(uid_bytes.into())?;
89    Ok(NativeResult::ok(context.gas_used(), smallvec![]))
90}
91
92#[derive(Clone)]
93pub struct RecordNewIdCostParams {
94    pub object_record_new_uid_cost_base: InternalGas,
95}
96/// ****************************************************************************
97/// ********************* native fun record_new_uid
98/// Implementation of the Move native function `record_new_uid(id: address)`
99///   gas cost: object_record_new_uid_cost_base                | this is a
100/// simple ID addition *********************************************************
101/// **************************************
102pub fn record_new_uid(
103    context: &mut NativeContext,
104    ty_args: Vec<Type>,
105    mut args: VecDeque<Value>,
106) -> PartialVMResult<NativeResult> {
107    debug_assert!(ty_args.is_empty());
108    debug_assert!(args.len() == 1);
109
110    let record_new_id_cost_params = context
111        .extensions_mut()
112        .get::<NativesCostTable>()
113        .record_new_id_cost_params
114        .clone();
115
116    // Charge base fee
117    native_charge_gas_early_exit!(
118        context,
119        record_new_id_cost_params.object_record_new_uid_cost_base
120    );
121
122    // unwrap safe because the interface of native function guarantees it.
123    let uid_bytes = pop_arg!(args, AccountAddress);
124
125    let obj_runtime: &mut ObjectRuntime = context.extensions_mut().get_mut();
126    obj_runtime.new_id(uid_bytes.into())?;
127    Ok(NativeResult::ok(context.gas_used(), smallvec![]))
128}