Skip to content

Commit

Permalink
Support the data_struct related testing for the verifier. (#1729)
Browse files Browse the repository at this point in the history
* support the data_struct testing for verifier

append missed code

* fix the wrong status code

* remove the useless function

* change the used scope of the unsafe
  • Loading branch information
steelgeek091 authored May 23, 2024
1 parent 58f0bb6 commit c194798
Show file tree
Hide file tree
Showing 22 changed files with 327 additions and 131 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
processed 1 task

task 0 'publish'. lines 1-9:
status ABORTED with code 10006 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//# publish
module 0x1.TestModule1 {
metadata {
data_struct {
// error code 10006: MALFORMED_STRUCT_NAME
invalid_module_struct_name -> true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
processed 1 task

task 0 'publish'. lines 1-14:
status ABORTED with code 10001 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//# publish
module 0x1.TestModule1 {
metadata {
private_generics {
// error code 10001: FUNCTION_NOT_EXITS
0x1::TestModule1::f111 -> true;
}
}

public f1() {
label b0:
return;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
processed 1 task

task 0 'publish'. lines 1-9:
status ABORTED with code 10010 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//# publish
module 0x1.TestModule1 {
metadata {
private_generics {
// error code 10010: INVALID_MODULE_OWNER
0x123::SomeModule::f1 -> true;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
processed 1 task

task 0 'publish'. lines 1-11:
status ABORTED with code 10007 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//# publish
module 0x1.TestModule1 {
struct S0 has drop { x: u64 }

metadata {
private_generics {
// error code 10007: MALFORMED_FUNCTION_NAME
invalid_module_function_name -> true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ processed 2 tasks
task 0 'publish'. lines 1-8:
status EXECUTED

task 1 'publish'. lines 10-35:
status ABORTED with code 2 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
task 1 'publish'. lines 10-36:
status ABORTED with code 10008 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module 0x1.TestModule1 {
label b0:
s0 = TestModule0.new();
s1 = TestModule0.new();
// error code 10008: INVALID_DATA_STRUCT
Self.f1<TestModule0.S0, TestModule0.S0>(move(s0), move(s1));
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ processed 2 tasks
task 0 'publish'. lines 1-8:
status EXECUTED

task 1 'publish'. lines 10-35:
status ABORTED with code 2 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
task 1 'publish'. lines 10-36:
status ABORTED with code 10003 in 0000000000000000000000000000000000000000000000000000000000000002::move_module
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module 0x1.TestModule1 {
import 0x1.TestModule0;
metadata {
private_generics {
// error code 10003: NOT_ENOUGH_PARAMETERS
0x1::TestModule1::f1 -> [2, 3];
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ fn native_sort_and_verify_modules_inner(
Ok(_) => {}
Err(e) => {
log::info!("modules verification error: {:?}", e);
return Ok(NativeResult::err(cost, E_MODULE_VERIFICATION_ERROR));
let error_code = e.sub_status().unwrap_or(E_MODULE_VERIFICATION_ERROR);
return Ok(NativeResult::err(cost, error_code));
}
}

Expand Down
1 change: 1 addition & 0 deletions moveos/moveos-verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ move-command-line-common = { workspace = true }
move-vm-runtime = { workspace = true }
move-vm-types = { workspace = true }
move-symbol-pool = { workspace = true }
move-ir-types = { workspace = true }

moveos-types = { workspace = true }
log = "0.4.21"
57 changes: 57 additions & 0 deletions moveos/moveos-verifier/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use crate::metadata::{run_extended_checks, RuntimeModuleMetadataV1};
use codespan_reporting::diagnostic::Severity;
use itertools::Itertools;
use move_binary_format::CompiledModule;
use move_command_line_common::address::NumericalAddress;
use move_command_line_common::files::MOVE_COMPILED_EXTENSION;
use move_compiler::compiled_unit::CompiledUnit;
Expand All @@ -12,6 +13,9 @@ use move_compiler::Flags;
use move_core_types::account_address::AccountAddress;
use move_core_types::language_storage::ModuleId;
use move_core_types::metadata::Metadata;
use move_ir_types::ast::CopyableVal_;
use move_ir_types::ast::Exp_;
use move_ir_types::ast::Metadata as ASTMetadata;
use move_model::model::GlobalEnv;
use move_model::options::ModelBuilderOptions;
use move_model::run_model_builder_with_options_and_compilation_flags;
Expand Down Expand Up @@ -383,3 +387,56 @@ pub fn inject_runtime_metadata<P: AsRef<Path>>(
}
}
}

pub fn compile_and_inject_metadata(
compiled_module: &CompiledModule,
ast_metadata: ASTMetadata,
) -> CompiledModule {
let mut module = compiled_module.clone();

let mut rooch_metadata = RuntimeModuleMetadataV1::default();
for (metadata_type, metadata_item) in ast_metadata.value {
if metadata_type == "private_generics" {
let mut private_generics_map: BTreeMap<String, Vec<usize>> = BTreeMap::new();
for (metadata_key, metadata_value) in metadata_item.iter() {
let mut generic_type_indices: Vec<usize> = Vec::new();
for idx_expr in metadata_value.iter() {
let expr_value = idx_expr.value.clone();
if let Exp_::Value(copyable_val) = expr_value {
if let CopyableVal_::U64(u64_value) = copyable_val.value {
generic_type_indices.push(u64_value as usize);
}
}
}
private_generics_map.insert(metadata_key.clone(), generic_type_indices);
}

rooch_metadata.private_generics_indices = private_generics_map;
}

if metadata_type == "data_struct" {
let mut data_structs_map: BTreeMap<String, bool> = BTreeMap::new();
for (metadata_key, metadata_value) in metadata_item.iter() {
for idx_expr in metadata_value.iter() {
let expr_value = idx_expr.value.clone();
if let Exp_::Value(copyable_val) = expr_value {
if let CopyableVal_::Bool(bool_value) = copyable_val.value {
data_structs_map.insert(metadata_key.clone(), bool_value);
}
}
}
}

rooch_metadata.data_struct_map = data_structs_map;
}
}

let serialized_metadata =
bcs::to_bytes(&rooch_metadata).expect("BCS for RuntimeModuleMetadata");
module.metadata.push(Metadata {
key: ROOCH_METADATA_KEY.to_vec(),
value: serialized_metadata,
});

module
}
112 changes: 112 additions & 0 deletions moveos/moveos-verifier/src/error_code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use serde::{de, ser};
use std::fmt;
macro_rules! derive_code_try_from_repr {
(
#[repr($repr_ty:ident)]
$( #[$metas:meta] )*
$vis:vis enum $enum_name:ident {
$(
$variant:ident = $value: expr
),*
$( , )?
}
) => {
#[repr($repr_ty)]
$( #[$metas] )*
$vis enum $enum_name {
$(
$variant = $value
),*
}

impl std::convert::TryFrom<$repr_ty> for $enum_name {
type Error = &'static str;
fn try_from(value: $repr_ty) -> Result<Self, Self::Error> {
match value {
$(
$value => Ok($enum_name::$variant),
)*
_ => Err("invalid ErrorCode"),
}
}
}

#[cfg(any(test, feature = "fuzzing"))]
const ERROR_CODE_VALUES: &'static [$repr_ty] = &[
$($value),*
];
};
}

derive_code_try_from_repr! {
#[repr(u64)]
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum ErrorCode {
MALFORMED_METADATA = 10000,
FUNCTION_NOT_EXITS = 10001,
STRUCT_NOT_EXISTS = 10002,
NOT_ENOUGH_PARAMETERS = 10003,
TOO_MANY_PARAMETERS = 10004,
TYPE_MISMATCH = 10005,
MALFORMED_STRUCT_NAME = 10006,
MALFORMED_FUNCTION_NAME = 10007,
INVALID_DATA_STRUCT = 10008,
INVALID_DATA_STRUCT_TYPE = 10009,
INVALID_MODULE_OWNER = 10010,

INVALID_ENTRY_FUNC_SIGNATURE = 11000,
INVALID_PARAM_TYPE_ENTRY_FUNCTION = 11001,

INVALID_PUBLIC_INIT_FUNC = 12000,
INVALID_INIT_FUNC_WITH_ENTRY = 12001,
INVALID_TOO_MANY_PARAMS_INIT_FUNC = 12002,

INVALID_INSTRUCTION = 13000,

UNKNOWN_CODE = 18446744073709551615,
}
}

impl ser::Serialize for ErrorCode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_u64((*self).into())
}
}

impl<'de> de::Deserialize<'de> for ErrorCode {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct ErrorCodeVisitor;
impl<'de> de::Visitor<'de> for ErrorCodeVisitor {
type Value = ErrorCode;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("StatusCode as u64")
}

fn visit_u64<E>(self, v: u64) -> Result<ErrorCode, E>
where
E: de::Error,
{
Ok(ErrorCode::try_from(v).unwrap_or(ErrorCode::UNKNOWN_CODE))
}
}

deserializer.deserialize_u64(ErrorCodeVisitor)
}
}

impl From<ErrorCode> for u64 {
fn from(status: ErrorCode) -> u64 {
status as u64
}
}
2 changes: 2 additions & 0 deletions moveos/moveos-verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
pub mod build;
pub mod metadata;
pub mod verifier;

pub mod error_code;
16 changes: 7 additions & 9 deletions moveos/moveos-verifier/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1431,15 +1431,13 @@ fn check_func_data_struct(
return (true, "".to_string());
}

unsafe {
let data_struct_opt = {
let data = GLOBAL_DATA_STRUCT.read().unwrap();
data.get(full_struct_name.as_str()).map(|_| true)
};
if let Some(is_data_struct) = data_struct_opt {
if is_data_struct {
return (true, "".to_string());
}
let data_struct_opt = unsafe {
let data = GLOBAL_DATA_STRUCT.read().unwrap();
data.get(full_struct_name.as_str()).map(|_| true)
};
if let Some(is_data_struct) = data_struct_opt {
if is_data_struct {
return (true, "".to_string());
}
}

Expand Down
Loading

0 comments on commit c194798

Please sign in to comment.