Skip to content

Commit 7d60cb8

Browse files
authored
Merge branch 'main' into feat/proposal-form-template-test
2 parents 133efa2 + 6b093b0 commit 7d60cb8

File tree

12 files changed

+231
-98
lines changed

12 files changed

+231
-98
lines changed

rust/cardano-chain-follower/examples/follow_chains.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ async fn follow_for(
343343
|| (chain_update.immutable() != last_immutable)
344344
|| reached_tip
345345
|| follow_all
346-
|| (updates % RUNNING_UPDATE_INTERVAL == 0)
346+
|| updates.is_multiple_of(RUNNING_UPDATE_INTERVAL)
347347
|| (last_fork != chain_update.data.fork())
348348
{
349349
current_era = this_era;

rust/cardano-chain-follower/src/mithril_snapshot_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ fn remove_whitespace(s: &str) -> String {
495495

496496
/// Check if a string is an even number of hex digits.
497497
fn is_hex(s: &str) -> bool {
498-
s.chars().count() % 2 == 0 && s.chars().all(|c| c.is_ascii_hexdigit())
498+
s.chars().count().is_multiple_of(2) && s.chars().all(|c| c.is_ascii_hexdigit())
499499
}
500500

501501
#[cfg(test)]

rust/catalyst-types/src/catalyst_id/role_index.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ pub enum RoleIdError {
2828
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, EnumIs)]
2929
#[repr(u8)]
3030
#[non_exhaustive]
31+
#[derive(Default)]
3132
pub enum RoleId {
3233
/// Primary required role use for voting and commenting.
34+
#[default]
3335
Role0 = 0,
3436
/// Delegated representative (dRep) that vote on behalf of delegators.
3537
DelegatedRepresentative = 1,
@@ -85,12 +87,6 @@ impl RoleId {
8587
}
8688
}
8789

88-
impl Default for RoleId {
89-
fn default() -> Self {
90-
Self::Role0
91-
}
92-
}
93-
9490
impl From<u8> for RoleId {
9591
fn from(value: u8) -> Self {
9692
match value {

rust/hermes-ipfs/examples/pubsub.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ async fn main() -> anyhow::Result<()> {
6666
let mut event_stream = hermes_a.pubsub_events(option_topic.clone()).await?;
6767
let mut event_stream_b = hermes_b.pubsub_events(option_topic).await?;
6868

69-
let stream = hermes_a.pubsub_subscribe(topic.to_string()).await?;
70-
let stream_b = hermes_b.pubsub_subscribe(topic.to_string()).await?;
69+
let stream = hermes_a.pubsub_subscribe(topic.clone()).await?;
70+
let stream_b = hermes_b.pubsub_subscribe(topic.clone()).await?;
7171

7272
pin_mut!(stream);
7373
pin_mut!(stream_b);

rust/signed_doc/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ use cbork_utils::{array::Array, decode_context::DecodeCtx, with_cbor_bytes::With
2424
pub use content::Content;
2525
use decode_context::{CompatibilityPolicy, DecodeContext};
2626
pub use metadata::{
27-
ContentEncoding, ContentType, DocLocator, DocType, DocumentRef, DocumentRefs, Metadata, Section,
27+
Chain, ContentEncoding, ContentType, DocLocator, DocType, DocumentRef, DocumentRefs, Metadata,
28+
Section,
2829
};
2930
use minicbor::{decode, encode, Decode, Decoder, Encode};
3031
pub use signature::{CatalystId, Signatures};
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
//! Document Payload Chain.
2+
//!
3+
//! ref: <https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/metadata/#chain-link>
4+
5+
use std::{fmt::Display, hash::Hash};
6+
7+
use cbork_utils::{array::Array, decode_context::DecodeCtx};
8+
9+
use crate::DocumentRef;
10+
11+
/// Reference to the previous Signed Document in a sequence.
12+
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
13+
pub struct Chain {
14+
/// The consecutive sequence number of the current document
15+
/// in the chain.
16+
/// The very first document in a sequence is numbered `0` and it
17+
/// *MUST ONLY* increment by one for each successive document in
18+
/// the sequence.
19+
///
20+
/// The FINAL sequence number is encoded with the current height
21+
/// sequence value, negated.
22+
///
23+
/// For example the following values for height define a chain
24+
/// that has 5 documents in the sequence 0-4, the final height
25+
/// is negated to indicate the end of the chain:
26+
/// `0, 1, 2, 3, -4`
27+
///
28+
/// No subsequent document can be chained to a sequence that has
29+
/// a final chain height.
30+
height: i32,
31+
/// Reference to a single Signed Document.
32+
///
33+
/// Can be *ONLY* omitted in the very first document in a sequence.
34+
document_ref: Option<DocumentRef>,
35+
}
36+
37+
impl Display for Chain {
38+
fn fmt(
39+
&self,
40+
f: &mut std::fmt::Formatter<'_>,
41+
) -> std::fmt::Result {
42+
if let Some(document_ref) = &self.document_ref {
43+
write!(f, "height: {}, document_ref: {}", self.height, document_ref)
44+
} else {
45+
write!(f, "height: {}", self.height)
46+
}
47+
}
48+
}
49+
50+
impl minicbor::Encode<()> for Chain {
51+
fn encode<W: minicbor::encode::Write>(
52+
&self,
53+
e: &mut minicbor::Encoder<W>,
54+
_ctx: &mut (),
55+
) -> Result<(), minicbor::encode::Error<W::Error>> {
56+
e.array(if self.document_ref.is_some() { 2 } else { 1 })?;
57+
self.height.encode(e, &mut ())?;
58+
if let Some(doc_ref) = &self.document_ref {
59+
doc_ref.encode(e, &mut ())?;
60+
}
61+
Ok(())
62+
}
63+
}
64+
65+
impl minicbor::Decode<'_, ()> for Chain {
66+
fn decode(
67+
d: &mut minicbor::Decoder<'_>,
68+
_ctx: &mut (),
69+
) -> Result<Self, minicbor::decode::Error> {
70+
const CONTEXT: &str = "Chain decoding";
71+
72+
let arr = Array::decode(d, &mut DecodeCtx::Deterministic)?;
73+
74+
let Some(height_bytes) = arr.first() else {
75+
return Err(minicbor::decode::Error::message(format!(
76+
"{CONTEXT}: expected [height, ? document_ref], found empty array"
77+
)));
78+
};
79+
80+
let height = minicbor::Decoder::new(height_bytes).int()?;
81+
let height = height.try_into().map_err(minicbor::decode::Error::custom)?;
82+
83+
let document_ref = arr
84+
.get(1)
85+
.map(|bytes| {
86+
let mut d = minicbor::Decoder::new(bytes);
87+
DocumentRef::decode(&mut d, &mut ())
88+
})
89+
.transpose()?;
90+
91+
Ok(Self {
92+
height,
93+
document_ref,
94+
})
95+
}
96+
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use catalyst_types::uuid::UuidV7;
101+
use minicbor::{Decode, Decoder, Encode, Encoder};
102+
103+
use super::*;
104+
use crate::DocLocator;
105+
106+
#[test]
107+
fn test_chain_encode_decode_without_doc_ref() {
108+
let chain = Chain {
109+
height: 0,
110+
document_ref: None,
111+
};
112+
113+
let mut buf = Vec::new();
114+
let mut enc = Encoder::new(&mut buf);
115+
chain.encode(&mut enc, &mut ()).unwrap();
116+
117+
let mut dec = Decoder::new(&buf);
118+
let decoded = Chain::decode(&mut dec, &mut ()).unwrap();
119+
120+
assert_eq!(decoded, chain);
121+
}
122+
123+
#[test]
124+
fn test_chain_encode_decode_with_doc_ref() {
125+
let id = UuidV7::new();
126+
let ver = UuidV7::new();
127+
128+
let chain = Chain {
129+
height: 3,
130+
document_ref: Some(DocumentRef::new(id, ver, DocLocator::default())),
131+
};
132+
133+
let mut buf = Vec::new();
134+
let mut enc = Encoder::new(&mut buf);
135+
chain.encode(&mut enc, &mut ()).unwrap();
136+
137+
let mut dec = Decoder::new(&buf);
138+
let decoded = Chain::decode(&mut dec, &mut ()).unwrap();
139+
140+
assert_eq!(decoded, chain);
141+
}
142+
}

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

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
//! A [CBOR Encoded IPLD Content Identifier](https://github.com/ipld/cid-cbor/)
33
//! or also known as [IPFS CID](https://docs.ipfs.tech/concepts/content-addressing/#what-is-a-cid).
44
5-
use std::fmt::Display;
5+
use std::{fmt::Display, ops::Deref, str::FromStr};
66

77
use cbork_utils::{decode_context::DecodeCtx, map::Map};
88
use minicbor::{Decode, Decoder, Encode};
99

10+
use crate::metadata::document_refs::DocRefError;
11+
1012
/// CBOR tag of IPLD content identifiers (CIDs).
1113
const CID_TAG: u64 = 42;
1214

@@ -20,23 +22,17 @@ const DOC_LOC_MAP_ITEM: u64 = 1;
2022
#[derive(Clone, Debug, Default, PartialEq, Hash, Eq)]
2123
pub struct DocLocator(Vec<u8>);
2224

23-
impl DocLocator {
24-
#[must_use]
25-
/// Length of the document locator.
26-
pub fn len(&self) -> usize {
27-
self.0.len()
28-
}
25+
impl Deref for DocLocator {
26+
type Target = Vec<u8>;
2927

30-
#[must_use]
31-
/// Is the document locator empty.
32-
pub fn is_empty(&self) -> bool {
33-
self.0.is_empty()
28+
fn deref(&self) -> &Self::Target {
29+
&self.0
3430
}
3531
}
3632

3733
impl From<Vec<u8>> for DocLocator {
3834
fn from(value: Vec<u8>) -> Self {
39-
DocLocator(value)
35+
Self(value)
4036
}
4137
}
4238

@@ -49,6 +45,38 @@ impl Display for DocLocator {
4945
}
5046
}
5147

48+
impl FromStr for DocLocator {
49+
type Err = DocRefError;
50+
51+
fn from_str(s: &str) -> Result<Self, Self::Err> {
52+
s.strip_prefix("0x")
53+
.map(hex::decode)
54+
.ok_or(DocRefError::HexDecode("missing 0x prefix".to_string()))?
55+
.map(Self)
56+
.map_err(|e| DocRefError::HexDecode(e.to_string()))
57+
}
58+
}
59+
60+
impl<'de> serde::Deserialize<'de> for DocLocator {
61+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
62+
where D: serde::Deserializer<'de> {
63+
let s = String::deserialize(deserializer)?;
64+
s.parse::<DocLocator>().map_err(serde::de::Error::custom)
65+
}
66+
}
67+
68+
impl serde::Serialize for DocLocator {
69+
fn serialize<S>(
70+
&self,
71+
serializer: S,
72+
) -> Result<S::Ok, S::Error>
73+
where
74+
S: serde::Serializer,
75+
{
76+
serializer.serialize_str(&self.to_string())
77+
}
78+
}
79+
5280
// document_locator = { "cid" => cid }
5381
impl Decode<'_, ()> for DocLocator {
5482
fn decode(

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ use super::doc_locator::DocLocator;
1212
const DOC_REF_ARR_ITEM: u64 = 3;
1313

1414
/// Reference to a Document.
15-
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
15+
#[derive(Clone, Debug, PartialEq, Hash, Eq, serde::Serialize, serde::Deserialize)]
1616
pub struct DocumentRef {
1717
/// Reference to the Document Id
1818
id: UuidV7,
1919
/// Reference to the Document Ver
2020
ver: UuidV7,
2121
/// Document locator
22+
#[serde(rename = "cid", default)]
2223
doc_locator: DocLocator,
2324
}
2425

0 commit comments

Comments
 (0)