diff --git a/src/riscv/Cargo.lock b/src/riscv/Cargo.lock index e71f172ea70c90a8df7233c85044a1a8804b162b..2d8c43966385827c9a1149c321d39c1bb1782d67 100644 --- a/src/riscv/Cargo.lock +++ b/src/riscv/Cargo.lock @@ -1348,6 +1348,7 @@ dependencies = [ "rand 0.8.5", "rustc_apfloat", "serde", + "serde_json", "sha2 0.10.8", "strum 0.26.2", "tempfile", diff --git a/src/riscv/lib/Cargo.toml b/src/riscv/lib/Cargo.toml index e6f00483caa3846c1c7ad23a2e80c6d10034db54..dcb668da301aafd0673511472d7cfe7ebd153a49 100644 --- a/src/riscv/lib/Cargo.toml +++ b/src/riscv/lib/Cargo.toml @@ -16,6 +16,7 @@ num_enum.workspace = true paste.workspace = true rustc_apfloat.workspace = true serde.workspace = true +serde_json.workspace = true sha2.workspace = true strum.workspace = true tezos_crypto_rs.workspace = true diff --git a/src/riscv/lib/src/state_backend/owned_backend.rs b/src/riscv/lib/src/state_backend/owned_backend.rs index cfa80bfcfa85f73bd71cfe2c7eed3ded97cca657..66f848e4db3d031c0d62c313a0e7f8d3c01538d1 100644 --- a/src/riscv/lib/src/state_backend/owned_backend.rs +++ b/src/riscv/lib/src/state_backend/owned_backend.rs @@ -175,6 +175,13 @@ impl ManagerSerialise for Owned { region: &Self::Region, serializer: S, ) -> Result { + // A special encoding for single-element regions helps clean up encoding for serialisation + // formats that contain structures. For example, JSON, where single-element regions would + // be represented as array singletons. + if LEN == 1 { + return region[0].serialize(serializer); + } + // We're serialising this as a fixed-sized tuple because otherwise `bincode` would prefix // the length of this array, which is not needed. let mut serializer = serializer.serialize_tuple(LEN)?; @@ -203,6 +210,18 @@ impl ManagerDeserialise for Owned { >( deserializer: D, ) -> Result, D::Error> { + // A special encoding for single-element regions helps clean up encoding for serialisation + // formats that contain structures. For example, JSON, where single-element regions would + // be represented as array singletons. + if LEN == 1 { + let values = unsafe { + let mut values: [MaybeUninit; LEN] = mem::zeroed(); + values[0].write(E::deserialize(deserializer)?); + values.map(|value| value.assume_init()) + }; + return Ok(values); + } + struct Inner(PhantomData); impl<'de, E: serde::Deserialize<'de> + Sized, const LEN: usize> serde::de::Visitor<'de> @@ -341,4 +360,14 @@ pub mod test_helpers { assert_eq!(bytes, bytes_after); }); } + + /// Ensure that [`Cell`] serialises in a way that represents the underlying element + /// directly instead of wrapping it into an array (as it is an array under the hood). + #[test] + fn cell_direct_serialise() { + let cell: Cell = Cell::bind([42]); + let json_value = serde_json::to_value(cell).unwrap(); + let expected_json_value = serde_json::json!(42); + assert_eq!(json_value, expected_json_value); + } } diff --git a/src/rust_deps/Cargo.lock b/src/rust_deps/Cargo.lock index 12de255b8486d4d722f10ee9ef53ac2018c3e615..72b8b5a8a285ac216a612f5ec3e289586ca25daf 100644 --- a/src/rust_deps/Cargo.lock +++ b/src/rust_deps/Cargo.lock @@ -2232,6 +2232,7 @@ dependencies = [ "paste", "rustc_apfloat", "serde", + "serde_json", "sha2 0.10.8", "strum 0.26.2", "tezos-smart-rollup-constants",