Skip to content

Commit a3fff4e

Browse files
committed
Add manual deser for Data
1 parent 36d9fd3 commit a3fff4e

File tree

7 files changed

+164
-65
lines changed

7 files changed

+164
-65
lines changed

notarization-move/Move.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ id = "MoveStdlib"
2222
source = { git = "https://github.com/iotaledger/iota.git", rev = "80fc853da5811f842be7bf749d6a981a17c9e565", subdir = "crates/iota-framework/packages/move-stdlib" }
2323

2424
[move.toolchain-version]
25-
compiler-version = "0.11.6-rc"
25+
compiler-version = "1.1.0"
2626
edition = "2024.beta"
2727
flavor = "iota"
2828

2929
[env]
3030

3131
[env.localnet]
32-
chain-id = "2263b3a8"
33-
original-published-id = "0xfe2e54aae674420034f157607af3a74aece5df37c600e25de4a9db9e1fc648ae"
34-
latest-published-id = "0xfe2e54aae674420034f157607af3a74aece5df37c600e25de4a9db9e1fc648ae"
32+
chain-id = "11d8ffd3"
33+
original-published-id = "0xe44dc179140a174935fd79f7ac946f796cdfe02e74461624e983a31eb9765f6c"
34+
latest-published-id = "0xe44dc179140a174935fd79f7ac946f796cdfe02e74461624e983a31eb9765f6c"
3535
published-version = "1"
3636

3737
[env.devnet]

notarization-rs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ phf.workspace = true
1919
product_common = { workspace = true, default-features = false, features = [
2020
"transaction",
2121
] }
22+
serde-value = "0.7.0"
2223
serde.workspace = true
2324
serde_json.workspace = true
2425
thiserror.workspace = true

notarization-rs/src/client/read_only.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,6 @@ impl NotarizationClientReadOnly {
419419
.await
420420
.map_err(|err| Error::UnexpectedApiResponse(format!("Failed to inspect transaction block: {err}")))?;
421421

422-
println!("inspection_result: {:?}", inspection_result);
423-
424422
let execution_results = inspection_result
425423
.results
426424
.ok_or_else(|| Error::UnexpectedApiResponse("DevInspectResults missing 'results' field".to_string()))?;

notarization-rs/src/core/notarization.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ use iota_interaction::IotaClientTrait;
3131
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
3232
pub struct OnChainNotarization {
3333
pub id: UID,
34-
// TODO: remove this field and use the state field instead
35-
pub state: State<String>,
34+
pub state: State,
3635
pub immutable_metadata: ImmutableMetadata,
3736
pub updateable_metadata: Option<String>,
3837
pub last_state_change_at: u64,
@@ -143,8 +142,6 @@ impl<M: Clone + OptionalSend + OptionalSync> Transaction for CreateNotarization<
143142
.first()
144143
.ok_or_else(|| Error::TransactionUnexpectedResponse("events should be provided".to_string()))?;
145144

146-
println!("data: {:?}", data);
147-
148145
let notarization_id = match method {
149146
NotarizationMethod::Dynamic => {
150147
let event: Event<DynamicNotarizationCreated> = serde_json::from_value(data.parsed_json.clone())

notarization-rs/src/core/state.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2020-2025 IOTA Stiftung
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use core::fmt;
45
use std::str::FromStr;
56

67
use async_trait::async_trait;
@@ -12,7 +13,7 @@ use iota_interaction::types::{TypeTag, MOVE_STDLIB_PACKAGE_ID};
1213
use iota_interaction::{ident_str, MoveType, OptionalSync};
1314
use product_common::core_client::CoreClientReadOnly;
1415
use product_common::transaction::transaction_builder::Transaction;
15-
use serde::{Deserialize, Serialize};
16+
use serde::{Deserialize, Deserializer, Serialize};
1617
use tokio::sync::OnceCell;
1718

1819
use super::move_utils;
@@ -28,12 +29,27 @@ pub struct State<T = Data> {
2829
pub metadata: Option<String>,
2930
}
3031

31-
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
32+
#[derive(Debug, Clone, Serialize, PartialEq)]
3233
pub enum Data {
3334
Bytes(Vec<u8>),
3435
Text(String),
3536
}
3637

38+
impl<'de> Deserialize<'de> for Data {
39+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
40+
where
41+
D: Deserializer<'de>,
42+
{
43+
let raw_bytes = Vec::<u8>::deserialize(deserializer)?;
44+
45+
if let Ok(text) = String::from_utf8(raw_bytes.clone()) {
46+
return Ok(Data::Text(text));
47+
}
48+
49+
Ok(Data::Bytes(raw_bytes))
50+
}
51+
}
52+
3753
impl Data {
3854
pub(crate) fn tag(&self) -> TypeTag {
3955
match self {
@@ -42,6 +58,20 @@ impl Data {
4258
.expect("should be valid type tag"),
4359
}
4460
}
61+
62+
pub fn as_bytes(self) -> Result<Vec<u8>, Error> {
63+
match self {
64+
Data::Bytes(data) => Ok(data),
65+
Data::Text(_) => Err(Error::GenericError("Data is not a vector".to_string())),
66+
}
67+
}
68+
69+
pub fn as_text(self) -> Result<String, Error> {
70+
match self {
71+
Data::Bytes(_) => Err(Error::GenericError("Data is not a string".to_string())),
72+
Data::Text(data) => Ok(data),
73+
}
74+
}
4575
}
4676

4777
impl State {

notarization-rs/tests/e2e/dynamic_notarization.rs

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use notarization::core::notarization::OnChainNotarization;
1313
use notarization::core::state::{Data, State};
1414
use notarization::core::timelock::TimeLock;
1515
use notarization::core::NotarizationMethod;
16+
use product_common::core_client::CoreClientReadOnly;
1617

1718
#[tokio::test]
1819
async fn create_simple_dynamic_notarization_works() -> anyhow::Result<()> {
@@ -27,8 +28,6 @@ async fn create_simple_dynamic_notarization_works() -> anyhow::Result<()> {
2728
.await?
2829
.output;
2930

30-
println!("onchain_notarization: {:?}", onchain_notarization);
31-
3231
assert_eq!(
3332
onchain_notarization.immutable_metadata.description,
3433
Some("Test Notarization".to_string())
@@ -145,7 +144,7 @@ async fn test_update_state_dynamic_notarization() -> anyhow::Result<()> {
145144
.id;
146145

147146
let new_state = State::from_string("updated_state".to_string(), Some("state_metadata".to_string()));
148-
147+
149148
let update_result = test_client
150149
.update_state(new_state.clone(), *notarization_id.object_id())
151150
.build_and_execute(&mut test_client)
@@ -154,7 +153,7 @@ async fn test_update_state_dynamic_notarization() -> anyhow::Result<()> {
154153
assert!(update_result.is_ok(), "State update should succeed");
155154

156155
let retrieved_state = test_client.state(*notarization_id.object_id()).await?;
157-
assert_eq!(retrieved_state.data.as_string()?, "updated_state");
156+
assert_eq!(retrieved_state.data.as_text()?, "updated_state");
158157
assert_eq!(retrieved_state.metadata, Some("state_metadata".to_string()));
159158

160159
let version_count = test_client.state_version_count(*notarization_id.object_id()).await?;
@@ -179,7 +178,7 @@ async fn test_update_metadata_dynamic_notarization() -> anyhow::Result<()> {
179178
.id;
180179

181180
let new_metadata = Some("updated_metadata".to_string());
182-
181+
183182
let update_result = test_client
184183
.update_metadata(new_metadata.clone(), *notarization_id.object_id())
185184
.build_and_execute(&mut test_client)
@@ -215,7 +214,10 @@ async fn test_destroy_dynamic_notarization_no_locks() -> anyhow::Result<()> {
215214
.build_and_execute(&mut test_client)
216215
.await;
217216

218-
assert!(destroy_result.is_ok(), "Destroy should succeed for unlocked notarization");
217+
assert!(
218+
destroy_result.is_ok(),
219+
"Destroy should succeed for unlocked notarization"
220+
);
219221

220222
Ok(())
221223
}
@@ -254,10 +256,13 @@ async fn test_read_only_methods_dynamic_notarization() -> anyhow::Result<()> {
254256

255257
let description = "Test Description".to_string();
256258
let updateable_metadata = "Test Metadata".to_string();
257-
259+
258260
let notarization_id = test_client
259261
.create_dynamic_notarization()
260-
.with_state(State::from_string("test_state".to_string(), Some("state_meta".to_string())))
262+
.with_state(State::from_string(
263+
"test_state".to_string(),
264+
Some("state_meta".to_string()),
265+
))
261266
.with_immutable_description(description.clone())
262267
.with_updateable_metadata(updateable_metadata.clone())
263268
.finish()
@@ -273,7 +278,7 @@ async fn test_read_only_methods_dynamic_notarization() -> anyhow::Result<()> {
273278
assert_eq!(retrieved_metadata, Some(updateable_metadata));
274279

275280
let state = test_client.state(*notarization_id.object_id()).await?;
276-
assert_eq!(state.data.as_string()?, "test_state");
281+
assert_eq!(state.data.as_text()?, "test_state");
277282
assert_eq!(state.metadata, Some("state_meta".to_string()));
278283

279284
let created_at = test_client.created_at_ts(*notarization_id.object_id()).await?;
@@ -317,14 +322,38 @@ async fn test_lock_checking_methods() -> anyhow::Result<()> {
317322
.output
318323
.id;
319324

320-
assert!(test_client.is_transfer_locked(*locked_notarization_id.object_id()).await?);
321-
assert!(!test_client.is_transfer_locked(*unlocked_notarization_id.object_id()).await?);
325+
assert!(
326+
test_client
327+
.is_transfer_locked(*locked_notarization_id.object_id())
328+
.await?
329+
);
330+
assert!(
331+
!test_client
332+
.is_transfer_locked(*unlocked_notarization_id.object_id())
333+
.await?
334+
);
322335

323-
assert!(!test_client.is_update_locked(*locked_notarization_id.object_id()).await?);
324-
assert!(!test_client.is_update_locked(*unlocked_notarization_id.object_id()).await?);
336+
assert!(
337+
!test_client
338+
.is_update_locked(*locked_notarization_id.object_id())
339+
.await?
340+
);
341+
assert!(
342+
!test_client
343+
.is_update_locked(*unlocked_notarization_id.object_id())
344+
.await?
345+
);
325346

326-
assert!(!test_client.is_destroy_locked(*locked_notarization_id.object_id()).await?);
327-
assert!(!test_client.is_destroy_locked(*unlocked_notarization_id.object_id()).await?);
347+
assert!(
348+
!test_client
349+
.is_destroy_locked(*locked_notarization_id.object_id())
350+
.await?
351+
);
352+
assert!(
353+
!test_client
354+
.is_destroy_locked(*unlocked_notarization_id.object_id())
355+
.await?
356+
);
328357

329358
let lock_metadata_locked = test_client.lock_metadata(*locked_notarization_id.object_id()).await?;
330359
assert!(lock_metadata_locked.is_some());
@@ -350,7 +379,7 @@ async fn test_multiple_state_updates() -> anyhow::Result<()> {
350379

351380
for i in 1..=3 {
352381
let new_state = State::from_string(format!("state_v{}", i), Some(format!("metadata_{}", i)));
353-
382+
354383
test_client
355384
.update_state(new_state, *notarization_id.object_id())
356385
.build_and_execute(&mut test_client)
@@ -360,7 +389,7 @@ async fn test_multiple_state_updates() -> anyhow::Result<()> {
360389
assert_eq!(version_count, i as u64);
361390

362391
let state = test_client.state(*notarization_id.object_id()).await?;
363-
assert_eq!(state.data.as_string()?, format!("state_v{}", i));
392+
assert_eq!(state.data.as_text()?, format!("state_v{}", i));
364393
assert_eq!(state.metadata, Some(format!("metadata_{}", i)));
365394
}
366395

@@ -386,7 +415,7 @@ async fn test_bytes_state_operations() -> anyhow::Result<()> {
386415

387416
let updated_data = vec![10, 20, 30];
388417
let new_state = State::from_bytes(updated_data.clone(), Some("bytes_metadata".to_string()));
389-
418+
390419
test_client
391420
.update_state(new_state, *notarization_id.object_id())
392421
.build_and_execute(&mut test_client)

0 commit comments

Comments
 (0)