diff --git a/aptos-move/framework/aptos-stdlib/aptos-framework/releases/artifacts/current/error_description/error_description.errmap b/aptos-move/framework/aptos-stdlib/aptos-framework/releases/artifacts/current/error_description/error_description.errmap new file mode 100644 index 0000000000000..4dd6c3b82bf32 Binary files /dev/null and b/aptos-move/framework/aptos-stdlib/aptos-framework/releases/artifacts/current/error_description/error_description.errmap differ diff --git a/aptos-move/framework/aptos-stdlib/sources/type_info.move b/aptos-move/framework/aptos-stdlib/sources/type_info.move index 2989c0529d80e..5bdc186a31dd6 100644 --- a/aptos-move/framework/aptos-stdlib/sources/type_info.move +++ b/aptos-move/framework/aptos-stdlib/sources/type_info.move @@ -1,4 +1,6 @@ module aptos_std::type_info { + use std::string; + struct TypeInfo has copy, drop, store { account_address: address, module_name: vector<u8>, @@ -18,6 +20,7 @@ module aptos_std::type_info { } public native fun type_of<T>(): TypeInfo; + public native fun type_name<T>(): string::String; #[test] fun test() { @@ -26,4 +29,31 @@ module aptos_std::type_info { assert!(module_name(&type_info) == b"type_info", 1); assert!(struct_name(&type_info) == b"TypeInfo", 2); } + + #[test] + fun test_type_name() { + use aptos_std::table::Table; + + assert!(type_name<bool>() == string::utf8(b"bool"), 0); + assert!(type_name<u8>() == string::utf8(b"u8"), 1); + assert!(type_name<u64>() == string::utf8(b"u64"), 2); + assert!(type_name<u128>() == string::utf8(b"u128"), 3); + assert!(type_name<address>() == string::utf8(b"address"), 4); + assert!(type_name<signer>() == string::utf8(b"signer"), 5); + + // vector + assert!(type_name<vector<u8>>() == string::utf8(b"vector<u8>"), 6); + assert!(type_name<vector<vector<u8>>>() == string::utf8(b"vector<vector<u8>>"), 7); + assert!(type_name<vector<vector<TypeInfo>>>() == string::utf8(b"vector<vector<0x1::type_info::TypeInfo>>"), 8); + + + // struct + assert!(type_name<TypeInfo>() == string::utf8(b"0x1::type_info::TypeInfo"), 9); + assert!(type_name< + Table< + TypeInfo, + Table<u8, vector<TypeInfo>> + > + >() == string::utf8(b"0x1::table::Table<0x1::type_info::TypeInfo, 0x1::table::Table<u8, vector<0x1::type_info::TypeInfo>>>"), 10); + } } diff --git a/aptos-move/framework/src/natives/mod.rs b/aptos-move/framework/src/natives/mod.rs index 0b42d10a9d96d..1c74fa539e53c 100644 --- a/aptos-move/framework/src/natives/mod.rs +++ b/aptos-move/framework/src/natives/mod.rs @@ -14,6 +14,7 @@ use move_deps::{ pub mod cost { pub const APTOS_CREATE_ADDRESS: u64 = 5; pub const APTOS_LIB_TYPE_OF: u64 = 10; + pub const APTOS_LIB_TYPE_NAME: u64 = 10; pub const APTOS_SIP_HASH: u64 = 10; pub const APTOS_SECP256K1_RECOVER: u64 = 71; } @@ -50,6 +51,7 @@ pub fn all_natives(framework_addr: AccountAddress) -> NativeFunctionTable { signature::native_secp256k1_recover, ), ("type_info", "type_of", type_info::type_of), + ("type_info", "type_name", type_info::type_name), ("hash", "sip_hash", hash::native_sip_hash), ]; NATIVES diff --git a/aptos-move/framework/src/natives/type_info.rs b/aptos-move/framework/src/natives/type_info.rs index 6367ac85cc56d..d475e56e9e6d4 100644 --- a/aptos-move/framework/src/natives/type_info.rs +++ b/aptos-move/framework/src/natives/type_info.rs @@ -29,6 +29,7 @@ pub fn type_of( let cost = GasCost::new(super::cost::APTOS_LIB_TYPE_OF, 1).total(); let type_tag = context.type_to_type_tag(&ty_args[0])?; + if let TypeTag::Struct(struct_tag) = type_tag { Ok(NativeResult::ok( cost, @@ -42,6 +43,27 @@ pub fn type_of( } } +/// Returns a string representing the TypeTag of the parameter. +pub fn type_name( + context: &mut NativeContext, + ty_args: Vec<Type>, + arguments: VecDeque<Value>, +) -> PartialVMResult<NativeResult> { + debug_assert!(ty_args.len() == 1); + debug_assert!(arguments.is_empty()); + + let cost = GasCost::new(super::cost::APTOS_LIB_TYPE_NAME, 1).total(); + let type_tag = context.type_to_type_tag(&ty_args[0])?; + let type_name = type_tag.to_string(); + + Ok(NativeResult::ok( + cost, + smallvec![Value::struct_(Struct::pack(vec![Value::vector_u8( + type_name.as_bytes().to_vec() + )]))], + )) +} + fn type_of_internal(struct_tag: &StructTag) -> Result<SmallVec<[Value; 1]>, std::fmt::Error> { let mut name = struct_tag.name.to_string(); if let Some(first_ty) = struct_tag.type_params.first() { diff --git a/aptos-move/framework/tests/move_unit_test.rs b/aptos-move/framework/tests/move_unit_test.rs index 075d1cffb5da2..0af58ac547e2d 100644 --- a/aptos-move/framework/tests/move_unit_test.rs +++ b/aptos-move/framework/tests/move_unit_test.rs @@ -41,10 +41,15 @@ pub fn aptos_test_natives() -> NativeFunctionTable { } #[test] -fn move_unit_tests() { +fn move_framework_unit_tests() { run_tests_for_pkg("aptos-framework"); } +#[test] +fn move_stdlib_unit_tests() { + run_tests_for_pkg("aptos-stdlib"); +} + #[test] fn move_token_unit_tests() { run_tests_for_pkg("aptos-token"); diff --git a/testsuite/run_forge.sh b/testsuite/run_forge.sh index 4c503081d3053..f186c8a0719d1 100755 --- a/testsuite/run_forge.sh +++ b/testsuite/run_forge.sh @@ -14,7 +14,7 @@ pwd | grep -qE 'aptos-core$' || (echo "Please run from aptos-core root directory # for calculating regression TPS_THRESHOLD=5000 -P99_LATENCY_MS_THRESHOLD=6000 +P99_LATENCY_MS_THRESHOLD=8000 FORGE_OUTPUT=${FORGE_OUTPUT:-forge_output.txt} FORGE_REPORT=${FORGE_REPORT:-forge_report.json}