|
| 1 | +use std::collections::VecDeque; |
| 2 | + |
| 3 | +use move_binary_format::errors::PartialVMResult; |
| 4 | +use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte, NumBytes}; |
| 5 | +use move_vm_runtime::native_functions::NativeContext; |
| 6 | +use move_vm_types::loaded_data::runtime_types::Type; |
| 7 | +use move_vm_types::natives::function::NativeResult; |
| 8 | +use move_vm_types::pop_arg; |
| 9 | +use move_vm_types::values::Value; |
| 10 | +use serde_json::Number; |
| 11 | +use serde_json::Value as JSONValue; |
| 12 | +use smallvec::smallvec; |
| 13 | + |
| 14 | +use moveos_stdlib::natives::moveos_stdlib::wasm::E_CBOR_MARSHAL_FAILED; |
| 15 | + |
| 16 | +#[derive(Debug, Clone)] |
| 17 | +pub struct ArgsPackingGasParameters { |
| 18 | + pub base: InternalGas, |
| 19 | + pub per_byte: InternalGasPerByte, |
| 20 | +} |
| 21 | + |
| 22 | +impl ArgsPackingGasParameters { |
| 23 | + pub fn zeros() -> Self { |
| 24 | + Self { |
| 25 | + base: 0.into(), |
| 26 | + per_byte: 0.into(), |
| 27 | + } |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +/// Rust implementation of native_pack_inscribe_generate_args |
| 32 | +#[inline] |
| 33 | +pub(crate) fn native_pack_inscribe_generate_args( |
| 34 | + gas_params: &ArgsPackingGasParameters, |
| 35 | + _context: &mut NativeContext, |
| 36 | + _ty_args: Vec<Type>, |
| 37 | + mut args: VecDeque<Value>, |
| 38 | +) -> PartialVMResult<NativeResult> { |
| 39 | + let user_input_key = pop_arg!(args, Vec<u8>); |
| 40 | + let user_input = pop_arg!(args, Vec<u8>); |
| 41 | + let seed_key = pop_arg!(args, Vec<u8>); |
| 42 | + let seed = pop_arg!(args, Vec<u8>); |
| 43 | + let deploy_args_key = pop_arg!(args, Vec<u8>); |
| 44 | + let deploy_args = pop_arg!(args, Vec<u8>); |
| 45 | + |
| 46 | + let user_input_key_string = String::from_utf8_lossy(user_input_key.as_slice()).to_string(); |
| 47 | + let seed_key_string = String::from_utf8_lossy(seed_key.as_slice()).to_string(); |
| 48 | + let deploy_args_key_string = String::from_utf8_lossy(deploy_args_key.as_slice()).to_string(); |
| 49 | + |
| 50 | + // the top level cbor map |
| 51 | + let mut buffer_map = serde_json::Map::new(); |
| 52 | + |
| 53 | + // attrs |
| 54 | + let mut attrs_buffer_vec = Vec::new(); |
| 55 | + for byte in deploy_args.iter() { |
| 56 | + attrs_buffer_vec.push(serde_json::Value::Number(Number::from(byte.clone()))); |
| 57 | + } |
| 58 | + |
| 59 | + buffer_map.insert( |
| 60 | + deploy_args_key_string, |
| 61 | + serde_json::Value::Array(attrs_buffer_vec), |
| 62 | + ); |
| 63 | + |
| 64 | + // seed |
| 65 | + let seed_string = String::from_utf8_lossy(seed.as_slice()).to_string(); |
| 66 | + buffer_map.insert(seed_key_string, serde_json::Value::String(seed_string)); |
| 67 | + |
| 68 | + // user_input |
| 69 | + let user_input_string = String::from_utf8_lossy(user_input.as_slice()).to_string(); |
| 70 | + buffer_map.insert( |
| 71 | + user_input_key_string, |
| 72 | + serde_json::Value::String(user_input_string), |
| 73 | + ); |
| 74 | + |
| 75 | + // marshal the cbor map to bytes |
| 76 | + let top_buffer_map = JSONValue::Object(buffer_map); |
| 77 | + let mut top_buffer = Vec::new(); |
| 78 | + match ciborium::into_writer(&top_buffer_map, &mut top_buffer) { |
| 79 | + Ok(_) => {} |
| 80 | + Err(_) => { |
| 81 | + return Ok(NativeResult::err(gas_params.base, E_CBOR_MARSHAL_FAILED)); |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + let mut cost = gas_params.base; |
| 86 | + let total_length = user_input_key.len() |
| 87 | + + user_input.len() |
| 88 | + + seed_key.len() |
| 89 | + + seed.len() |
| 90 | + + deploy_args_key.len() |
| 91 | + + deploy_args.len(); |
| 92 | + cost += gas_params.per_byte * NumBytes::new(total_length as u64); |
| 93 | + |
| 94 | + let ret = Value::vector_u8(top_buffer); |
| 95 | + Ok(NativeResult::ok(cost, smallvec![ret])) |
| 96 | +} |
0 commit comments