iota_move_natives_latest/
validator.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::iota_system_state::iota_system_state_inner_v1::ValidatorMetadataV1;
8use move_binary_format::errors::{PartialVMError, PartialVMResult};
9use move_core_types::{gas_algebra::InternalGas, vm_status::StatusCode};
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;
17
18#[derive(Clone, Debug)]
19pub struct ValidatorValidateMetadataBcsCostParams {
20    pub validator_validate_metadata_cost_base: InternalGas,
21    pub validator_validate_metadata_data_cost_per_byte: InternalGas,
22}
23/// ****************************************************************************
24/// ********************* native fun validate_metadata_bcs
25/// Implementation of the Move native function `validate_metadata_bcs(metadata:
26/// vector<u8>)`   gas cost: validator_validate_metadata_cost_base           |
27/// fixed cosrs
28///              + validator_validate_metadata_data_cost_per_byte *
29///                metadata_bytes.len()   | assume cost is proportional to size
30/// ****************************************************************************
31/// *******************
32pub fn validate_metadata_bcs(
33    context: &mut NativeContext,
34    ty_args: Vec<Type>,
35    mut args: VecDeque<Value>,
36) -> PartialVMResult<NativeResult> {
37    debug_assert!(ty_args.is_empty());
38    debug_assert!(args.len() == 1);
39
40    let validator_validate_metadata_bcs_cost_params = context
41        .extensions_mut()
42        .get::<NativesCostTable>()
43        .validator_validate_metadata_bcs_cost_params
44        .clone();
45
46    native_charge_gas_early_exit!(
47        context,
48        validator_validate_metadata_bcs_cost_params.validator_validate_metadata_cost_base
49    );
50
51    let metadata_bytes = pop_arg!(args, Vec<u8>);
52
53    native_charge_gas_early_exit!(
54        context,
55        validator_validate_metadata_bcs_cost_params.validator_validate_metadata_data_cost_per_byte
56            * (metadata_bytes.len() as u64).into()
57    );
58
59    let validator_metadata =
60        bcs::from_bytes::<ValidatorMetadataV1>(&metadata_bytes).map_err(|_| {
61            PartialVMError::new(StatusCode::MALFORMED).with_message(
62                "ValidatorMetadata Move struct does not match internal ValidatorMetadataV1 struct"
63                    .to_string(),
64            )
65        })?;
66
67    let cost = context.gas_used();
68
69    if let Result::Err(err_code) = validator_metadata.verify() {
70        return Ok(NativeResult::err(cost, err_code));
71    }
72
73    Ok(NativeResult::ok(cost, smallvec![]))
74}