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::{CrdtDataOperation, CrdtPolicyOperation, Op, SequenceCrdt};
19use serde::{Deserialize, Serialize};
20use std::{
21 collections::BTreeMap,
22 fmt::{self, Debug, Formatter},
23 hash::Hash,
24};
25use xor_name::XorName;
26type ActorType = PublicKey;
28
29pub type DataWriteOp<T> = CrdtDataOperation<ActorType, T>;
31
32pub type PolicyWriteOp<T> = CrdtPolicyOperation<ActorType, T>;
34
35pub type PublicSeqData = SequenceCrdt<ActorType, PublicPolicy>;
37pub type PrivateSeqData = SequenceCrdt<ActorType, PrivatePolicy>;
39
40impl Debug for PublicSeqData {
41 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
42 write!(formatter, "PubSequence {:?}", self.address().name())
43 }
44}
45
46impl Debug for PrivateSeqData {
47 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
48 write!(formatter, "PrivSequence {:?}", self.address().name())
49 }
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, PartialOrd, Eq, Hash)]
56pub struct WriteOp<T> {
57 pub address: Address,
59 pub crdt_op: Op<T, ActorType>,
61}
62
63#[derive(Clone, Eq, PartialEq, PartialOrd, Hash, Serialize, Deserialize, Debug)]
65pub enum Data {
66 Public(PublicSeqData),
68 Private(PrivateSeqData),
70}
71
72impl Data {
73 pub fn new_public(actor: ActorType, name: XorName, tag: u64) -> Self {
75 Self::Public(PublicSeqData::new(actor, Address::Public { name, tag }))
76 }
77
78 pub fn new_private(actor: ActorType, name: XorName, tag: u64) -> Self {
80 Self::Private(PrivateSeqData::new(actor, Address::Private { name, tag }))
81 }
82
83 pub fn address(&self) -> &Address {
85 match self {
86 Data::Public(data) => data.address(),
87 Data::Private(data) => data.address(),
88 }
89 }
90
91 pub fn kind(&self) -> Kind {
93 self.address().kind()
94 }
95
96 pub fn name(&self) -> &XorName {
98 self.address().name()
99 }
100
101 pub fn tag(&self) -> u64 {
103 self.address().tag()
104 }
105
106 pub fn is_pub(&self) -> bool {
108 self.kind().is_pub()
109 }
110
111 pub fn is_private(&self) -> bool {
113 self.kind().is_private()
114 }
115
116 pub fn check_permission(&self, action: Action, requester: PublicKey) -> Result<()> {
123 macro_rules! check_perm {
124 ($data: ident, $requester: ident, $action: ident) => {
125 $data
126 .policy(Index::FromEnd(1))
127 .ok_or(Error::AccessDenied)?
128 .is_action_allowed($requester, $action)
129 };
130 }
131
132 match self {
133 Data::Public(data) => check_perm!(data, requester, action),
134 Data::Private(data) => check_perm!(data, requester, action),
135 }
136 }
137
138 pub fn len(&self) -> u64 {
140 match self {
141 Data::Public(data) => data.len(),
142 Data::Private(data) => data.len(),
143 }
144 }
145
146 pub fn is_empty(&self) -> bool {
148 self.len() == 0
149 }
150
151 pub fn policy_version(&self) -> u64 {
153 match self {
154 Data::Public(data) => data.policy_index(),
155 Data::Private(data) => data.policy_index(),
156 }
157 }
158
159 pub fn in_range(&self, start: Index, end: Index) -> Option<Entries> {
161 match self {
162 Data::Public(data) => data.in_range(start, end),
163 Data::Private(data) => data.in_range(start, end),
164 }
165 }
166
167 pub fn get(&self, index: Index) -> Option<&Vec<u8>> {
169 match self {
170 Data::Public(data) => data.get(index),
171 Data::Private(data) => data.get(index),
172 }
173 }
174
175 pub fn last_entry(&self) -> Option<&Entry> {
177 match self {
178 Data::Public(data) => data.last_entry(),
179 Data::Private(data) => data.last_entry(),
180 }
181 }
182
183 pub fn append(&mut self, entry: Entry) -> Result<DataWriteOp<Entry>> {
185 match self {
186 Data::Public(data) => data.append(entry),
187 Data::Private(data) => data.append(entry),
188 }
189 }
190
191 pub fn apply_data_op(&mut self, op: DataWriteOp<Entry>) -> Result<()> {
193 match self {
194 Data::Public(data) => data.apply_data_op(op),
195 Data::Private(data) => data.apply_data_op(op),
196 }
197 }
198
199 pub fn set_pub_policy(
201 &mut self,
202 owner: PublicKey,
203 permissions: BTreeMap<User, PublicPermissions>,
204 ) -> Result<PolicyWriteOp<PublicPolicy>> {
205 match self {
206 Data::Public(data) => data.set_policy(PublicPolicy { owner, permissions }),
207 Data::Private(_) => Err(Error::InvalidOperation),
208 }
209 }
210
211 pub fn set_priv_policy(
213 &mut self,
214 owner: PublicKey,
215 permissions: BTreeMap<PublicKey, PrivatePermissions>,
216 ) -> Result<PolicyWriteOp<PrivatePolicy>> {
217 match self {
218 Data::Private(data) => data.set_policy(PrivatePolicy { owner, permissions }),
219 Data::Public(_) => Err(Error::InvalidOperation),
220 }
221 }
222
223 pub fn apply_pub_policy_op(&mut self, op: PolicyWriteOp<PublicPolicy>) -> Result<()> {
225 match (self, &op.crdt_op) {
226 (Data::Public(data), Op::Insert { .. }) => data.apply_policy_op(op),
227 _ => Err(Error::InvalidOperation),
228 }
229 }
230
231 pub fn apply_priv_policy_op(&mut self, op: PolicyWriteOp<PrivatePolicy>) -> Result<()> {
233 match self {
234 Data::Private(data) => data.apply_policy_op(op),
235 _ => Err(Error::InvalidOperation),
236 }
237 }
238
239 pub fn permissions(&self, user: User, version: impl Into<Index>) -> Result<Permissions> {
241 let user_perm = match self {
242 Data::Public(data) => data
243 .policy(version)
244 .ok_or(Error::NoSuchEntry)?
245 .permissions(user)
246 .ok_or(Error::NoSuchEntry)?,
247 Data::Private(data) => data
248 .policy(version)
249 .ok_or(Error::NoSuchEntry)?
250 .permissions(user)
251 .ok_or(Error::NoSuchEntry)?,
252 };
253
254 Ok(user_perm)
255 }
256
257 pub fn pub_policy(&self, version: impl Into<Index>) -> Result<&PublicPolicy> {
259 let perms = match self {
260 Data::Public(data) => data.policy(version),
261 Data::Private(_) => return Err(Error::InvalidOperation),
262 };
263 perms.ok_or(Error::NoSuchEntry)
264 }
265
266 pub fn priv_policy(&self, version: impl Into<Index>) -> Result<&PrivatePolicy> {
268 let perms = match self {
269 Data::Private(data) => data.policy(version),
270 Data::Public(_) => return Err(Error::InvalidOperation),
271 };
272 perms.ok_or(Error::NoSuchEntry)
273 }
274}
275
276impl From<PublicSeqData> for Data {
277 fn from(data: PublicSeqData) -> Self {
278 Data::Public(data)
279 }
280}
281
282impl From<PrivateSeqData> for Data {
283 fn from(data: PrivateSeqData) -> Self {
284 Data::Private(data)
285 }
286}
287
288#[cfg(test)]
289mod tests {
290 use crate::{
291 Error, PublicKey, Result, Sequence, SequenceAddress, SequenceIndex, SequenceKind,
292 SequencePermissions, SequencePrivatePermissions, SequencePublicPermissions, SequenceUser,
293 };
294 use std::collections::BTreeMap;
295 use threshold_crypto::SecretKey;
296 use xor_name::XorName;
297
298 #[test]
299 fn sequence_create_public() {
300 let actor = gen_public_key();
301 let sequence_name = XorName::random();
302 let sequence_tag = 43_000;
303 let sequence = Sequence::new_public(actor, sequence_name, sequence_tag);
304 assert_eq!(sequence.kind(), SequenceKind::Public);
305 assert_eq!(*sequence.name(), sequence_name);
306 assert_eq!(sequence.tag(), sequence_tag);
307 assert!(sequence.is_pub());
308 assert!(!sequence.is_private());
309
310 let sequence_address =
311 SequenceAddress::from_kind(SequenceKind::Public, sequence_name, sequence_tag);
312 assert_eq!(*sequence.address(), sequence_address);
313 }
314
315 #[test]
316 fn sequence_create_private() {
317 let actor = gen_public_key();
318 let sequence_name = XorName::random();
319 let sequence_tag = 43_000;
320 let sequence = Sequence::new_private(actor, sequence_name, sequence_tag);
321 assert_eq!(sequence.kind(), SequenceKind::Private);
322 assert_eq!(*sequence.name(), sequence_name);
323 assert_eq!(sequence.tag(), sequence_tag);
324 assert!(!sequence.is_pub());
325 assert!(sequence.is_private());
326
327 let sequence_address =
328 SequenceAddress::from_kind(SequenceKind::Private, sequence_name, sequence_tag);
329 assert_eq!(*sequence.address(), sequence_address);
330 }
331
332 #[test]
333 fn sequence_append_entry_and_apply() -> Result<()> {
334 let actor = gen_public_key();
335 let sequence_name = XorName::random();
336 let sequence_tag = 43_000;
337 let mut replica1 = Sequence::new_public(actor, sequence_name, sequence_tag);
338 let mut replica2 = Sequence::new_public(actor, sequence_name, sequence_tag);
339
340 let mut perms1 = BTreeMap::default();
341 let user_perms1 = SequencePublicPermissions::new(true, false);
342 let _ = perms1.insert(SequenceUser::Anyone, user_perms1);
343 let policy_op = replica1.set_pub_policy(actor, perms1)?;
344 replica2.apply_pub_policy_op(policy_op)?;
345
346 let entry1 = b"value0".to_vec();
347 let entry2 = b"value1".to_vec();
348
349 let op1 = replica1.append(entry1.clone())?;
350 let op2 = replica1.append(entry2.clone())?;
351
352 replica2.apply_data_op(op2)?;
354 replica2.apply_data_op(op1)?;
355
356 assert_eq!(replica1.len(), 2);
357 assert_eq!(replica2.len(), 2);
358
359 let index_0 = SequenceIndex::FromStart(0);
360 let first_entry = replica1.get(index_0);
361 assert_eq!(first_entry, Some(&entry1));
362 assert_eq!(first_entry, replica2.get(index_0));
363
364 let index_1 = SequenceIndex::FromStart(1);
365 let second_entry = replica1.get(index_1);
366 assert_eq!(second_entry, Some(&entry2));
367 assert_eq!(second_entry, replica2.get(index_1));
368
369 let last_entry = replica1.last_entry();
370 assert_eq!(last_entry, Some(&entry2));
371 assert_eq!(last_entry, replica2.last_entry());
372
373 Ok(())
374 }
375
376 #[test]
377 fn sequence_public_set_policy_and_apply() -> Result<()> {
378 let actor = gen_public_key();
379 let sequence_name = XorName::random();
380 let sequence_tag = 43_000;
381 let mut replica1 = Sequence::new_public(actor, sequence_name, sequence_tag);
382 let mut replica2 = Sequence::new_public(actor, sequence_name, sequence_tag);
383
384 let mut perms1 = BTreeMap::default();
385 let user_perms1 = SequencePublicPermissions::new(true, false);
386 let _ = perms1.insert(SequenceUser::Anyone, user_perms1);
387
388 let mut perms2 = BTreeMap::default();
389 let user_perms2 = SequencePublicPermissions::new(false, true);
390 let _ = perms2.insert(SequenceUser::Key(actor), user_perms2);
391
392 let op1 = replica1.set_pub_policy(actor, perms1.clone())?;
393 let op2 = replica1.set_pub_policy(actor, perms2.clone())?;
394
395 check_not_causally_ready_failure(replica2.apply_pub_policy_op(op2.clone()))?;
398
399 replica2.apply_pub_policy_op(op1)?;
401 replica2.apply_pub_policy_op(op2)?;
402
403 assert_eq!(replica1.policy_version(), 2);
404 assert_eq!(replica2.policy_version(), 2);
405
406 let index_0 = SequenceIndex::FromStart(0);
407 let first_entry = replica1.pub_policy(index_0)?;
408 assert_eq!(first_entry.permissions, perms1);
409 assert_eq!(first_entry.owner, actor);
410 assert_eq!(first_entry, replica2.pub_policy(index_0)?);
411 assert_eq!(
412 SequencePermissions::Pub(user_perms1),
413 replica1.permissions(SequenceUser::Anyone, index_0)?
414 );
415
416 let index_1 = SequenceIndex::FromStart(1);
417 let second_entry = replica1.pub_policy(index_1)?;
418 assert_eq!(second_entry.permissions, perms2);
419 assert_eq!(second_entry.owner, actor);
420 assert_eq!(second_entry, replica2.pub_policy(index_1)?);
421 assert_eq!(
422 SequencePermissions::Pub(user_perms2),
423 replica1.permissions(SequenceUser::Key(actor), index_1)?
424 );
425
426 Ok(())
427 }
428
429 #[test]
430 fn sequence_private_set_policy_and_apply() -> Result<()> {
431 let actor1 = gen_public_key();
432 let actor2 = gen_public_key();
433 let sequence_name = XorName::random();
434 let sequence_tag = 43_000;
435 let mut replica1 = Sequence::new_private(actor1, sequence_name, sequence_tag);
436 let mut replica2 = Sequence::new_private(actor2, sequence_name, sequence_tag);
437
438 let mut perms1 = BTreeMap::default();
439 let user_perms1 = SequencePrivatePermissions::new(true, false, true);
440 let _ = perms1.insert(actor1, user_perms1);
441
442 let mut perms2 = BTreeMap::default();
443 let user_perms2 = SequencePrivatePermissions::new(false, true, false);
444 let _ = perms2.insert(actor2, user_perms2);
445
446 let op1 = replica1.set_priv_policy(actor2, perms1.clone())?;
447 let op2 = replica1.set_priv_policy(actor1, perms2.clone())?;
448
449 check_not_causally_ready_failure(replica2.apply_priv_policy_op(op2.clone()))?;
452
453 replica2.apply_priv_policy_op(op1)?;
455 replica2.apply_priv_policy_op(op2)?;
456
457 assert_eq!(replica1.policy_version(), 2);
458 assert_eq!(replica2.policy_version(), 2);
459
460 let index_0 = SequenceIndex::FromStart(0);
461 let first_entry = replica1.priv_policy(index_0)?;
462 assert_eq!(first_entry.permissions, perms1);
463 assert_eq!(first_entry.owner, actor2);
464 assert_eq!(first_entry, replica2.priv_policy(index_0)?);
465 assert_eq!(
466 SequencePermissions::Priv(user_perms1),
467 replica1.permissions(SequenceUser::Key(actor1), index_0)?
468 );
469
470 let index_1 = SequenceIndex::FromStart(1);
471 let second_entry = replica1.priv_policy(index_1)?;
472 assert_eq!(second_entry.permissions, perms2);
473 assert_eq!(second_entry.owner, actor1);
474 assert_eq!(second_entry, replica2.priv_policy(index_1)?);
475 assert_eq!(
476 SequencePermissions::Priv(user_perms2),
477 replica1.permissions(SequenceUser::Key(actor2), index_1)?
478 );
479
480 Ok(())
481 }
482
483 #[test]
484 fn sequence_concurrent_policy_and_data_ops() -> Result<()> {
485 let actor1 = gen_public_key();
486 let actor2 = gen_public_key();
487 let sdata_name: XorName = rand::random();
488 let sdata_tag = 43_000u64;
489
490 let mut replica1 = Sequence::new_public(actor1, sdata_name, sdata_tag);
492 let mut replica2 = Sequence::new_public(actor2, sdata_name, sdata_tag);
493
494 let mut perms = BTreeMap::default();
497 let user_perms =
498 SequencePublicPermissions::new(true, false);
499 let _ = perms.insert(SequenceUser::Key(actor2), user_perms);
500 let grant_op = replica1.set_pub_policy(actor1, perms)?;
501 replica2.apply_pub_policy_op(grant_op)?;
502
503 let item1 = b"item1";
505 let append_op1 = replica1.append(item1.to_vec())?;
506 replica2.apply_data_op(append_op1)?;
507
508 assert_eq!(replica1.len(), 1);
510 assert_eq!(replica1.policy_version(), 1);
511 assert_eq!(replica2.len(), 1);
512 assert_eq!(replica2.policy_version(), 1);
513
514 let revoke_op = replica1.set_pub_policy(actor1, BTreeMap::default())?;
516 assert_eq!(replica1.policy_version(), 2);
518
519 let item2 = b"item2";
521 let append_op2 = replica2.append(item2.to_vec())?;
522 assert_eq!(replica2.len(), 2);
524
525 replica1.apply_data_op(append_op2)?;
527 assert_eq!(replica1.len(), 1);
528
529 replica2.apply_pub_policy_op(revoke_op)?;
531 assert_eq!(replica2.policy_version(), 2);
532 assert_eq!(replica2.len(), 1);
533
534 verify_data_convergence(&[&replica1, &replica2], 1);
538
539 Ok(())
540 }
541
542 #[test]
543 fn sequence_causality_between_data_and_policy_ops() -> Result<()> {
544 let actor1 = gen_public_key();
545 let actor2 = gen_public_key();
546 let actor3 = gen_public_key();
547 let sdata_name: XorName = rand::random();
548 let sdata_tag = 43_001u64;
549
550 let mut replica1 = Sequence::new_public(actor1, sdata_name, sdata_tag);
552 let mut replica2 = Sequence::new_public(actor2, sdata_name, sdata_tag);
553 let mut replica3 = Sequence::new_public(actor3, sdata_name, sdata_tag);
554
555 let owner_op = replica1.set_pub_policy(actor1, BTreeMap::default())?;
557 replica2.apply_pub_policy_op(owner_op.clone())?;
558 replica3.apply_pub_policy_op(owner_op)?;
559
560 let mut perms = BTreeMap::default();
562 let user_perms =
563 SequencePublicPermissions::new(true, false);
564 let _ = perms.insert(SequenceUser::Key(actor3), user_perms);
565 let grant_op = replica1.set_pub_policy(actor1, perms)?;
566 replica3.apply_pub_policy_op(grant_op.clone())?;
567
568 assert_eq!(replica1.len(), 0);
570 assert_eq!(replica1.policy_version(), 2);
571 assert_eq!(replica2.len(), 0);
572 assert_eq!(replica2.policy_version(), 1);
573 assert_eq!(replica3.len(), 0);
574 assert_eq!(replica3.policy_version(), 2);
575
576 let item = b"item0";
578 let append_op = replica3.append(item.to_vec())?;
579 assert_eq!(replica3.len(), 1);
580
581 replica1.apply_data_op(append_op.clone())?;
583 assert_eq!(replica1.len(), 1);
584
585 check_not_causally_ready_failure(replica2.apply_data_op(append_op.clone()))?;
588 assert_eq!(replica2.len(), 0);
589
590 replica2.apply_pub_policy_op(grant_op)?;
592 assert_eq!(replica2.policy_version(), 2);
593
594 replica2.apply_data_op(append_op)?;
597 verify_data_convergence(&[&replica1, &replica2, &replica3], 1);
598
599 Ok(())
600 }
601
602 #[test]
603 fn sequence_concurrent_policy_ops() -> Result<()> {
604 let actor1 = gen_public_key();
605 let actor2 = gen_public_key();
606 let sdata_name: XorName = rand::random();
607 let sdata_tag = 43_001u64;
608
609 let mut replica1 = Sequence::new_public(actor1, sdata_name, sdata_tag);
611 let mut replica2 = Sequence::new_public(actor2, sdata_name, sdata_tag);
612
613 let mut perms = BTreeMap::default();
615 let user_perms =
616 SequencePublicPermissions::new(true, false);
617 let _ = perms.insert(SequenceUser::Key(actor2), user_perms);
618 let owner_op = replica1.set_pub_policy(actor1, perms.clone())?;
619 replica2.apply_pub_policy_op(owner_op)?;
620
621 let item0 = b"item0".to_vec();
623 let append_op = replica1.append(item0)?;
624 replica2.apply_data_op(append_op)?;
625
626 assert_eq!(replica1.len(), 1);
628 assert_eq!(replica1.policy_version(), 1);
629 assert_eq!(replica2.len(), 1);
630 assert_eq!(replica2.policy_version(), 1);
631
632 let owner_op_1 = replica1.set_pub_policy(actor2, perms.clone())?;
634 let owner_op_2 = replica2.set_pub_policy(actor2, perms)?;
635 let item1_r1 = b"item1_replica1".to_vec();
637 let item1_r2 = b"item1_replica2".to_vec();
638 let append_op1 = replica1.append(item1_r1)?;
639 let append_op2 = replica2.append(item1_r2)?;
640
641 assert_eq!(replica1.len(), 2);
642 assert_eq!(replica2.len(), 2);
643
644 replica1.apply_pub_policy_op(owner_op_2)?;
646 replica2.apply_pub_policy_op(owner_op_1)?;
647
648 assert_eq!(replica1.policy_version(), 3);
649 assert_eq!(replica2.policy_version(), 3);
650
651 replica1.apply_data_op(append_op2)?;
653 replica2.apply_data_op(append_op1)?;
654
655 verify_data_convergence(&[&replica1, &replica2], 2);
659
660 Ok(())
661 }
662
663 #[test]
664 fn sequence_old_data_op() -> Result<()> {
665 let actor1 = gen_public_key();
666 let actor2 = gen_public_key();
667 let sdata_name: XorName = rand::random();
668 let sdata_tag = 43_001u64;
669
670 let mut replica1 = Sequence::new_public(actor1, sdata_name, sdata_tag);
672 let mut replica2 = Sequence::new_public(actor2, sdata_name, sdata_tag);
673
674 let mut perms = BTreeMap::default();
676 let user_perms =
677 SequencePublicPermissions::new(true, false);
678 let _ = perms.insert(SequenceUser::Key(actor2), user_perms);
679 let owner_op = replica1.set_pub_policy(actor1, perms)?;
680 replica2.apply_pub_policy_op(owner_op)?;
681
682 let item0 = b"item0".to_vec();
684 let append_op = replica1.append(item0)?;
685
686 let policy_op = replica1.set_pub_policy(actor1, BTreeMap::default())?;
688 replica2.apply_pub_policy_op(policy_op)?;
689
690 replica2.apply_data_op(append_op)?;
692
693 assert_eq!(replica1.policy_version(), 2);
694 assert_eq!(replica2.policy_version(), 2);
695
696 verify_data_convergence(&[&replica1, &replica2], 1);
697
698 Ok(())
699 }
700
701 fn gen_public_key() -> PublicKey {
704 PublicKey::Bls(SecretKey::random().public_key())
705 }
706
707 fn check_not_causally_ready_failure(result: Result<()>) -> Result<()> {
709 match result {
710 Err(Error::OpNotCausallyReady) => Ok(()),
711 Err(err) => Err(Error::Unexpected(format!(
712 "Error returned was the unexpected one: {}",
713 err
714 ))),
715 Ok(()) => Err(Error::Unexpected(
716 "Data op applied unexpectedly".to_string(),
717 )),
718 }
719 }
720
721 fn verify_data_convergence(replicas: &[&Sequence], expected_len: u64) {
723 let index_beyond = SequenceIndex::FromStart(expected_len);
726 for r in replicas {
727 assert_eq!(r.len(), expected_len);
728 assert_eq!(r.get(index_beyond), None);
729 }
730
731 for i in 0..expected_len {
733 let index = SequenceIndex::FromStart(i);
734 let r0_entry = replicas[0].get(index);
735 for r in replicas {
736 assert_eq!(r0_entry, r.get(index));
737 }
738 }
739 }
740}