river_core/room_state/
version.rs1use super::{ChatRoomParametersV1, ChatRoomStateV1};
9use freenet_scaffold::ComposableState;
10use serde::{Deserialize, Serialize};
11
12pub const CURRENT_STATE_VERSION: u32 = 1;
14
15#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
21pub struct StateVersion(pub u32);
22
23impl Default for StateVersion {
24 fn default() -> Self {
25 StateVersion(0)
28 }
29}
30
31impl ComposableState for StateVersion {
32 type ParentState = ChatRoomStateV1;
33 type Summary = u32;
34 type Delta = ();
35 type Parameters = ChatRoomParametersV1;
36
37 fn verify(
38 &self,
39 _parent_state: &Self::ParentState,
40 _parameters: &Self::Parameters,
41 ) -> Result<(), String> {
42 if self.0 > CURRENT_STATE_VERSION {
45 return Err(format!(
46 "Unknown state version {}. This contract supports versions 0-{}. \
47 Please upgrade your client.",
48 self.0, CURRENT_STATE_VERSION
49 ));
50 }
51 Ok(())
52 }
53
54 fn summarize(
55 &self,
56 _parent_state: &Self::ParentState,
57 _parameters: &Self::Parameters,
58 ) -> Self::Summary {
59 self.0
60 }
61
62 fn delta(
63 &self,
64 _parent_state: &Self::ParentState,
65 _parameters: &Self::Parameters,
66 _old_state_summary: &Self::Summary,
67 ) -> Option<Self::Delta> {
68 None
70 }
71
72 fn apply_delta(
73 &mut self,
74 _parent_state: &Self::ParentState,
75 _parameters: &Self::Parameters,
76 _delta: &Option<Self::Delta>,
77 ) -> Result<(), String> {
78 Ok(())
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use freenet_stdlib::prelude::serde_json;
88
89 #[test]
90 fn test_version_default_is_zero() {
91 let v = StateVersion::default();
92 assert_eq!(v.0, 0);
93 }
94
95 #[test]
96 fn test_version_verify_accepts_current() {
97 let v = StateVersion(CURRENT_STATE_VERSION);
98 let parent = ChatRoomStateV1::default();
99 let params = ChatRoomParametersV1 {
100 owner: ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng).verifying_key(),
101 };
102 assert!(v.verify(&parent, ¶ms).is_ok());
103 }
104
105 #[test]
106 fn test_version_verify_accepts_legacy() {
107 let v = StateVersion(0);
108 let parent = ChatRoomStateV1::default();
109 let params = ChatRoomParametersV1 {
110 owner: ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng).verifying_key(),
111 };
112 assert!(v.verify(&parent, ¶ms).is_ok());
113 }
114
115 #[test]
116 fn test_version_verify_rejects_future() {
117 let v = StateVersion(CURRENT_STATE_VERSION + 1);
118 let parent = ChatRoomStateV1::default();
119 let params = ChatRoomParametersV1 {
120 owner: ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng).verifying_key(),
121 };
122 assert!(v.verify(&parent, ¶ms).is_err());
123 }
124
125 #[test]
126 fn test_version_serialization_roundtrip() {
127 let v = StateVersion(CURRENT_STATE_VERSION);
129 let serialized = serde_json::to_string(&v).unwrap();
130 let deserialized: StateVersion = serde_json::from_str(&serialized).unwrap();
131 assert_eq!(v, deserialized);
132 }
133
134 #[test]
135 fn test_state_without_version_field_deserializes_with_default() {
136 use crate::room_state::configuration::{AuthorizedConfigurationV1, Configuration};
139
140 let owner_sk = ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng);
141 let owner_vk = owner_sk.verifying_key();
142
143 let mut state = ChatRoomStateV1::default();
145 let mut config = Configuration::default();
146 config.owner_member_id = owner_vk.into();
147 state.configuration = AuthorizedConfigurationV1::new(config, &owner_sk);
148
149 let mut json_value: serde_json::Value = serde_json::to_value(&state).unwrap();
151 if let serde_json::Value::Object(ref mut map) = json_value {
152 map.remove("version");
153 }
154 let legacy_json = serde_json::to_string(&json_value).unwrap();
155
156 let deserialized: ChatRoomStateV1 = serde_json::from_str(&legacy_json).unwrap();
158 assert_eq!(
159 deserialized.version.0, 0,
160 "Legacy state without version field should deserialize with version=0"
161 );
162 }
163
164 #[test]
165 fn test_state_with_version_field_roundtrips() {
166 use crate::room_state::configuration::{AuthorizedConfigurationV1, Configuration};
167
168 let owner_sk = ed25519_dalek::SigningKey::generate(&mut rand::rngs::OsRng);
169 let owner_vk = owner_sk.verifying_key();
170
171 let mut state = ChatRoomStateV1::default();
172 let mut config = Configuration::default();
173 config.owner_member_id = owner_vk.into();
174 state.configuration = AuthorizedConfigurationV1::new(config, &owner_sk);
175 state.version = StateVersion(CURRENT_STATE_VERSION);
176
177 let json = serde_json::to_string(&state).unwrap();
179 let deserialized: ChatRoomStateV1 = serde_json::from_str(&json).unwrap();
180
181 assert_eq!(deserialized.version.0, CURRENT_STATE_VERSION);
182 }
183}