1mod metadata;
11mod seq_crdt;
12
13use crate::{Error, PublicKey, Result};
14pub use metadata::{
15 Action, Address, Entries, Entry, Index, Kind, Perm, Permissions, Policy, PrivatePermissions,
16 PrivatePolicy, PublicPermissions, PublicPolicy, User,
17};
18use seq_crdt::{CrdtOperation, SequenceCrdt};
19use serde::{Deserialize, Serialize};
20use std::collections::BTreeMap;
21use std::{fmt::Debug, hash::Hash};
22use xor_name::XorName;
23
24type ActorType = String;
26
27pub type DataOp<T> = CrdtOperation<ActorType, T>;
29
30pub type PublicSeqData = SequenceCrdt<ActorType, PublicPolicy>;
32pub type PrivateSeqData = SequenceCrdt<ActorType, PrivatePolicy>;
34
35#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)]
37enum SeqData {
38 Public(PublicSeqData),
40 Private(PrivateSeqData),
42}
43
44#[derive(Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Debug)]
46pub struct Data {
47 authority: PublicKey,
48 data: SeqData,
49}
50
51#[allow(clippy::len_without_is_empty)]
52impl Data {
53 pub fn new_public(
60 authority: PublicKey,
61 actor: ActorType,
62 name: XorName,
63 tag: u64,
64 policy: Option<PublicPolicy>,
65 ) -> Self {
66 let policy = policy.unwrap_or(PublicPolicy {
67 owner: authority,
68 permissions: BTreeMap::new(),
69 });
70
71 Self {
72 authority,
73 data: SeqData::Public(PublicSeqData::new(
74 actor,
75 Address::Public { name, tag },
76 policy,
77 )),
78 }
79 }
80
81 pub fn new_private(
88 authority: PublicKey,
89 actor: ActorType,
90 name: XorName,
91 tag: u64,
92 policy: Option<PrivatePolicy>,
93 ) -> Self {
94 let policy = policy.unwrap_or(PrivatePolicy {
95 owner: authority,
96 permissions: BTreeMap::new(),
97 });
98
99 Self {
100 authority,
101 data: SeqData::Private(PrivateSeqData::new(
102 actor,
103 Address::Private { name, tag },
104 policy,
105 )),
106 }
107 }
108
109 pub fn address(&self) -> &Address {
111 match &self.data {
112 SeqData::Public(data) => data.address(),
113 SeqData::Private(data) => data.address(),
114 }
115 }
116
117 pub fn kind(&self) -> Kind {
119 self.address().kind()
120 }
121
122 pub fn name(&self) -> &XorName {
124 self.address().name()
125 }
126
127 pub fn tag(&self) -> u64 {
129 self.address().tag()
130 }
131
132 pub fn is_public(&self) -> bool {
134 self.kind().is_public()
135 }
136
137 pub fn is_private(&self) -> bool {
139 self.kind().is_private()
140 }
141
142 pub fn len(&self, requester: Option<PublicKey>) -> Result<u64> {
145 self.check_permission(Action::Read, requester)?;
146
147 Ok(match &self.data {
148 SeqData::Public(data) => data.len(),
149 SeqData::Private(data) => data.len(),
150 })
151 }
152
153 pub fn is_empty(&self, requester: Option<PublicKey>) -> Result<bool> {
155 self.check_permission(Action::Read, requester)?;
156
157 Ok(self.len(None)? == 0)
158 }
159
160 pub fn in_range(
163 &self,
164 start: Index,
165 end: Index,
166 requester: Option<PublicKey>,
167 ) -> Result<Option<Entries>> {
168 self.check_permission(Action::Read, requester)?;
169
170 let entries = match &self.data {
171 SeqData::Public(data) => data.in_range(start, end),
172 SeqData::Private(data) => data.in_range(start, end),
173 };
174
175 Ok(entries)
176 }
177
178 pub fn get(&self, index: Index, requester: Option<PublicKey>) -> Result<Option<&Vec<u8>>> {
180 self.check_permission(Action::Read, requester)?;
181
182 Ok(match &self.data {
183 SeqData::Public(data) => data.get(index),
184 SeqData::Private(data) => data.get(index),
185 })
186 }
187
188 pub fn last_entry(&self, requester: Option<PublicKey>) -> Result<Option<&Entry>> {
190 self.check_permission(Action::Read, requester)?;
191
192 Ok(match &self.data {
193 SeqData::Public(data) => data.last_entry(),
194 SeqData::Private(data) => data.last_entry(),
195 })
196 }
197
198 pub fn create_unsigned_append_op(&mut self, entry: Entry) -> Result<DataOp<Entry>> {
200 self.check_permission(Action::Append, None)?;
201
202 match &mut self.data {
203 SeqData::Public(data) => data.create_append_op(entry, self.authority),
204 SeqData::Private(data) => data.create_append_op(entry, self.authority),
205 }
206 }
207
208 pub fn apply_op(&mut self, op: DataOp<Entry>) -> Result<()> {
210 self.check_permission(Action::Append, Some(op.source))?;
211
212 match &mut self.data {
213 SeqData::Public(data) => data.apply_op(op),
214 SeqData::Private(data) => data.apply_op(op),
215 }
216 }
217
218 pub fn permissions(&self, user: User, requester: Option<PublicKey>) -> Result<Permissions> {
220 self.check_permission(Action::Read, requester)?;
221
222 let user_perm = match &self.data {
223 SeqData::Public(data) => data.policy().permissions(user).ok_or(Error::NoSuchEntry)?,
224 SeqData::Private(data) => data.policy().permissions(user).ok_or(Error::NoSuchEntry)?,
225 };
226
227 Ok(user_perm)
228 }
229
230 pub fn public_policy(&self) -> Result<&PublicPolicy> {
232 match &self.data {
233 SeqData::Public(data) => Ok(data.policy()),
234 SeqData::Private(_) => Err(Error::InvalidOperation),
235 }
236 }
237
238 pub fn private_policy(&self, requester: Option<PublicKey>) -> Result<&PrivatePolicy> {
240 self.check_permission(Action::Read, requester)?;
241 match &self.data {
242 SeqData::Private(data) => Ok(data.policy()),
243 SeqData::Public(_) => Err(Error::InvalidOperation),
244 }
245 }
246
247 pub fn check_permission(&self, action: Action, requester: Option<PublicKey>) -> Result<()> {
254 let requester = requester.unwrap_or(self.authority);
255 match &self.data {
256 SeqData::Public(data) => data.policy().is_action_allowed(requester, action),
257 SeqData::Private(data) => data.policy().is_action_allowed(requester, action),
258 }
259 }
260
261 pub fn owner(&self) -> PublicKey {
263 match &self.data {
264 SeqData::Public(data) => data.policy().owner,
265 SeqData::Private(data) => data.policy().owner,
266 }
267 }
268
269 pub fn replica_authority(&self) -> PublicKey {
271 self.authority
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use crate::{
278 utils, Error, Keypair, Result, Sequence, SequenceAddress, SequenceEntry, SequenceIndex,
279 SequenceKind, SequenceOp, SequencePermissions, SequencePrivatePermissions,
280 SequencePrivatePolicy, SequencePublicPermissions, SequencePublicPolicy, SequenceUser,
281 };
282 use anyhow::anyhow;
283 use proptest::prelude::*;
284 use rand::rngs::OsRng;
285 use std::{collections::BTreeMap, sync::Arc};
286 use xor_name::XorName;
287
288 #[test]
289 fn sequence_create_public() {
290 let sequence_name = XorName::random();
291 let sequence_tag = 43_000;
292 let (_, sequence) = &gen_pub_seq_replicas(None, sequence_name, sequence_tag, None, 1)[0];
293
294 assert_eq!(sequence.kind(), SequenceKind::Public);
295 assert_eq!(*sequence.name(), sequence_name);
296 assert_eq!(sequence.tag(), sequence_tag);
297 assert!(sequence.is_public());
298 assert!(!sequence.is_private());
299
300 let sequence_address =
301 SequenceAddress::from_kind(SequenceKind::Public, sequence_name, sequence_tag);
302 assert_eq!(*sequence.address(), sequence_address);
303 }
304
305 #[test]
306 fn sequence_create_private() {
307 let sequence_name = XorName::random();
308 let sequence_tag = 43_000;
309 let (_, sequence) = &gen_priv_seq_replicas(None, sequence_name, sequence_tag, None, 1)[0];
310
311 assert_eq!(sequence.kind(), SequenceKind::Private);
312 assert_eq!(*sequence.name(), sequence_name);
313 assert_eq!(sequence.tag(), sequence_tag);
314 assert!(!sequence.is_public());
315 assert!(sequence.is_private());
316
317 let sequence_address =
318 SequenceAddress::from_kind(SequenceKind::Private, sequence_name, sequence_tag);
319 assert_eq!(*sequence.address(), sequence_address);
320 }
321
322 #[test]
323 fn sequence_concurrent_append_ops() -> Result<()> {
324 let authority_keypair1 = Keypair::new_ed25519(&mut OsRng);
325 let authority1 = authority_keypair1.public_key();
326 let authority_keypair2 = Keypair::new_ed25519(&mut OsRng);
327 let authority2 = authority_keypair2.public_key();
328 let sequence_name: XorName = rand::random();
329 let sequence_tag = 43_000u64;
330
331 let mut perms = BTreeMap::default();
334 let user_perms = SequencePublicPermissions::new(true);
335 let _ = perms.insert(SequenceUser::Key(authority2), user_perms);
336
337 let mut replica1 = Sequence::new_public(
339 authority1,
340 authority1.to_string(),
341 sequence_name,
342 sequence_tag,
343 Some(SequencePublicPolicy {
344 owner: authority1,
345 permissions: perms.clone(),
346 }),
347 );
348 let mut replica2 = Sequence::new_public(
349 authority2,
350 authority2.to_string(),
351 sequence_name,
352 sequence_tag,
353 Some(SequencePublicPolicy {
354 owner: authority1,
355 permissions: perms,
356 }),
357 );
358
359 let item1 = b"item1";
361 let append_op1 = sign_sequence_op(
362 replica1.create_unsigned_append_op(item1.to_vec())?,
363 &authority_keypair1,
364 )?;
365 replica1.apply_op(append_op1.clone())?;
366
367 assert_eq!(replica1.len(None)?, 1);
369 assert_eq!(replica2.len(None)?, 0);
370
371 let item2 = b"item2";
373 let append_op2 = sign_sequence_op(
374 replica2.create_unsigned_append_op(item2.to_vec())?,
375 &authority_keypair2,
376 )?;
377 replica2.apply_op(append_op2.clone())?;
378
379 assert_eq!(replica2.len(None)?, 1);
381
382 replica1.apply_op(append_op2)?;
384 replica2.apply_op(append_op1)?;
385
386 verify_data_convergence(vec![replica1, replica2], 2)?;
388
389 Ok(())
390 }
391
392 #[test]
393 fn sequence_get_in_range() -> anyhow::Result<()> {
394 let mut replicas = create_public_seq_replicas(1);
395 let (authority_keypair, sequence) = &mut replicas[0];
396
397 let entry1 = b"value0".to_vec();
398 let entry2 = b"value1".to_vec();
399 let entry3 = b"value2".to_vec();
400
401 let op1 = sign_sequence_op(
402 sequence.create_unsigned_append_op(entry1.clone())?,
403 &authority_keypair,
404 )?;
405 sequence.apply_op(op1)?;
406
407 let op2 = sign_sequence_op(
408 sequence.create_unsigned_append_op(entry2.clone())?,
409 &authority_keypair,
410 )?;
411 sequence.apply_op(op2)?;
412
413 let op3 = sign_sequence_op(
414 sequence.create_unsigned_append_op(entry3.clone())?,
415 &authority_keypair,
416 )?;
417 sequence.apply_op(op3)?;
418
419 assert_eq!(sequence.len(None)?, 3);
420
421 let index_0 = SequenceIndex::FromStart(0);
422 let index_1 = SequenceIndex::FromStart(1);
423 let index_2 = SequenceIndex::FromStart(2);
424 let end_index = SequenceIndex::FromEnd(0);
425
426 let first_entry = sequence.in_range(index_0, index_1, None)?;
427 assert_eq!(first_entry, Some(vec![entry1.clone()]));
428
429 let all_entries = sequence.in_range(index_0, end_index, None)?;
430 assert_eq!(
431 all_entries,
432 Some(vec![entry1, entry2.clone(), entry3.clone()])
433 );
434
435 let last_entry = sequence.in_range(index_2, end_index, None)?;
436 assert_eq!(last_entry, Some(vec![entry3]));
437
438 let second_entry = sequence.in_range(index_1, SequenceIndex::FromEnd(1), None)?;
439 assert_eq!(second_entry, Some(vec![entry2]));
440
441 let index_3 = SequenceIndex::FromStart(3);
442 match sequence.in_range(index_3, index_3, None) {
443 Ok(None) => Ok(()),
444 Ok(Some(entries)) => Err(anyhow!(
445 "Unexpectedly fetched entries from Sequence: {:?}",
446 entries
447 )),
448 Err(err) => Err(anyhow!(
449 "Unexpected error thrown when trying to fetch from Sequence with out of bound start index: {:?}",
450 err
451 )),
452 }
453 }
454
455 #[test]
456 fn sequence_query_public_policy() -> anyhow::Result<()> {
457 let authority_keypair1 = Keypair::new_ed25519(&mut OsRng);
459 let owner1 = authority_keypair1.public_key();
460 let mut perms1 = BTreeMap::default();
461 let _ = perms1.insert(SequenceUser::Anyone, SequencePublicPermissions::new(true));
462 let replica1 = create_public_seq_replica_with(
463 Some(authority_keypair1),
464 Some(SequencePublicPolicy {
465 owner: owner1,
466 permissions: perms1.clone(),
467 }),
468 );
469
470 let authority_keypair2 = Keypair::new_ed25519(&mut OsRng);
472 let authority2 = authority_keypair2.public_key();
473 let mut perms2 = BTreeMap::default();
474 let _ = perms2.insert(
475 SequenceUser::Key(owner1),
476 SequencePublicPermissions::new(true),
477 );
478 let replica2 = create_public_seq_replica_with(
479 Some(authority_keypair2),
480 Some(SequencePublicPolicy {
481 owner: authority2,
482 permissions: perms2.clone(),
483 }),
484 );
485
486 assert_eq!(replica1.owner(), owner1);
487 assert_eq!(replica1.replica_authority(), owner1);
488 assert_eq!(replica1.public_policy()?.permissions, perms1);
489 assert_eq!(
490 SequencePermissions::Public(SequencePublicPermissions::new(true)),
491 replica1.permissions(SequenceUser::Anyone, None)?
492 );
493
494 assert_eq!(replica2.owner(), authority2);
495 assert_eq!(replica2.replica_authority(), authority2);
496 assert_eq!(replica2.public_policy()?.permissions, perms2);
497 assert_eq!(
498 SequencePermissions::Public(SequencePublicPermissions::new(true)),
499 replica2.permissions(SequenceUser::Key(owner1), None)?
500 );
501
502 Ok(())
503 }
504
505 #[test]
506 fn sequence_query_private_policy() -> anyhow::Result<()> {
507 let authority_keypair1 = Keypair::new_ed25519(&mut OsRng);
508 let authority1 = authority_keypair1.public_key();
509 let authority_keypair2 = Keypair::new_ed25519(&mut OsRng);
510 let authority2 = authority_keypair2.public_key();
511
512 let mut perms1 = BTreeMap::default();
513 let user_perms1 =
514 SequencePrivatePermissions::new(true, false);
515 let _ = perms1.insert(authority1, user_perms1);
516
517 let mut perms2 = BTreeMap::default();
518 let user_perms2 = SequencePrivatePermissions::new(true, true);
519 let _ = perms2.insert(authority2, user_perms2);
520 let user_perms2 =
521 SequencePrivatePermissions::new(false, true);
522 let _ = perms2.insert(authority1, user_perms2);
523
524 let replica1 = create_private_seq_replica_with(
525 Some(authority_keypair1),
526 Some(SequencePrivatePolicy {
527 owner: authority1,
528 permissions: perms1.clone(),
529 }),
530 );
531
532 let replica2 = create_private_seq_replica_with(
533 Some(authority_keypair2),
534 Some(SequencePrivatePolicy {
535 owner: authority2,
536 permissions: perms2.clone(),
537 }),
538 );
539
540 assert_eq!(replica1.owner(), authority1);
541 assert_eq!(replica1.replica_authority(), authority1);
542 assert_eq!(
543 replica1.private_policy(Some(authority1))?.permissions,
544 perms1
545 );
546 assert_eq!(
547 SequencePermissions::Private(SequencePrivatePermissions::new(true, false)),
548 replica1.permissions(SequenceUser::Key(authority1), None)?
549 );
550
551 assert_eq!(replica2.owner(), authority2);
552 assert_eq!(replica2.replica_authority(), authority2);
553 assert_eq!(
554 replica2.private_policy(Some(authority2))?.permissions,
555 perms2
556 );
557 assert_eq!(
558 SequencePermissions::Private(SequencePrivatePermissions::new(true, true)),
559 replica2.permissions(SequenceUser::Key(authority2), None)?
560 );
561 assert_eq!(
562 SequencePermissions::Private(SequencePrivatePermissions::new(false, true)),
563 replica2.permissions(SequenceUser::Key(authority1), None)?
564 );
565
566 Ok(())
567 }
568
569 #[test]
570 fn sequence_public_append_fails_when_no_perms_for_authority() -> anyhow::Result<()> {
571 let authority_keypair1 = Keypair::new_ed25519(&mut OsRng);
573 let owner1 = authority_keypair1.public_key();
574 let mut perms1 = BTreeMap::default();
575 let _ = perms1.insert(SequenceUser::Anyone, SequencePublicPermissions::new(true));
576 let mut replica1 = create_public_seq_replica_with(
577 Some(authority_keypair1.clone()),
578 Some(SequencePublicPolicy {
579 owner: owner1,
580 permissions: perms1,
581 }),
582 );
583
584 let authority_keypair2 = Keypair::new_ed25519(&mut OsRng);
586 let authority2 = authority_keypair2.public_key();
587 let mut perms2 = BTreeMap::default();
588 let _ = perms2.insert(
589 SequenceUser::Key(owner1),
590 SequencePublicPermissions::new(false),
591 );
592 let mut replica2 = create_public_seq_replica_with(
593 Some(authority_keypair2.clone()),
594 Some(SequencePublicPolicy {
595 owner: authority2,
596 permissions: perms2,
597 }),
598 );
599
600 let item1 = b"item1";
602 let item2 = b"item2";
603 let append_op1 = sign_sequence_op(
604 replica1.create_unsigned_append_op(item1.to_vec())?,
605 &authority_keypair1,
606 )?;
607 replica1.apply_op(append_op1.clone())?;
608 check_op_not_allowed_failure(replica2.apply_op(append_op1))?;
609
610 let append_op2 = sign_sequence_op(
611 replica2.create_unsigned_append_op(item2.to_vec())?,
612 &authority_keypair2,
613 )?;
614 replica1.apply_op(append_op2.clone())?;
615 replica2.apply_op(append_op2)?;
616
617 assert_eq!(replica1.len(None)?, 2);
618 assert_eq!(replica2.len(None)?, 1);
619
620 Ok(())
621 }
622
623 #[test]
624 fn sequence_private_append_fails_when_no_perms_for_authority() -> anyhow::Result<()> {
625 let authority_keypair1 = Keypair::new_ed25519(&mut OsRng);
626 let authority1 = authority_keypair1.public_key();
627 let authority_keypair2 = Keypair::new_ed25519(&mut OsRng);
628 let authority2 = authority_keypair2.public_key();
629
630 let mut perms1 = BTreeMap::default();
631 let user_perms1 =
632 SequencePrivatePermissions::new(false, true);
633 let _ = perms1.insert(authority2, user_perms1);
634
635 let mut perms2 = BTreeMap::default();
636 let user_perms2 =
637 SequencePrivatePermissions::new(true, false);
638 let _ = perms2.insert(authority1, user_perms2);
639
640 let mut replica1 = create_private_seq_replica_with(
641 Some(authority_keypair1.clone()),
642 Some(SequencePrivatePolicy {
643 owner: authority1,
644 permissions: perms1,
645 }),
646 );
647
648 let mut replica2 = create_private_seq_replica_with(
649 Some(authority_keypair2.clone()),
650 Some(SequencePrivatePolicy {
651 owner: authority2,
652 permissions: perms2,
653 }),
654 );
655
656 let item1 = b"item1";
658 let item2 = b"item2";
659 let append_op1 = sign_sequence_op(
660 replica1.create_unsigned_append_op(item1.to_vec())?,
661 &authority_keypair1,
662 )?;
663 replica1.apply_op(append_op1.clone())?;
664 check_op_not_allowed_failure(replica2.apply_op(append_op1))?;
665
666 let append_op2 = sign_sequence_op(
667 replica2.create_unsigned_append_op(item2.to_vec())?,
668 &authority_keypair2,
669 )?;
670 replica1.apply_op(append_op2.clone())?;
671 replica2.apply_op(append_op2)?;
672
673 assert_eq!(replica1.len(None)?, 2);
674 assert_eq!(replica2.len(None)?, 1);
675
676 let data = replica1.get(SequenceIndex::FromStart(0), Some(authority1))?;
680 let last_entry = replica1.last_entry(Some(authority1))?;
681 let from_range = replica1.in_range(
682 SequenceIndex::FromStart(0),
683 SequenceIndex::FromStart(1),
684 Some(authority1),
685 )?;
686 if data == Some(&item1.to_vec()) {
690 assert_eq!(last_entry, Some(&item2.to_vec()));
691 assert_eq!(from_range, Some(vec![item1.to_vec()]));
692 } else {
693 assert_eq!(data, Some(&item2.to_vec()));
694 assert_eq!(last_entry, Some(&item1.to_vec()));
695 assert_eq!(from_range, Some(vec![item2.to_vec()]));
696 }
697
698 let data = replica2.get(SequenceIndex::FromStart(0), Some(authority1))?;
699 let last_entry = replica2.last_entry(Some(authority1))?;
700 let from_range = replica2.in_range(
701 SequenceIndex::FromStart(0),
702 SequenceIndex::FromStart(1),
703 Some(authority1),
704 )?;
705 assert_eq!(data, Some(&item2.to_vec()));
706 assert_eq!(last_entry, Some(&item2.to_vec()));
707 assert_eq!(from_range, Some(vec![item2.to_vec()]));
708
709 check_op_not_allowed_failure(replica1.get(SequenceIndex::FromStart(0), Some(authority2)))?;
711 check_op_not_allowed_failure(replica1.last_entry(Some(authority2)))?;
712 check_op_not_allowed_failure(replica1.in_range(
713 SequenceIndex::FromStart(0),
714 SequenceIndex::FromStart(1),
715 Some(authority2),
716 ))?;
717
718 let data = replica2.get(SequenceIndex::FromStart(0), Some(authority2))?;
720 let last_entry = replica2.last_entry(Some(authority2))?;
721 let from_range = replica2.in_range(
722 SequenceIndex::FromStart(0),
723 SequenceIndex::FromStart(1),
724 Some(authority2),
725 )?;
726 assert_eq!(data, Some(&item2.to_vec()));
727 assert_eq!(last_entry, Some(&item2.to_vec()));
728 assert_eq!(from_range, Some(vec![item2.to_vec()]));
729
730 Ok(())
731 }
732
733 fn sign_sequence_op(
736 mut op: SequenceOp<SequenceEntry>,
737 keypair: &Keypair,
738 ) -> Result<SequenceOp<SequenceEntry>> {
739 let bytes = utils::serialise(&op.crdt_op)?;
740 let signature = keypair.sign(&bytes);
741 op.signature = Some(signature);
742 Ok(op)
743 }
744
745 fn gen_pub_seq_replicas(
746 authority_keypair: Option<Keypair>,
747 name: XorName,
748 tag: u64,
749 policy: Option<SequencePublicPolicy>,
750 count: usize,
751 ) -> Vec<(Keypair, Sequence)> {
752 let replicas: Vec<(Keypair, Sequence)> = (0..count)
753 .map(|_| {
754 let authority_keypair = authority_keypair
755 .clone()
756 .unwrap_or_else(|| Keypair::new_ed25519(&mut OsRng));
757 let authority = authority_keypair.public_key();
758 let sequence = Sequence::new_public(
759 authority,
760 authority.to_string(),
761 name,
762 tag,
763 policy.clone(),
764 );
765 (authority_keypair, sequence)
766 })
767 .collect();
768
769 assert_eq!(replicas.len(), count);
770 replicas
771 }
772
773 fn gen_priv_seq_replicas(
774 authority_keypair: Option<Keypair>,
775 name: XorName,
776 tag: u64,
777 policy: Option<SequencePrivatePolicy>,
778 count: usize,
779 ) -> Vec<(Keypair, Sequence)> {
780 let replicas: Vec<(Keypair, Sequence)> = (0..count)
781 .map(|_| {
782 let authority_keypair = authority_keypair
783 .clone()
784 .unwrap_or_else(|| Keypair::new_ed25519(&mut OsRng));
785 let authority = authority_keypair.public_key();
786 let sequence = Sequence::new_private(
787 authority,
788 authority.to_string(),
789 name,
790 tag,
791 policy.clone(),
792 );
793 (authority_keypair, sequence)
794 })
795 .collect();
796
797 assert_eq!(replicas.len(), count);
798 replicas
799 }
800
801 fn create_public_seq_replicas(count: usize) -> Vec<(Keypair, Sequence)> {
802 let sequence_name = XorName::random();
803 let sequence_tag = 43_000;
804
805 gen_pub_seq_replicas(None, sequence_name, sequence_tag, None, count)
806 }
807
808 fn create_public_seq_replica_with(
809 authority_keypair: Option<Keypair>,
810 policy: Option<SequencePublicPolicy>,
811 ) -> Sequence {
812 let sequence_name = XorName::random();
813 let sequence_tag = 43_000;
814 let replicas =
815 gen_pub_seq_replicas(authority_keypair, sequence_name, sequence_tag, policy, 1);
816 replicas[0].1.clone()
817 }
818
819 fn create_private_seq_replica_with(
820 authority_keypair: Option<Keypair>,
821 policy: Option<SequencePrivatePolicy>,
822 ) -> Sequence {
823 let sequence_name = XorName::random();
824 let sequence_tag = 43_000;
825 let replicas =
826 gen_priv_seq_replicas(authority_keypair, sequence_name, sequence_tag, policy, 1);
827 replicas[0].1.clone()
828 }
829
830 fn check_op_not_allowed_failure<T>(result: Result<T>) -> anyhow::Result<()> {
832 match result {
833 Err(Error::AccessDenied(_)) => Ok(()),
834 Err(err) => Err(anyhow!(
835 "Error returned was the unexpected one for a non-allowed op: {}",
836 err
837 )),
838 Ok(_) => Err(anyhow!(
839 "Data operation succeded unexpectedly, an AccessDenied error was expected"
840 .to_string(),
841 )),
842 }
843 }
844
845 fn verify_data_convergence(replicas: Vec<Sequence>, expected_len: u64) -> Result<()> {
847 let index_beyond = SequenceIndex::FromStart(expected_len);
850 for r in &replicas {
851 assert_eq!(r.len(None)?, expected_len);
852 assert_eq!(r.get(index_beyond, None)?, None);
853 }
854
855 for i in 0..expected_len {
857 let index = SequenceIndex::FromStart(i);
858 let r0_entry = replicas[0].get(index, None)?;
859 for r in &replicas {
860 assert_eq!(r0_entry, r.get(index, None)?);
861 }
862 }
863
864 Ok(())
865 }
866
867 fn generate_replicas(
869 max_quantity: usize,
870 ) -> impl Strategy<Value = Result<(Vec<Sequence>, Arc<Keypair>)>> {
871 let xorname = XorName::random();
872 let tag = 45_000u64;
873 let owner_keypair = Arc::new(Keypair::new_ed25519(&mut OsRng));
874 let owner = owner_keypair.public_key();
875 (1..max_quantity + 1).prop_map(move |quantity| {
876 let mut replicas = Vec::with_capacity(quantity);
877 for _ in 0..quantity {
878 let actor = Keypair::new_ed25519(&mut OsRng).public_key().to_string();
879 let policy = SequencePublicPolicy {
880 owner,
881 permissions: BTreeMap::default(),
882 };
883 let replica = Sequence::new_public(owner, actor, xorname, tag, Some(policy));
884
885 replicas.push(replica);
886 }
887
888 Ok((replicas, owner_keypair.clone()))
889 })
890 }
891
892 fn generate_seq_entry() -> impl Strategy<Value = Vec<u8>> {
894 "\\PC*".prop_map(|s| s.into_bytes())
895 }
896
897 fn generate_dataset(max_quantity: usize) -> impl Strategy<Value = Vec<Vec<u8>>> {
899 prop::collection::vec(generate_seq_entry(), 1..max_quantity + 1)
900 }
901
902 proptest! {
903 #[test]
904 fn proptest_seq_doesnt_crash_with_random_data(
905 s in generate_seq_entry()
906 ) {
907 let sequence_name = XorName::random();
909 let sequence_tag = 45_000u64;
910 let owner_keypair = Keypair::new_ed25519(&mut OsRng);
911 let policy = SequencePublicPolicy {
912 owner: owner_keypair.public_key(),
913 permissions: BTreeMap::default(),
914 };
915
916 let mut replicas = gen_pub_seq_replicas(
917 Some(owner_keypair.clone()),
918 sequence_name,
919 sequence_tag,
920 Some(policy),
921 2);
922 let (_, mut replica1) = replicas.remove(0);
923 let (_, mut replica2) = replicas.remove(0);
924
925 let append_op = sign_sequence_op(replica1.create_unsigned_append_op(s)?, &owner_keypair)?;
927 replica1.apply_op(append_op.clone())?;
928 replica2.apply_op(append_op)?;
929
930 verify_data_convergence(vec![replica1, replica2], 1)?;
931 }
932
933 #[test]
934 fn proptest_seq_converge_with_many_random_data(
935 dataset in generate_dataset(1000)
936 ) {
937 let sequence_name = XorName::random();
939 let sequence_tag = 43_001u64;
940 let owner_keypair = Keypair::new_ed25519(&mut OsRng);
941 let policy = SequencePublicPolicy {
942 owner: owner_keypair.public_key(),
943 permissions: BTreeMap::default(),
944 };
945
946 let mut replicas = gen_pub_seq_replicas(
948 Some(owner_keypair.clone()),
949 sequence_name,
950 sequence_tag,
951 Some(policy),
952 2);
953 let (_, mut replica1) = replicas.remove(0);
954 let (_, mut replica2) = replicas.remove(0);
955
956 let dataset_length = dataset.len() as u64;
957
958 for data in dataset {
960 let append_op = sign_sequence_op(replica1.create_unsigned_append_op(data)?, &owner_keypair)?;
962 replica1.apply_op(append_op.clone())?;
963 replica2.apply_op(append_op)?;
965 }
966
967 verify_data_convergence(vec![replica1, replica2], dataset_length)?;
968
969 }
970
971 #[test]
972 fn proptest_seq_converge_with_many_random_data_across_arbitrary_number_of_replicas(
973 dataset in generate_dataset(500),
974 res in generate_replicas(50)
975 ) {
976 let (mut replicas, owner_keypair) = res?;
977 let dataset_length = dataset.len() as u64;
978
979 for data in dataset {
981 let op = sign_sequence_op(replicas[0].create_unsigned_append_op(data)?, &owner_keypair)?;
983
984 for replica in &mut replicas {
986 replica.apply_op(op.clone())?;
987 }
988 }
989
990 verify_data_convergence(replicas, dataset_length)?;
991 }
992 }
993}