Skip to main content

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