1use crate::{error::Result, Error, Permissions, RegisterAddress, RegisterOp};
10#[cfg(feature = "test-utils")]
11use bls::SecretKey;
12use bls::{PublicKey, Signature};
13use serde::{Deserialize, Serialize};
14use std::collections::BTreeSet;
15use xor_name::XorName;
16
17const MAX_REG_ENTRY_SIZE: usize = 1024;
19
20const MAX_REG_NUM_ENTRIES: u16 = 1024;
22
23#[derive(Clone, Eq, PartialEq, PartialOrd, Hash, Serialize, Deserialize, Debug)]
25pub struct Register {
26 address: RegisterAddress,
28 permissions: Permissions,
32}
33
34#[derive(Clone, Debug, Serialize, Deserialize, PartialOrd, PartialEq, Eq, Hash)]
37pub struct SignedRegister {
38 register: Register,
40 signature: Signature,
42 ops: BTreeSet<RegisterOp>,
45}
46
47impl SignedRegister {
48 pub fn new(register: Register, signature: Signature, ops: BTreeSet<RegisterOp>) -> Self {
50 Self {
51 register,
52 signature,
53 ops,
54 }
55 }
56
57 pub fn base_register(&self) -> &Register {
59 &self.register
60 }
61
62 pub fn verify(&self) -> Result<()> {
64 let reg_size = self.ops.len();
65 if reg_size >= MAX_REG_NUM_ENTRIES as usize {
66 return Err(Error::TooManyEntries(reg_size));
67 }
68
69 let bytes = self.register.bytes()?;
70 if !self
71 .register
72 .owner()
73 .verify(&self.signature, bytes.as_slice())
74 {
75 return Err(Error::InvalidSignature);
76 }
77
78 for op in &self.ops {
79 self.register.check_register_op(op)?;
80 let size = op.crdt_op.value.len();
81 if size > MAX_REG_ENTRY_SIZE {
82 return Err(Error::EntryTooBig {
83 size,
84 max: MAX_REG_ENTRY_SIZE,
85 });
86 }
87 }
88 Ok(())
89 }
90
91 pub fn verify_with_address(&self, address: RegisterAddress) -> Result<()> {
92 if self.register.address() != &address {
93 return Err(Error::InvalidRegisterAddress {
94 requested: Box::new(address),
95 got: Box::new(*self.address()),
96 });
97 }
98 self.verify()
99 }
100
101 pub fn merge(&mut self, other: &Self) -> Result<()> {
103 self.register.verify_is_mergeable(&other.register)?;
104 self.ops.extend(other.ops.clone());
105 Ok(())
106 }
107
108 pub fn verified_merge(&mut self, other: &Self) -> Result<()> {
111 self.register.verify_is_mergeable(&other.register)?;
112 other.verify()?;
113 self.ops.extend(other.ops.clone());
114 Ok(())
115 }
116
117 pub fn address(&self) -> &RegisterAddress {
119 self.register.address()
120 }
121
122 pub fn owner(&self) -> PublicKey {
124 self.register.owner()
125 }
126
127 pub fn add_op(&mut self, op: RegisterOp) -> Result<()> {
129 let reg_size = self.ops.len();
130 if reg_size >= MAX_REG_NUM_ENTRIES as usize {
131 return Err(Error::TooManyEntries(reg_size));
132 }
133
134 let size = op.crdt_op.value.len();
135 if size > MAX_REG_ENTRY_SIZE {
136 return Err(Error::EntryTooBig {
137 size,
138 max: MAX_REG_ENTRY_SIZE,
139 });
140 }
141
142 self.register.check_register_op(&op)?;
143 self.ops.insert(op);
144 Ok(())
145 }
146
147 pub fn ops(&self) -> &BTreeSet<RegisterOp> {
149 &self.ops
150 }
151
152 #[cfg(feature = "test-utils")]
154 pub fn test_new_from_address(address: RegisterAddress, owner: &SecretKey) -> Self {
155 let base_register = Register {
156 address,
157 permissions: Permissions::AnyoneCanWrite,
158 };
159 let bytes = if let Ok(bytes) = base_register.bytes() {
160 bytes
161 } else {
162 panic!("Failed to serialize register {base_register:?}");
163 };
164 let signature = owner.sign(bytes);
165 Self::new(base_register, signature, BTreeSet::new())
166 }
167}
168
169impl Register {
170 pub fn new(owner: PublicKey, meta: XorName, mut permissions: Permissions) -> Self {
172 permissions.add_writer(owner);
173 Self {
174 address: RegisterAddress { meta, owner },
175 permissions,
176 }
177 }
178
179 pub fn bytes(&self) -> Result<Vec<u8>> {
182 rmp_serde::to_vec(self).map_err(|_| Error::SerialisationFailed)
183 }
184
185 pub fn address(&self) -> &RegisterAddress {
187 &self.address
188 }
189
190 pub fn owner(&self) -> PublicKey {
192 self.address.owner()
193 }
194
195 pub fn permissions(&self) -> &Permissions {
197 &self.permissions
198 }
199
200 pub fn check_register_op(&self, op: &RegisterOp) -> Result<()> {
202 if self.permissions.can_anyone_write() {
203 return Ok(()); }
205 self.check_user_permissions(op.source)?;
206 op.verify_signature(&op.source)
207 }
208
209 pub fn check_user_permissions(&self, requester: PublicKey) -> Result<()> {
215 if self.permissions.can_write(&requester) {
216 Ok(())
217 } else {
218 Err(Error::AccessDenied(requester))
219 }
220 }
221
222 fn verify_is_mergeable(&self, other: &Self) -> Result<()> {
224 if self.address() != other.address() || self.permissions != other.permissions {
225 return Err(Error::DifferentBaseRegister);
226 }
227 Ok(())
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use crate::{RegisterCrdt, RegisterOp};
234
235 use super::*;
236
237 use bls::SecretKey;
238 use rand::{thread_rng, Rng};
239 use std::collections::BTreeSet;
240 use xor_name::XorName;
241
242 #[test]
243 fn register_create() {
244 let meta = xor_name::rand::random();
245 let (authority_sk, register) = &gen_reg_replicas(None, meta, None, 1)[0];
246
247 let authority = authority_sk.public_key();
248 assert_eq!(register.owner(), authority);
249 assert_eq!(register.owner(), authority);
250
251 let address = RegisterAddress::new(meta, authority);
252 assert_eq!(*register.address(), address);
253 }
254
255 #[test]
256 fn register_permissions() -> eyre::Result<()> {
257 let owner_sk = SecretKey::random();
258 let owner = owner_sk.public_key();
259 let user_sk_1 = SecretKey::random();
260 let other_user = user_sk_1.public_key();
261 let user_sk_2 = SecretKey::random();
262
263 let meta: XorName = xor_name::rand::random();
264 let address = RegisterAddress { meta, owner };
265
266 let mut signed_reg_1 = create_reg_replica_with(
268 meta,
269 Some(owner_sk.clone()),
270 Some(Permissions::new_anyone_can_write()),
271 );
272 let op = generate_random_op(address, &owner_sk)?;
274 assert!(signed_reg_1.add_op(op).is_ok());
275 let op = generate_random_op(address, &user_sk_1)?;
276 assert!(signed_reg_1.add_op(op).is_ok());
277 let op = generate_random_op(address, &user_sk_2)?;
278 assert!(signed_reg_1.add_op(op).is_ok());
279
280 let mut signed_reg_2 = create_reg_replica_with(
282 meta,
283 Some(owner_sk.clone()),
284 Some(Permissions::new_with([other_user])),
285 );
286 let op = generate_random_op(address, &owner_sk)?;
288 assert!(signed_reg_2.add_op(op).is_ok());
289 let op = generate_random_op(address, &user_sk_1)?;
290 assert!(signed_reg_2.add_op(op).is_ok());
291 let op = generate_random_op(address, &user_sk_2)?;
292 assert!(signed_reg_2.add_op(op).is_err());
293
294 let mut signed_reg_3 = create_reg_replica_with(meta, Some(owner_sk.clone()), None);
296 let op = generate_random_op(address, &owner_sk)?;
298 assert!(signed_reg_3.add_op(op).is_ok());
299 let op = generate_random_op(address, &user_sk_1)?;
301 let res = signed_reg_3.add_op(op);
302 assert!(
303 matches!(&res, Err(err) if err == &Error::AccessDenied(other_user)),
304 "Unexpected result: {res:?}"
305 );
306
307 let res1 = signed_reg_1.merge(&signed_reg_2);
309 let res2 = signed_reg_2.merge(&signed_reg_1);
310 assert!(
311 matches!(&res1, Err(err) if err == &Error::DifferentBaseRegister),
312 "Unexpected result: {res1:?}"
313 );
314 assert_eq!(res1, res2);
315
316 Ok(())
317 }
318
319 #[test]
320 fn register_query_public_perms() -> eyre::Result<()> {
321 let meta = xor_name::rand::random();
322
323 let authority_sk1 = SecretKey::random();
325 let authority_pk1 = authority_sk1.public_key();
326 let owner1 = authority_pk1;
327 let perms1 = Permissions::new_anyone_can_write();
328 let replica1 = create_reg_replica_with(meta, Some(authority_sk1), Some(perms1));
329
330 let authority_sk2 = SecretKey::random();
332 let authority_pk2 = authority_sk2.public_key();
333 let owner2 = authority_pk2;
334 let perms2 = Permissions::new_with([owner1]);
335 let replica2 = create_reg_replica_with(meta, Some(authority_sk2), Some(perms2));
336
337 let sk_rand = SecretKey::random();
339 let random_user = sk_rand.public_key();
340 let sk_rand2 = SecretKey::random();
341 let random_user2 = sk_rand2.public_key();
342
343 assert_eq!(replica1.owner(), authority_pk1);
345 assert_eq!(replica1.register.check_user_permissions(owner1), Ok(()));
346 assert_eq!(replica1.register.check_user_permissions(owner2), Ok(()));
347 assert_eq!(
348 replica1.register.check_user_permissions(random_user),
349 Ok(())
350 );
351 assert_eq!(
352 replica1.register.check_user_permissions(random_user2),
353 Ok(())
354 );
355
356 assert_eq!(replica2.owner(), authority_pk2);
358 assert_eq!(replica2.register.check_user_permissions(owner1), Ok(()));
359 assert_eq!(replica2.register.check_user_permissions(owner2), Ok(()));
360 assert_eq!(
361 replica2.register.check_user_permissions(random_user),
362 Err(Error::AccessDenied(random_user))
363 );
364 assert_eq!(
365 replica2.register.check_user_permissions(random_user2),
366 Err(Error::AccessDenied(random_user2))
367 );
368
369 Ok(())
370 }
371
372 #[test]
373 fn exceeding_max_reg_entries_errors() -> eyre::Result<()> {
374 let meta = xor_name::rand::random();
375
376 let authority_sk1 = SecretKey::random();
378 let owner = authority_sk1.public_key();
379 let perms1 = Permissions::new_anyone_can_write();
380 let address = RegisterAddress { meta, owner };
381
382 let mut replica = create_reg_replica_with(meta, Some(authority_sk1.clone()), Some(perms1));
383
384 for _ in 0..MAX_REG_NUM_ENTRIES {
385 let op = generate_random_op(address, &authority_sk1)?;
386 assert!(replica.add_op(op).is_ok());
387 }
388
389 let op = generate_random_op(address, &authority_sk1)?;
390
391 let excess_entry = replica.add_op(op);
392
393 match excess_entry {
394 Err(Error::TooManyEntries(size)) => {
395 assert_eq!(size, 1024);
396 Ok(())
397 }
398 anything_else => {
399 eyre::bail!(
400 "Expected Excess entries error was not found. Instead: {anything_else:?}"
401 )
402 }
403 }
404 }
405
406 fn gen_reg_replicas(
408 authority_sk: Option<SecretKey>,
409 meta: XorName,
410 perms: Option<Permissions>,
411 count: usize,
412 ) -> Vec<(SecretKey, SignedRegister)> {
413 let replicas: Vec<(SecretKey, SignedRegister)> = (0..count)
414 .map(|_| {
415 let authority_sk = authority_sk.clone().unwrap_or_else(SecretKey::random);
416 let authority = authority_sk.public_key();
417 let perms = perms.clone().unwrap_or_default();
418 let register = Register::new(authority, meta, perms);
419
420 let signature = authority_sk.sign(register.bytes().unwrap());
421 let signed_reg = SignedRegister::new(register, signature, Default::default());
422
423 (authority_sk, signed_reg)
424 })
425 .collect();
426
427 assert_eq!(replicas.len(), count);
428 replicas
429 }
430
431 fn create_reg_replica_with(
432 meta: XorName,
433 authority_sk: Option<SecretKey>,
434 perms: Option<Permissions>,
435 ) -> SignedRegister {
436 let replicas = gen_reg_replicas(authority_sk, meta, perms, 1);
437 replicas[0].1.clone()
438 }
439
440 fn random_register_entry() -> Vec<u8> {
441 let random_bytes = thread_rng().gen::<[u8; 32]>();
442 random_bytes.to_vec()
443 }
444
445 fn generate_random_op(address: RegisterAddress, writer_sk: &SecretKey) -> Result<RegisterOp> {
446 let mut crdt_reg = RegisterCrdt::new(address);
447 let item = random_register_entry();
448 let (_hash, addr, crdt_op) = crdt_reg.write(item, &BTreeSet::new())?;
449 Ok(RegisterOp::new(addr, crdt_op, writer_sk))
450 }
451}