iota_move_natives_latest/
tx_context.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, convert::TryFrom};
6
7use iota_types::base_types::{ObjectID, TransactionDigest};
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, natives::function::NativeResult, pop_arg, values::Value,
13};
14use smallvec::smallvec;
15
16use crate::{NativesCostTable, object_runtime::ObjectRuntime};
17
18#[derive(Clone)]
19pub struct TxContextDeriveIdCostParams {
20    pub tx_context_derive_id_cost_base: InternalGas,
21}
22/// ****************************************************************************
23/// ********************* native fun derive_id
24/// Implementation of the Move native function `fun derive_id(tx_hash:
25/// vector<u8>, ids_created: u64): address`   gas cost:
26/// tx_context_derive_id_cost_base                | we operate on fixed size
27/// data structures ************************************************************
28/// ***********************************
29pub fn derive_id(
30    context: &mut NativeContext,
31    ty_args: Vec<Type>,
32    mut args: VecDeque<Value>,
33) -> PartialVMResult<NativeResult> {
34    debug_assert!(ty_args.is_empty());
35    debug_assert!(args.len() == 2);
36
37    let tx_context_derive_id_cost_params = context
38        .extensions_mut()
39        .get::<NativesCostTable>()
40        .tx_context_derive_id_cost_params
41        .clone();
42    native_charge_gas_early_exit!(
43        context,
44        tx_context_derive_id_cost_params.tx_context_derive_id_cost_base
45    );
46
47    let ids_created = pop_arg!(args, u64);
48    let tx_hash = pop_arg!(args, Vec<u8>);
49
50    // unwrap safe because all digests in Move are serialized from the Rust
51    // `TransactionDigest`
52    let digest = TransactionDigest::try_from(tx_hash.as_slice()).unwrap();
53    let address = AccountAddress::from(ObjectID::derive_id(digest, ids_created));
54    let obj_runtime: &mut ObjectRuntime = context.extensions_mut().get_mut();
55    obj_runtime.new_id(address.into())?;
56
57    Ok(NativeResult::ok(
58        context.gas_used(),
59        smallvec![Value::address(address)],
60    ))
61}