Skip to content

Commit

Permalink
Always serialize BlobId as string if is_human_readable (#2681)
Browse files Browse the repository at this point in the history
## Motivation

#2668 was not necessarily the best way we can fix this issue.

## Proposal

Always serialize `BlobId` as string if `is_human_readable`. Fixes #2671

## Test Plan

Reverted #2668, made sure the `test_save_wallet_with_pending_blobs` test failed, and made sure it went back to passing with the new serialization implementation.

## Release Plan

- Nothing to do / These changes follow the usual release cycle.
  • Loading branch information
Andre da Silva authored Oct 23, 2024
1 parent 610985d commit 23a6f69
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 53 deletions.
57 changes: 41 additions & 16 deletions linera-base/src/identifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::{
use anyhow::{anyhow, Context};
use async_graphql::SimpleObject;
use linera_witty::{WitLoad, WitStore, WitType};
use serde::{Deserialize, Serialize};
use serde::{Deserialize, Deserializer, Serialize, Serializer};

use crate::{
bcs_scalar,
Expand Down Expand Up @@ -201,21 +201,7 @@ impl From<&BlobContent> for BlobType {
}

/// A content-addressed blob ID i.e. the hash of the `BlobContent`.
#[derive(
Eq,
PartialEq,
Ord,
PartialOrd,
Clone,
Copy,
Hash,
Debug,
Serialize,
Deserialize,
WitType,
WitStore,
WitLoad,
)]
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug, WitType, WitStore, WitLoad)]
#[cfg_attr(with_testing, derive(test_strategy::Arbitrary, Default))]
pub struct BlobId {
/// The hash of the blob.
Expand Down Expand Up @@ -263,6 +249,45 @@ impl FromStr for BlobId {
}
}

#[derive(Serialize, Deserialize)]
#[serde(rename = "BlobId")]
struct BlobIdHelper {
hash: CryptoHash,
blob_type: BlobType,
}

impl Serialize for BlobId {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(&self.to_string())
} else {
let helper = BlobIdHelper {
hash: self.hash,
blob_type: self.blob_type,
};
helper.serialize(serializer)
}
}
}

impl<'a> Deserialize<'a> for BlobId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'a>,
{
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
Self::from_str(&s).map_err(serde::de::Error::custom)
} else {
let helper = BlobIdHelper::deserialize(deserializer)?;
Ok(BlobId::new(helper.hash, helper.blob_type))
}
}
}

/// The index of a message in a chain.
#[derive(
Eq,
Expand Down
35 changes: 0 additions & 35 deletions linera-client/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,38 +66,3 @@ macro_rules! impl_from_infallible {

pub(crate) use impl_from_dynamic;
pub(crate) use impl_from_infallible;

pub mod serde_btreemap_keys_as_strings {
use std::{collections::BTreeMap, fmt::Display, str::FromStr};

use serde::{self, Deserialize, Deserializer, Serialize, Serializer};

pub fn serialize<K, V, S>(map: &BTreeMap<K, V>, serializer: S) -> Result<S::Ok, S::Error>
where
K: Display,
V: Serialize,
S: Serializer,
{
let string_map: BTreeMap<String, &V> =
map.iter().map(|(k, v)| (k.to_string(), v)).collect();
string_map.serialize(serializer)
}

pub fn deserialize<'de, K, V, D>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
where
K: FromStr + Ord,
<K as FromStr>::Err: Display,
V: Deserialize<'de>,
D: Deserializer<'de>,
{
let string_map: BTreeMap<String, V> = BTreeMap::deserialize(deserializer)?;
string_map
.into_iter()
.map(|(k, v)| {
k.parse()
.map(|key| (key, v))
.map_err(serde::de::Error::custom)
})
.collect()
}
}
3 changes: 1 addition & 2 deletions linera-client/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use linera_storage::Storage;
use rand::Rng as _;
use serde::{Deserialize, Serialize};

use crate::{config::GenesisConfig, error, util::serde_btreemap_keys_as_strings, Error};
use crate::{config::GenesisConfig, error, Error};

#[derive(Serialize, Deserialize)]
pub struct Wallet {
Expand Down Expand Up @@ -210,7 +210,6 @@ pub struct UserChain {
pub timestamp: Timestamp,
pub next_block_height: BlockHeight,
pub pending_block: Option<Block>,
#[serde(with = "serde_btreemap_keys_as_strings")]
pub pending_blobs: BTreeMap<BlobId, Blob>,
}

Expand Down

0 comments on commit 23a6f69

Please sign in to comment.