Skip to content

Commit 8afb686

Browse files
apskhemMr-Leshiy
andauthored
feat(rust/signed-doc): Apply deterministic array decoding to Collaborators and DocumentRefs (#665)
* feat: initial * chore: set back version * test: collaborators * fix: cspell * fix: cspell * fix: cspell --------- Co-authored-by: Alex Pozhylenkov <[email protected]>
1 parent 31eebf6 commit 8afb686

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

rust/signed_doc/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ workspace = true
1212

1313
[dependencies]
1414
catalyst-types = { version = "0.0.11", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "catalyst-types/v0.0.11" }
15-
cbork-utils = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils-v0.0.2" }
15+
cbork-utils = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils/v0.0.3" }
1616

1717
# When updating the specification version, it should also be updated for the `catalyst-signed-doc-macro` crate.
1818
catalyst-signed-doc-macro = { version = "0.0.1", path = "../catalyst-signed-doc-macro" }

rust/signed_doc/src/metadata/collaborators.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl minicbor::Decode<'_, ()> for Collaborators {
4747
d: &mut minicbor::Decoder<'_>,
4848
_ctx: &mut (),
4949
) -> Result<Self, minicbor::decode::Error> {
50-
Array::decode(d, &mut DecodeCtx::Deterministic)
50+
Array::decode(d, &mut DecodeCtx::ArrayDeterministic)
5151
.and_then(|arr| {
5252
if arr.is_empty() {
5353
Err(minicbor::decode::Error::message(
@@ -117,7 +117,7 @@ impl serde::Serialize for Collaborators {
117117

118118
#[cfg(test)]
119119
mod tests {
120-
use minicbor::{Decode, Decoder, Encoder};
120+
use minicbor::{Decode, Decoder, Encode, Encoder};
121121
use test_case::test_case;
122122

123123
use super::*;
@@ -152,4 +152,46 @@ mod tests {
152152
Collaborators::decode(&mut Decoder::new(e.into_writer().as_slice()), &mut ()).is_err()
153153
);
154154
}
155+
156+
#[test]
157+
fn test_deterministic_decoding() {
158+
/* cspell:disable */
159+
let mut cat_ids = vec![
160+
CatalystId::from_str(
161+
"id.catalyst://preprod.cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE/7/3",
162+
)
163+
.unwrap(),
164+
CatalystId::from_str(
165+
"id.catalyst://midnight/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE/0/1",
166+
)
167+
.unwrap(),
168+
];
169+
/* cspell:enable */
170+
cat_ids.sort_by(|a, b| {
171+
let a = a.to_string();
172+
let b = b.to_string();
173+
let a_bytes = a.as_bytes();
174+
let b_bytes = b.as_bytes();
175+
176+
match a_bytes.len().cmp(&b_bytes.len()) {
177+
std::cmp::Ordering::Equal => a_bytes.cmp(b_bytes),
178+
other => other,
179+
}
180+
});
181+
182+
let collaborators = Collaborators::from(cat_ids.clone());
183+
let mut e = Encoder::new(Vec::new());
184+
collaborators.encode(&mut e, &mut ()).unwrap();
185+
186+
let result = Collaborators::decode(&mut Decoder::new(e.into_writer().as_slice()), &mut ());
187+
assert!(result.is_ok());
188+
189+
let mut e = Encoder::new(Vec::new());
190+
cat_ids.reverse();
191+
let collaborators = Collaborators::from(cat_ids.clone());
192+
collaborators.encode(&mut e, &mut ()).unwrap();
193+
194+
let result = Collaborators::decode(&mut Decoder::new(e.into_writer().as_slice()), &mut ());
195+
assert!(result.is_err());
196+
}
155197
}

rust/signed_doc/src/metadata/document_refs/mod.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ impl Decode<'_, CompatibilityPolicy> for DocumentRefs {
8686

8787
// Old: [id, ver]
8888
// New: [ 1* [id, ver, locator] ]
89-
let outer_arr = Array::decode(d, &mut DecodeCtx::Deterministic)
89+
let outer_arr = Array::decode(d, &mut DecodeCtx::ArrayDeterministic)
9090
.map_err(|e| minicbor::decode::Error::message(format!("{CONTEXT}: {e}")))?;
9191

9292
match outer_arr.as_slice() {
@@ -355,4 +355,45 @@ pub(crate) mod tests {
355355

356356
assert_eq!(refs, refs_from_json);
357357
}
358+
359+
#[test]
360+
fn test_deterministic_decoding() {
361+
let mut refs = vec![create_dummy_doc_ref(), create_dummy_doc_ref()];
362+
refs.sort_by(|a, b| {
363+
let a_bytes = {
364+
let mut e = Encoder::new(Vec::new());
365+
a.encode(&mut e, &mut ()).unwrap();
366+
e.into_writer()
367+
};
368+
let b_bytes = {
369+
let mut e = Encoder::new(Vec::new());
370+
b.encode(&mut e, &mut ()).unwrap();
371+
e.into_writer()
372+
};
373+
374+
match a_bytes.len().cmp(&b_bytes.len()) {
375+
std::cmp::Ordering::Equal => a_bytes.as_slice().cmp(&b_bytes),
376+
other => other,
377+
}
378+
});
379+
380+
let mut e = Encoder::new(Vec::new());
381+
refs.encode(&mut e, &mut ()).unwrap();
382+
383+
let result = DocumentRefs::decode(
384+
&mut Decoder::new(e.into_writer().as_slice()),
385+
&mut CompatibilityPolicy::Fail,
386+
);
387+
assert!(result.is_ok());
388+
389+
let mut e = Encoder::new(Vec::new());
390+
refs.reverse();
391+
refs.encode(&mut e, &mut ()).unwrap();
392+
393+
let result = DocumentRefs::decode(
394+
&mut Decoder::new(e.into_writer().as_slice()),
395+
&mut CompatibilityPolicy::Fail,
396+
);
397+
assert!(result.is_err());
398+
}
358399
}

0 commit comments

Comments
 (0)