diff --git a/crates/json/src/json_to_value.rs b/crates/json/src/json_to_value.rs index 607ee3e6..d97bf2f1 100644 --- a/crates/json/src/json_to_value.rs +++ b/crates/json/src/json_to_value.rs @@ -98,6 +98,14 @@ pub fn convert_json_value_to_value( } Struct(layout) => match layout { WithTypes { fields, type_ } => { + // The move compiler inserts a dummy field with the value of false + // for structs with no fields. + if fields.len() == 1 && fields[0].name.as_str() == "dummy_field" { + return Ok(Value::struct_(Struct::pack(vec![ + Value::bool(false) + ]))); + } + let full_name = format!("{}::{}", type_.module_id().short_str_lossless(), type_.name); match full_name.as_str() { diff --git a/crates/json/src/move_to_json.rs b/crates/json/src/move_to_json.rs index f826c897..d4ed7780 100644 --- a/crates/json/src/move_to_json.rs +++ b/crates/json/src/move_to_json.rs @@ -59,6 +59,12 @@ fn convert_move_value_to_json_value(val: &MoveValue, depth: usize) -> VMResult { + // The move compiler inserts a dummy field with the value of false + // for structs with no fields. + if fields.len() == 1 && fields[0].0.as_str() == "dummy_field" { + return Ok(JSONValue::Object(Map::new())); + } + let mut fields_map: Map = Map::new(); for (id, mv) in fields.iter() { let value = convert_move_value_to_json_value(mv, depth + 1)?; @@ -68,6 +74,12 @@ fn convert_move_value_to_json_value(val: &MoveValue, depth: usize) -> VMResult { + // The move compiler inserts a dummy field with the value of false + // for structs with no fields. + if fields.len() == 1 && fields[0].0.as_str() == "dummy_field" { + return Ok(JSONValue::Object(Map::new())); + } + // check the struct type is string // if yes, then convert move value to json string // else, execute convert function recursively diff --git a/crates/natives/src/event.rs b/crates/natives/src/event.rs index 5809c840..eae453e2 100644 --- a/crates/natives/src/event.rs +++ b/crates/natives/src/event.rs @@ -27,6 +27,9 @@ const EUNABLE_TO_EMIT_EVENT_DELAYED_FIELD: u64 = (ECATEGORY_INVALID_ARGUMENT << #[derive(Default, Tid)] pub struct NativeEventContext { events: Vec<(ContractEvent, MoveTypeLayout)>, + + #[cfg(feature = "testing")] + events_for_testing: Vec<(Vec, TypeTag)>, } impl NativeEventContext { @@ -35,11 +38,11 @@ impl NativeEventContext { } #[cfg(feature = "testing")] - fn emitted_events(&self, ty_tag: &TypeTag) -> Vec<(&str, &MoveTypeLayout)> { - let mut events = vec![]; - for (event, ty_layout) in self.events.iter() { - if event.type_tag() == ty_tag { - events.push((event.event_data(), ty_layout)); + fn emitted_events(&self, ty_tag: &TypeTag) -> Vec<&[u8]> { + let mut events: Vec<&[u8]> = vec![]; + for (data, tt) in self.events_for_testing.iter() { + if tt == ty_tag { + events.push(data); } } events @@ -116,6 +119,19 @@ fn native_emit_event( })?; let ctx = context.extensions_mut().get_mut::(); + + // Cache the emitted event for testing. + #[cfg(feature = "testing")] + { + let blob = msg.simple_serialize(&layout).ok_or_else(|| { + SafeNativeError::InvariantViolation(PartialVMError::new( + StatusCode::VALUE_SERIALIZATION_ERROR, + )) + })?; + + ctx.events_for_testing.push((blob, type_tag.clone())); + } + ctx.events.push(( ContractEvent::new(type_tag, serde_value.to_string()), annotated_layout, @@ -130,18 +146,18 @@ fn native_emitted_events( ty_args: Vec, arguments: VecDeque, ) -> SafeNativeResult> { - use initia_move_json::deserialize_json_to_value; - debug_assert!(ty_args.len() == 1); debug_assert!(arguments.is_empty()); - let ty_tag = context.type_to_type_tag(&ty_args[0])?; + let ty = &ty_args[0]; + let ty_tag = context.type_to_type_tag(ty)?; + let ty_layout = context.type_to_type_layout(ty)?; let ctx = context.extensions_mut().get_mut::(); let events = ctx .emitted_events(&ty_tag) .into_iter() - .map(|(str, ty_layout)| { - deserialize_json_to_value(ty_layout, str.as_bytes()).map_err(|_| { + .map(|blob| { + Value::simple_deserialize(blob, &ty_layout).ok_or_else(|| { SafeNativeError::InvariantViolation(PartialVMError::new( StatusCode::VALUE_DESERIALIZATION_ERROR, )) diff --git a/precompile/binaries/minlib/block.mv b/precompile/binaries/minlib/block.mv index 9417962a..9d4419e0 100644 Binary files a/precompile/binaries/minlib/block.mv and b/precompile/binaries/minlib/block.mv differ diff --git a/precompile/binaries/stdlib/block.mv b/precompile/binaries/stdlib/block.mv index 9417962a..9d4419e0 100644 Binary files a/precompile/binaries/stdlib/block.mv and b/precompile/binaries/stdlib/block.mv differ diff --git a/precompile/modules/initia_stdlib/sources/account.move b/precompile/modules/initia_stdlib/sources/account.move index 0c66d28e..4d76c8cc 100644 --- a/precompile/modules/initia_stdlib/sources/account.move +++ b/precompile/modules/initia_stdlib/sources/account.move @@ -398,4 +398,11 @@ module initia_std::account { create_table_account(new_address); create_object_account(new_address); } + + // functions for compatibility with the aptos + + #[test_only] + public fun create_account_for_test(new_address: address): signer { + create_signer_for_test(new_address) + } } diff --git a/precompile/modules/initia_stdlib/sources/block.move b/precompile/modules/initia_stdlib/sources/block.move index 225fd405..4cce4797 100644 --- a/precompile/modules/initia_stdlib/sources/block.move +++ b/precompile/modules/initia_stdlib/sources/block.move @@ -12,4 +12,32 @@ module initia_std::block { assert!(height == 12321u64, 0); assert!(timestamp == 9999999u64, 1); } + + // Functions for compatibility with the aptos + + #[view] + public fun get_current_block_height(): u64 { + let (height, _) = get_block_info(); + height + } + + #[view] + public fun get_current_block_timestamp(): u64 { + let (_, timestamp) = get_block_info(); + timestamp + } + + #[test_only] + public fun initialize_for_test( + _vm: &signer, _epoch_interval_microsecs: u64 + ) { + // no-op + } + + #[test_only] + public fun emit_writeset_block_event( + _vm: &signer, _fake_block_hash: address + ) { + // no-op + } } diff --git a/precompile/modules/initia_stdlib/sources/code.move b/precompile/modules/initia_stdlib/sources/code.move index 2d3e34c9..21c0734e 100644 --- a/precompile/modules/initia_stdlib/sources/code.move +++ b/precompile/modules/initia_stdlib/sources/code.move @@ -177,9 +177,7 @@ module initia_std::code { &mut registry.metadata, option::none(), option::none(), 1 ); loop { - if (!table::prepare_mut(iter)) { - break; - }; + if (!table::prepare_mut(iter)) { break }; let (_, metadata) = table::next_mut(iter); metadata.upgrade_policy = UPGRADE_POLICY_IMMUTABLE; diff --git a/precompile/modules/initia_stdlib/sources/compatibility/reconfiguration.move b/precompile/modules/initia_stdlib/sources/compatibility/reconfiguration.move new file mode 100644 index 00000000..ae6bb987 --- /dev/null +++ b/precompile/modules/initia_stdlib/sources/compatibility/reconfiguration.move @@ -0,0 +1,6 @@ +#[test_only] +module initia_std::reconfiguration { + public fun initialize_for_test(_: &signer) { + // no-op + } +} diff --git a/precompile/modules/initia_stdlib/sources/json.move b/precompile/modules/initia_stdlib/sources/json.move index 76f69b9e..b39302e1 100644 --- a/precompile/modules/initia_stdlib/sources/json.move +++ b/precompile/modules/initia_stdlib/sources/json.move @@ -52,6 +52,18 @@ module initia_std::json { c: vector, } + #[test_only] + struct EmptyObject has copy, drop {} + + #[test] + fun test_empty_marshal_unmarshal_empty() { + let json = marshal(&EmptyObject{}); + assert!(json == b"{}", 1); + + let val = unmarshal(json); + assert!(val == EmptyObject{}, 2); + } + #[test] fun test_marshal_unmarshal_u64() { let json = marshal(&10u64); diff --git a/precompile/modules/minitia_stdlib/sources/account.move b/precompile/modules/minitia_stdlib/sources/account.move index c04476db..495e6d95 100644 --- a/precompile/modules/minitia_stdlib/sources/account.move +++ b/precompile/modules/minitia_stdlib/sources/account.move @@ -397,4 +397,11 @@ module minitia_std::account { create_table_account(new_address); create_object_account(new_address); } + + // functions for compatibility with the aptos + + #[test_only] + public fun create_account_for_test(new_address: address): signer { + create_signer_for_test(new_address) + } } diff --git a/precompile/modules/minitia_stdlib/sources/block.move b/precompile/modules/minitia_stdlib/sources/block.move index 4e461a46..a647d256 100644 --- a/precompile/modules/minitia_stdlib/sources/block.move +++ b/precompile/modules/minitia_stdlib/sources/block.move @@ -12,4 +12,32 @@ module minitia_std::block { assert!(height == 12321u64, 0); assert!(timestamp == 9999999u64, 1); } + + // Functions for compatibility with the aptos + + #[view] + public fun get_current_block_height(): u64 { + let (height, _) = get_block_info(); + height + } + + #[view] + public fun get_current_block_timestamp(): u64 { + let (_, timestamp) = get_block_info(); + timestamp + } + + #[test_only] + public fun initialize_for_test( + _vm: &signer, _epoch_interval_microsecs: u64 + ) { + // no-op + } + + #[test_only] + public fun emit_writeset_block_event( + _vm: &signer, _fake_block_hash: address + ) { + // no-op + } } diff --git a/precompile/modules/minitia_stdlib/sources/code.move b/precompile/modules/minitia_stdlib/sources/code.move index dad3e333..3c842a40 100644 --- a/precompile/modules/minitia_stdlib/sources/code.move +++ b/precompile/modules/minitia_stdlib/sources/code.move @@ -177,9 +177,7 @@ module minitia_std::code { &mut registry.metadata, option::none(), option::none(), 1 ); loop { - if (!table::prepare_mut(iter)) { - break; - }; + if (!table::prepare_mut(iter)) { break }; let (_, metadata) = table::next_mut(iter); metadata.upgrade_policy = UPGRADE_POLICY_IMMUTABLE; diff --git a/precompile/modules/minitia_stdlib/sources/compatibility/reconfiguration.move b/precompile/modules/minitia_stdlib/sources/compatibility/reconfiguration.move new file mode 100644 index 00000000..b36fac9f --- /dev/null +++ b/precompile/modules/minitia_stdlib/sources/compatibility/reconfiguration.move @@ -0,0 +1,6 @@ +#[test_only] +module minitia_std::reconfiguration { + public fun initialize_for_test(_: &signer) { + // no-op + } +} diff --git a/precompile/modules/minitia_stdlib/sources/json.move b/precompile/modules/minitia_stdlib/sources/json.move index 3ec8d28c..fcba9eb7 100644 --- a/precompile/modules/minitia_stdlib/sources/json.move +++ b/precompile/modules/minitia_stdlib/sources/json.move @@ -52,6 +52,18 @@ module minitia_std::json { c: vector, } + #[test_only] + struct EmptyObject has copy, drop {} + + #[test] + fun test_empty_marshal_unmarshal_empty() { + let json = marshal(&EmptyObject{}); + assert!(json == b"{}", 1); + + let val = unmarshal(json); + assert!(val == EmptyObject{}, 2); + } + #[test] fun test_marshal_unmarshal_u64() { let json = marshal(&10u64);