From 6d40df8d14745a4deebf37b5a9f600319f9d489b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Thu, 19 Sep 2024 11:17:40 +0100 Subject: [PATCH] RISC-V: Specialise impl Serialise/Deserialise for 1-element regions --- src/riscv/Cargo.lock | 1 + src/riscv/lib/Cargo.toml | 1 + .../lib/src/state_backend/owned_backend.rs | 29 +++++++++++++++++++ src/rust_deps/Cargo.lock | 1 + 4 files changed, 32 insertions(+) diff --git a/src/riscv/Cargo.lock b/src/riscv/Cargo.lock index e71f172ea70c..2d8c43966385 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 e6f00483caa3..dcb668da301a 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 cfa80bfcfa85..66f848e4db3d 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 12de255b8486..72b8b5a8a285 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", -- GitLab