From faa3838cb64c4ffcbe096cc633efde767bfee010 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Tue, 20 May 2025 20:14:16 +0700 Subject: [PATCH 1/5] fix: deserialization function for u16 group maps was broken --- .../serialized_version/v1/mod.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index c9144dfa7c7..67ebb168f3b 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -15,6 +15,7 @@ use crate::prelude::BlockHeight; use bincode::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)] @@ -75,15 +76,25 @@ fn deserialize_u16_group_map<'de, D>( where D: serde::Deserializer<'de>, { - let map: BTreeMap = BTreeMap::deserialize(deserializer)?; - map.into_iter() + let raw: Value = Value::deserialize(deserializer)?; + + let json: JsonValue = raw + .try_into() + .map_err(|e| serde::de::Error::custom(format!("groups: {}", e)))?; + + let by_string: BTreeMap = + serde_json::from_value(json).map_err(serde::de::Error::custom)?; + + by_string + .into_iter() .map(|(k, v)| { k.parse::() - .map_err(serde::de::Error::custom) - .map(|key| (key, v)) + .map(|pos| (pos, v)) + .map_err(|e| serde::de::Error::custom(format!("invalid group key '{}': {}", k, e))) }) .collect() } + fn deserialize_u16_token_configuration_map<'de, D>( deserializer: D, ) -> Result, D::Error> From 1c5f1f7f72d61f9256668d4b930041db3377c04d Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 21 May 2025 13:45:52 +0700 Subject: [PATCH 2/5] fix --- packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 67ebb168f3b..bdbc164100b 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -79,7 +79,7 @@ where let raw: Value = Value::deserialize(deserializer)?; let json: JsonValue = raw - .try_into() + .try_to_validating_json() .map_err(|e| serde::de::Error::custom(format!("groups: {}", e)))?; let by_string: BTreeMap = From 469da9487583e58ceceb9d72efbd961606f9e5e5 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 21 May 2025 18:30:09 +0700 Subject: [PATCH 3/5] fix --- .../serialized_version/v1/mod.rs | 67 ++++++++++++++----- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index bdbc164100b..0ab4e14468e 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -4,6 +4,7 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::block::epoch::EpochIndex; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::v0::GroupV0; use crate::data_contract::group::Group; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; @@ -15,7 +16,6 @@ use crate::prelude::BlockHeight; use bincode::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)] @@ -70,29 +70,62 @@ pub struct DataContractInSerializationFormatV1 { pub description: Option, } +/// Deserialize `groups` map with stringified u16 keys and enum-wrapped `Group` values. +/// +/// Accepts: +/// ```json +/// { +/// "0": { +/// "V0": { +/// "members": { "...": 1 }, +/// "required_power": 3 +/// } +/// } +/// } +/// ``` fn deserialize_u16_group_map<'de, D>( deserializer: D, ) -> Result, D::Error> where D: serde::Deserializer<'de>, { - let raw: Value = Value::deserialize(deserializer)?; - - let json: JsonValue = raw - .try_to_validating_json() - .map_err(|e| serde::de::Error::custom(format!("groups: {}", e)))?; - - let by_string: BTreeMap = - serde_json::from_value(json).map_err(serde::de::Error::custom)?; + let map: BTreeMap = BTreeMap::deserialize(deserializer)?; + + let mut out = BTreeMap::new(); + + for (key_str, group_value) in map { + // Parse key to GroupContractPosition + let key = key_str.parse::().map_err(|e| { + serde::de::Error::custom(format!("invalid group key '{}': {}", key_str, e)) + })?; + + // Extract the V0 variant manually + let group_obj = group_value.into_btree_string_map().map_err(|e| { + serde::de::Error::custom(format!("invalid group structure at '{}': {}", key_str, e)) + })?; + + let v0_payload = group_obj.get("V0").ok_or_else(|| { + serde::de::Error::custom(format!("missing 'V0' variant under group '{}'", key_str)) + })?; + + // Deserialize the GroupV0 struct and wrap in Group::V0 + let serde_value: serde_json::Value = v0_payload.clone().try_into().map_err(|e| { + serde::de::Error::custom(format!( + "failed to convert platform_value::Value to serde_json::Value at '{}': {}", + key_str, e + )) + })?; + let group_v0: GroupV0 = GroupV0::deserialize(&serde_value).map_err(|e| { + serde::de::Error::custom(format!( + "failed to deserialize GroupV0 at '{}': {}", + key_str, e + )) + })?; + + out.insert(key, Group::V0(group_v0)); + } - by_string - .into_iter() - .map(|(k, v)| { - k.parse::() - .map(|pos| (pos, v)) - .map_err(|e| serde::de::Error::custom(format!("invalid group key '{}': {}", k, e))) - }) - .collect() + Ok(out) } fn deserialize_u16_token_configuration_map<'de, D>( From cc277822f25c4425b7e4213430344d8e3c2fad36 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 21 May 2025 19:46:02 +0700 Subject: [PATCH 4/5] fix --- packages/rs-dpp/Cargo.toml | 2 +- .../data_contract/serialized_version/v1/mod.rs | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 10091afae51..4a22b6dd8cd 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -49,7 +49,7 @@ serde_repr = { version = "0.1.7" } sha2 = { version = "0.10" } thiserror = { version = "2.0.12" } data-contracts = { path = "../data-contracts", optional = true } -platform-value = { path = "../rs-platform-value" } +platform-value = { path = "../rs-platform-value", features = ["json"] } platform-version = { path = "../rs-platform-version" } platform-versioning = { path = "../rs-platform-versioning" } platform-serialization = { path = "../rs-platform-serialization" } diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 0ab4e14468e..393bc46f2cc 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -16,6 +16,7 @@ use crate::prelude::BlockHeight; use bincode::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; use std::collections::BTreeMap; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)] @@ -83,6 +84,7 @@ pub struct DataContractInSerializationFormatV1 { /// } /// } /// ``` +/// Deserialize `groups` map with stringified u16 keys and enum-wrapped `Group` values. fn deserialize_u16_group_map<'de, D>( deserializer: D, ) -> Result, D::Error> @@ -94,28 +96,23 @@ where let mut out = BTreeMap::new(); for (key_str, group_value) in map { - // Parse key to GroupContractPosition let key = key_str.parse::().map_err(|e| { serde::de::Error::custom(format!("invalid group key '{}': {}", key_str, e)) })?; - // Extract the V0 variant manually let group_obj = group_value.into_btree_string_map().map_err(|e| { serde::de::Error::custom(format!("invalid group structure at '{}': {}", key_str, e)) })?; - let v0_payload = group_obj.get("V0").ok_or_else(|| { + let v0_value = group_obj.get("V0").ok_or_else(|| { serde::de::Error::custom(format!("missing 'V0' variant under group '{}'", key_str)) })?; - // Deserialize the GroupV0 struct and wrap in Group::V0 - let serde_value: serde_json::Value = v0_payload.clone().try_into().map_err(|e| { - serde::de::Error::custom(format!( - "failed to convert platform_value::Value to serde_json::Value at '{}': {}", - key_str, e - )) + let v0_json: JsonValue = v0_value.clone().try_into_validating_json().map_err(|e| { + serde::de::Error::custom(format!("failed to convert to json at '{}': {}", key_str, e)) })?; - let group_v0: GroupV0 = GroupV0::deserialize(&serde_value).map_err(|e| { + + let group_v0: GroupV0 = serde_json::from_value(v0_json).map_err(|e| { serde::de::Error::custom(format!( "failed to deserialize GroupV0 at '{}': {}", key_str, e From 4fb26a80a4bbfde86484593273ea561c78ad0b17 Mon Sep 17 00:00:00 2001 From: pauldelucia Date: Wed, 21 May 2025 19:46:33 +0700 Subject: [PATCH 5/5] fix --- packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 393bc46f2cc..bc6fd6e5ca7 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -84,7 +84,6 @@ pub struct DataContractInSerializationFormatV1 { /// } /// } /// ``` -/// Deserialize `groups` map with stringified u16 keys and enum-wrapped `Group` values. fn deserialize_u16_group_map<'de, D>( deserializer: D, ) -> Result, D::Error>