1use std::collections::HashMap;
14use std::time::Duration;
15
16use super::{
17 DeRecChannelStore, DeRecProtocol, DeRecSecretStore, DeRecShareStore, DeRecStateStore,
18 DeRecTransport, DeRecUserSecretStore, UnpairAck,
19};
20use derec_proto::TransportProtocol;
21
22pub struct BuilderSlotMissingMarker;
23
24pub struct BuilderSlotSetMarker<T>(T);
25
26pub struct DeRecProtocolBuilder<
48 ChannelStore,
49 ShareStore,
50 SecretStore,
51 UserSecretStore,
52 StateStore,
53 Transport,
54 OwnTransport,
55> {
56 secret_id: u64,
57 channel_store: ChannelStore,
58 share_store: ShareStore,
59 secret_store: SecretStore,
60 user_secret_store: UserSecretStore,
61 state_store: StateStore,
62 transport: Transport,
63 own_transport: OwnTransport,
64 threshold: usize,
65 keep_versions_count: usize,
66 timeout_in_secs: u64,
67 communication_info: HashMap<String, String>,
68 auto_respond_on_failure: bool,
69 unpair_ack: UnpairAck,
70 auto_reply_to: bool,
71 auto_accept: crate::protocol::AutoAcceptPolicy,
72 replica_id: Option<u64>,
73 parameter_range: Option<derec_proto::ParameterRange>,
74}
75
76impl
77 DeRecProtocolBuilder<
78 BuilderSlotMissingMarker,
79 BuilderSlotMissingMarker,
80 BuilderSlotMissingMarker,
81 BuilderSlotMissingMarker,
82 BuilderSlotMissingMarker,
83 BuilderSlotMissingMarker,
84 BuilderSlotMissingMarker,
85 >
86{
87 pub fn new(secret_id: u64) -> Self {
93 Self {
94 secret_id,
95 channel_store: BuilderSlotMissingMarker,
96 share_store: BuilderSlotMissingMarker,
97 secret_store: BuilderSlotMissingMarker,
98 user_secret_store: BuilderSlotMissingMarker,
99 state_store: BuilderSlotMissingMarker,
100 transport: BuilderSlotMissingMarker,
101 own_transport: BuilderSlotMissingMarker,
102 threshold: 3,
103 keep_versions_count: 3,
104 timeout_in_secs: 300,
105 communication_info: HashMap::new(),
106 auto_respond_on_failure: false,
107 unpair_ack: UnpairAck::Required,
108 auto_reply_to: false,
109 auto_accept: crate::protocol::AutoAcceptPolicy::default(),
110 replica_id: None,
111 parameter_range: None,
112 }
113 }
114}
115
116impl<ChannelStore, ShareStore, SecretStore, UserSecretStore, StateStore, Transport, OwnTransport>
117 DeRecProtocolBuilder<
118 ChannelStore,
119 ShareStore,
120 SecretStore,
121 UserSecretStore,
122 StateStore,
123 Transport,
124 OwnTransport,
125 >
126{
127 pub fn with_threshold(mut self, threshold: usize) -> Self {
136 self.threshold = threshold;
137 self
138 }
139
140 pub fn with_keep_versions_count(mut self, count: usize) -> Self {
144 self.keep_versions_count = count;
145 self
146 }
147
148 pub fn with_timeout(mut self, timeout: Duration) -> Self {
171 self.timeout_in_secs = timeout.as_secs().max(1);
172 self
173 }
174
175 pub fn with_communication_info(mut self, info: HashMap<String, String>) -> Self {
180 self.communication_info = info;
181 self
182 }
183
184 pub fn with_auto_respond_on_failure(mut self, enabled: bool) -> Self {
194 self.auto_respond_on_failure = enabled;
195 self
196 }
197
198 pub fn with_unpair_ack(mut self, ack: UnpairAck) -> Self {
208 self.unpair_ack = ack;
209 self
210 }
211
212 pub fn with_auto_reply_to(mut self, enabled: bool) -> Self {
233 self.auto_reply_to = enabled;
234 self
235 }
236
237 pub fn with_auto_accept(
251 mut self,
252 policy: crate::protocol::AutoAcceptPolicy,
253 ) -> Self {
254 self.auto_accept = policy;
255 self
256 }
257
258 pub fn with_replica_id(mut self, id: u64) -> Self {
279 self.replica_id = Some(id);
280 self
281 }
282
283 pub fn with_parameter_range(mut self, range: derec_proto::ParameterRange) -> Self {
295 self.parameter_range = Some(range);
296 self
297 }
298}
299
300impl<ShareStore, SecretStore, UserSecretStore, StateStore, Transport, OwnTransport>
301 DeRecProtocolBuilder<
302 BuilderSlotMissingMarker,
303 ShareStore,
304 SecretStore,
305 UserSecretStore,
306 StateStore,
307 Transport,
308 OwnTransport,
309 >
310{
311 pub fn with_channel_store<Cs: DeRecChannelStore>(
314 self,
315 store: Cs,
316 ) -> DeRecProtocolBuilder<
317 BuilderSlotSetMarker<Cs>,
318 ShareStore,
319 SecretStore,
320 UserSecretStore,
321 StateStore,
322 Transport,
323 OwnTransport,
324 > {
325 DeRecProtocolBuilder {
326 secret_id: self.secret_id,
327 channel_store: BuilderSlotSetMarker(store),
328 share_store: self.share_store,
329 secret_store: self.secret_store,
330 user_secret_store: self.user_secret_store,
331 state_store: self.state_store,
332 transport: self.transport,
333 own_transport: self.own_transport,
334 threshold: self.threshold,
335 keep_versions_count: self.keep_versions_count,
336 timeout_in_secs: self.timeout_in_secs,
337 communication_info: self.communication_info,
338 auto_respond_on_failure: self.auto_respond_on_failure,
339 unpair_ack: self.unpair_ack,
340 auto_reply_to: self.auto_reply_to,
341 auto_accept: self.auto_accept,
342 replica_id: self.replica_id,
343 parameter_range: self.parameter_range,
344 }
345 }
346}
347
348impl<ChannelStore, SecretStore, UserSecretStore, StateStore, Transport, OwnTransport>
349 DeRecProtocolBuilder<
350 ChannelStore,
351 BuilderSlotMissingMarker,
352 SecretStore,
353 UserSecretStore,
354 StateStore,
355 Transport,
356 OwnTransport,
357 >
358{
359 pub fn with_share_store<Sh: DeRecShareStore>(
362 self,
363 store: Sh,
364 ) -> DeRecProtocolBuilder<
365 ChannelStore,
366 BuilderSlotSetMarker<Sh>,
367 SecretStore,
368 UserSecretStore,
369 StateStore,
370 Transport,
371 OwnTransport,
372 > {
373 DeRecProtocolBuilder {
374 secret_id: self.secret_id,
375 channel_store: self.channel_store,
376 share_store: BuilderSlotSetMarker(store),
377 secret_store: self.secret_store,
378 user_secret_store: self.user_secret_store,
379 state_store: self.state_store,
380 transport: self.transport,
381 own_transport: self.own_transport,
382 threshold: self.threshold,
383 keep_versions_count: self.keep_versions_count,
384 timeout_in_secs: self.timeout_in_secs,
385 communication_info: self.communication_info,
386 auto_respond_on_failure: self.auto_respond_on_failure,
387 unpair_ack: self.unpair_ack,
388 auto_reply_to: self.auto_reply_to,
389 auto_accept: self.auto_accept,
390 replica_id: self.replica_id,
391 parameter_range: self.parameter_range,
392 }
393 }
394}
395
396impl<ChannelStore, ShareStore, UserSecretStore, StateStore, Transport, OwnTransport>
397 DeRecProtocolBuilder<
398 ChannelStore,
399 ShareStore,
400 BuilderSlotMissingMarker,
401 UserSecretStore,
402 StateStore,
403 Transport,
404 OwnTransport,
405 >
406{
407 pub fn with_secret_store<Ss: DeRecSecretStore>(
410 self,
411 store: Ss,
412 ) -> DeRecProtocolBuilder<
413 ChannelStore,
414 ShareStore,
415 BuilderSlotSetMarker<Ss>,
416 UserSecretStore,
417 StateStore,
418 Transport,
419 OwnTransport,
420 > {
421 DeRecProtocolBuilder {
422 secret_id: self.secret_id,
423 channel_store: self.channel_store,
424 share_store: self.share_store,
425 secret_store: BuilderSlotSetMarker(store),
426 user_secret_store: self.user_secret_store,
427 state_store: self.state_store,
428 transport: self.transport,
429 own_transport: self.own_transport,
430 threshold: self.threshold,
431 keep_versions_count: self.keep_versions_count,
432 timeout_in_secs: self.timeout_in_secs,
433 communication_info: self.communication_info,
434 auto_respond_on_failure: self.auto_respond_on_failure,
435 unpair_ack: self.unpair_ack,
436 auto_reply_to: self.auto_reply_to,
437 auto_accept: self.auto_accept,
438 replica_id: self.replica_id,
439 parameter_range: self.parameter_range,
440 }
441 }
442}
443
444impl<ChannelStore, ShareStore, SecretStore, StateStore, Transport, OwnTransport>
445 DeRecProtocolBuilder<
446 ChannelStore,
447 ShareStore,
448 SecretStore,
449 BuilderSlotMissingMarker,
450 StateStore,
451 Transport,
452 OwnTransport,
453 >
454{
455 pub fn with_user_secret_store<Us: DeRecUserSecretStore>(
461 self,
462 store: Us,
463 ) -> DeRecProtocolBuilder<
464 ChannelStore,
465 ShareStore,
466 SecretStore,
467 BuilderSlotSetMarker<Us>,
468 StateStore,
469 Transport,
470 OwnTransport,
471 > {
472 DeRecProtocolBuilder {
473 secret_id: self.secret_id,
474 channel_store: self.channel_store,
475 share_store: self.share_store,
476 secret_store: self.secret_store,
477 user_secret_store: BuilderSlotSetMarker(store),
478 state_store: self.state_store,
479 transport: self.transport,
480 own_transport: self.own_transport,
481 threshold: self.threshold,
482 keep_versions_count: self.keep_versions_count,
483 timeout_in_secs: self.timeout_in_secs,
484 communication_info: self.communication_info,
485 auto_respond_on_failure: self.auto_respond_on_failure,
486 unpair_ack: self.unpair_ack,
487 auto_reply_to: self.auto_reply_to,
488 auto_accept: self.auto_accept,
489 replica_id: self.replica_id,
490 parameter_range: self.parameter_range,
491 }
492 }
493}
494
495impl<ChannelStore, ShareStore, SecretStore, UserSecretStore, StateStore, OwnTransport>
496 DeRecProtocolBuilder<
497 ChannelStore,
498 ShareStore,
499 SecretStore,
500 UserSecretStore,
501 StateStore,
502 BuilderSlotMissingMarker,
503 OwnTransport,
504 >
505{
506 pub fn with_transport<Tr: DeRecTransport>(
509 self,
510 transport: Tr,
511 ) -> DeRecProtocolBuilder<
512 ChannelStore,
513 ShareStore,
514 SecretStore,
515 UserSecretStore,
516 StateStore,
517 BuilderSlotSetMarker<Tr>,
518 OwnTransport,
519 > {
520 DeRecProtocolBuilder {
521 secret_id: self.secret_id,
522 channel_store: self.channel_store,
523 share_store: self.share_store,
524 secret_store: self.secret_store,
525 user_secret_store: self.user_secret_store,
526 state_store: self.state_store,
527 transport: BuilderSlotSetMarker(transport),
528 own_transport: self.own_transport,
529 threshold: self.threshold,
530 keep_versions_count: self.keep_versions_count,
531 timeout_in_secs: self.timeout_in_secs,
532 communication_info: self.communication_info,
533 auto_respond_on_failure: self.auto_respond_on_failure,
534 unpair_ack: self.unpair_ack,
535 auto_reply_to: self.auto_reply_to,
536 auto_accept: self.auto_accept,
537 replica_id: self.replica_id,
538 parameter_range: self.parameter_range,
539 }
540 }
541}
542
543impl<ChannelStore, ShareStore, SecretStore, UserSecretStore, StateStore, Transport>
544 DeRecProtocolBuilder<
545 ChannelStore,
546 ShareStore,
547 SecretStore,
548 UserSecretStore,
549 StateStore,
550 Transport,
551 BuilderSlotMissingMarker,
552 >
553{
554 #[allow(clippy::type_complexity)]
565 pub fn with_own_transport(
566 self,
567 own_transport: impl crate::transport::IntoOwnTransport,
568 ) -> DeRecProtocolBuilder<
569 ChannelStore,
570 ShareStore,
571 SecretStore,
572 UserSecretStore,
573 StateStore,
574 Transport,
575 BuilderSlotSetMarker<
576 Result<crate::transport::TransportProtocol, crate::transport::TransportValidationError>,
577 >,
578 > {
579 let own_transport = own_transport.into_own_transport();
580 DeRecProtocolBuilder {
581 secret_id: self.secret_id,
582 channel_store: self.channel_store,
583 share_store: self.share_store,
584 secret_store: self.secret_store,
585 user_secret_store: self.user_secret_store,
586 state_store: self.state_store,
587 transport: self.transport,
588 own_transport: BuilderSlotSetMarker(own_transport),
589 threshold: self.threshold,
590 keep_versions_count: self.keep_versions_count,
591 timeout_in_secs: self.timeout_in_secs,
592 communication_info: self.communication_info,
593 auto_respond_on_failure: self.auto_respond_on_failure,
594 unpair_ack: self.unpair_ack,
595 auto_reply_to: self.auto_reply_to,
596 auto_accept: self.auto_accept,
597 replica_id: self.replica_id,
598 parameter_range: self.parameter_range,
599 }
600 }
601}
602
603impl<ChannelStore, ShareStore, SecretStore, UserSecretStore, Transport, OwnTransport>
604 DeRecProtocolBuilder<
605 ChannelStore,
606 ShareStore,
607 SecretStore,
608 UserSecretStore,
609 BuilderSlotMissingMarker,
610 Transport,
611 OwnTransport,
612 >
613{
614 pub fn with_state_store<St: DeRecStateStore>(
622 self,
623 store: St,
624 ) -> DeRecProtocolBuilder<
625 ChannelStore,
626 ShareStore,
627 SecretStore,
628 UserSecretStore,
629 BuilderSlotSetMarker<St>,
630 Transport,
631 OwnTransport,
632 > {
633 DeRecProtocolBuilder {
634 secret_id: self.secret_id,
635 channel_store: self.channel_store,
636 share_store: self.share_store,
637 secret_store: self.secret_store,
638 user_secret_store: self.user_secret_store,
639 state_store: BuilderSlotSetMarker(store),
640 transport: self.transport,
641 own_transport: self.own_transport,
642 threshold: self.threshold,
643 keep_versions_count: self.keep_versions_count,
644 timeout_in_secs: self.timeout_in_secs,
645 communication_info: self.communication_info,
646 auto_respond_on_failure: self.auto_respond_on_failure,
647 unpair_ack: self.unpair_ack,
648 auto_reply_to: self.auto_reply_to,
649 auto_accept: self.auto_accept,
650 replica_id: self.replica_id,
651 parameter_range: self.parameter_range,
652 }
653 }
654}
655
656impl<
657 Cs: DeRecChannelStore,
658 Sh: DeRecShareStore,
659 Ss: DeRecSecretStore,
660 Us: DeRecUserSecretStore,
661 St: DeRecStateStore,
662 Tr: DeRecTransport,
663>
664 DeRecProtocolBuilder<
665 BuilderSlotSetMarker<Cs>,
666 BuilderSlotSetMarker<Sh>,
667 BuilderSlotSetMarker<Ss>,
668 BuilderSlotSetMarker<Us>,
669 BuilderSlotSetMarker<St>,
670 BuilderSlotSetMarker<Tr>,
671 BuilderSlotSetMarker<
672 Result<crate::transport::TransportProtocol, crate::transport::TransportValidationError>,
673 >,
674 >
675{
676 pub fn build(self) -> crate::Result<DeRecProtocol<Cs, Sh, Ss, Us, St, Tr>> {
693 let own_transport: TransportProtocol = self.own_transport.0?.into();
694 let mut protocol = DeRecProtocol::new(
695 self.secret_id,
696 self.channel_store.0,
697 self.share_store.0,
698 self.secret_store.0,
699 self.user_secret_store.0,
700 self.state_store.0,
701 self.transport.0,
702 own_transport,
703 self.threshold,
704 self.keep_versions_count,
705 self.timeout_in_secs,
706 )?;
707 protocol.communication_info = self.communication_info;
708 protocol.auto_respond_on_failure = self.auto_respond_on_failure;
709 protocol.unpair_ack = self.unpair_ack;
710 protocol.auto_reply_to = self.auto_reply_to;
711 protocol.auto_accept = self.auto_accept;
712 protocol.replica_id = self.replica_id;
713 protocol.parameter_range = self.parameter_range;
714 Ok(protocol)
715 }
716}
717
718#[cfg(test)]
719mod tests {
720 use super::*;
721
722 #[test]
724 fn with_threshold_accepts_2() {
725 let b = DeRecProtocolBuilder::new(0).with_threshold(2);
726 assert_eq!(b.threshold, 2);
727 }
728
729 #[test]
732 fn with_auto_accept_round_trips_policy() {
733 let policy = crate::protocol::AutoAcceptPolicy {
734 store_share: true,
735 verify_share: true,
736 ..Default::default()
737 };
738 let b = DeRecProtocolBuilder::new(0).with_auto_accept(policy);
739 assert_eq!(b.auto_accept, policy);
740 }
741
742 #[test]
744 fn auto_accept_defaults_to_empty_policy() {
745 let b = DeRecProtocolBuilder::new(0);
746 assert_eq!(b.auto_accept, crate::protocol::AutoAcceptPolicy::default());
747 }
748
749 #[test]
751 fn with_threshold_accepts_3_and_above() {
752 let b3 = DeRecProtocolBuilder::new(0).with_threshold(3);
753 assert_eq!(b3.threshold, 3);
754 let b_high = DeRecProtocolBuilder::new(0).with_threshold(100);
755 assert_eq!(b_high.threshold, 100);
756 }
757
758 #[test]
762 fn with_threshold_accepts_invalid_values_silently() {
763 let b0 = DeRecProtocolBuilder::new(0).with_threshold(0);
764 assert_eq!(b0.threshold, 0);
765 let b1 = DeRecProtocolBuilder::new(0).with_threshold(1);
766 assert_eq!(b1.threshold, 1);
767 }
768
769 #[test]
774 fn protocol_new_rejects_zero_threshold() {
775 use crate::protocol::traits::{
776 ChannelStoreFuture, DeRecChannelStore, DeRecSecretStore, DeRecShareStore,
777 DeRecTransport, DeRecUserSecretStore, SecretStoreFuture, ShareStoreFuture,
778 TransportFuture,
779 };
780 use crate::protocol::types::{Channel, MissingPolicy, SecretKind, SecretValue, Share, UserSecrets};
781 use crate::types::ChannelId;
782 use derec_proto::TransportProtocol;
783
784 struct NoopChannelStore;
785 impl DeRecChannelStore for NoopChannelStore {
786 fn load(&self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, Option<Channel>> {
787 Box::pin(std::future::ready(Ok(None)))
788 }
789 fn save(&mut self, _: u64, _: Channel) -> ChannelStoreFuture<'_, ()> {
790 Box::pin(std::future::ready(Ok(())))
791 }
792 fn remove(&mut self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, bool> {
793 Box::pin(std::future::ready(Ok(false)))
794 }
795 fn channels(&self, _: u64) -> ChannelStoreFuture<'_, Vec<Channel>> {
796 Box::pin(std::future::ready(Ok(Vec::new())))
797 }
798 fn link_channel(
799 &mut self,
800 _: u64,
801 _: ChannelId,
802 _: ChannelId,
803 ) -> ChannelStoreFuture<'_, ()> {
804 Box::pin(std::future::ready(Ok(())))
805 }
806 fn linked_channels(
807 &self,
808 _: u64,
809 cid: ChannelId,
810 ) -> ChannelStoreFuture<'_, Vec<ChannelId>> {
811 Box::pin(std::future::ready(Ok(vec![cid])))
812 }
813 }
814
815 struct NoopShareStore;
816 impl DeRecShareStore for NoopShareStore {
817 fn load(
818 &self,
819 _: u64,
820 _: ChannelId,
821 _: &[u32],
822 ) -> ShareStoreFuture<'_, Vec<Share>> {
823 Box::pin(std::future::ready(Ok(Vec::new())))
824 }
825 fn load_many(
826 &self,
827 _: u64,
828 _: &[ChannelId],
829 _: &[u32],
830 ) -> ShareStoreFuture<'_, Vec<Share>> {
831 Box::pin(std::future::ready(Ok(Vec::new())))
832 }
833 fn load_all(
834 &self,
835 _: u64,
836 _: &[ChannelId],
837 ) -> ShareStoreFuture<'_, Vec<Share>> {
838 Box::pin(std::future::ready(Ok(Vec::new())))
839 }
840 fn latest_version(&self, _: u64) -> ShareStoreFuture<'_, Option<u32>> {
841 Box::pin(std::future::ready(Ok(None)))
842 }
843 fn save(&mut self, _: u64, _: ChannelId, _: Share) -> ShareStoreFuture<'_, ()> {
844 Box::pin(std::future::ready(Ok(())))
845 }
846 fn remove_channel(&mut self, _: u64, _: ChannelId) -> ShareStoreFuture<'_, ()> {
847 Box::pin(std::future::ready(Ok(())))
848 }
849 }
850
851 struct NoopSecretStore;
852 impl DeRecSecretStore for NoopSecretStore {
853 fn load(
854 &self,
855 _: u64,
856 _: ChannelId,
857 _: SecretKind,
858 ) -> SecretStoreFuture<'_, Option<SecretValue>> {
859 Box::pin(std::future::ready(Ok(None)))
860 }
861 fn load_many(
862 &self,
863 _: u64,
864 _: &[ChannelId],
865 _: SecretKind,
866 _: MissingPolicy,
867 ) -> SecretStoreFuture<'_, Vec<(ChannelId, SecretValue)>> {
868 Box::pin(std::future::ready(Ok(Vec::new())))
869 }
870 fn save(
871 &mut self,
872 _: u64,
873 _: ChannelId,
874 _: SecretValue,
875 ) -> SecretStoreFuture<'_, ()> {
876 Box::pin(std::future::ready(Ok(())))
877 }
878 fn remove(
879 &mut self,
880 _: u64,
881 _: ChannelId,
882 _: SecretKind,
883 ) -> SecretStoreFuture<'_, ()> {
884 Box::pin(std::future::ready(Ok(())))
885 }
886 }
887
888 struct NoopUserSecretStore;
889 impl DeRecUserSecretStore for NoopUserSecretStore {
890 fn load_latest(&self, _: u64) -> ShareStoreFuture<'_, Option<UserSecrets>> {
891 Box::pin(std::future::ready(Ok(None)))
892 }
893 fn save_latest(&mut self, _: u64, _: UserSecrets) -> ShareStoreFuture<'_, ()> {
894 Box::pin(std::future::ready(Ok(())))
895 }
896 fn remove(&mut self, _: u64) -> ShareStoreFuture<'_, ()> {
897 Box::pin(std::future::ready(Ok(())))
898 }
899 }
900
901 struct NoopTransport;
902 impl DeRecTransport for NoopTransport {
903 fn send(&self, _: &TransportProtocol, _: Vec<u8>) -> TransportFuture<'_> {
904 Box::pin(std::future::ready(Ok(())))
905 }
906 }
907
908 struct NoopStateStore;
909 impl crate::protocol::DeRecStateStore for NoopStateStore {
910 fn save(
911 &mut self,
912 _: u64,
913 _: crate::protocol::StateItem,
914 ) -> crate::protocol::StateStoreFuture<'_, ()> {
915 Box::pin(std::future::ready(Ok(())))
916 }
917 fn load(
918 &self,
919 _: u64,
920 _: crate::protocol::StateKey,
921 ) -> crate::protocol::StateStoreFuture<'_, Option<crate::protocol::StateItem>> {
922 Box::pin(std::future::ready(Ok(None)))
923 }
924 fn remove(
925 &mut self,
926 _: u64,
927 _: crate::protocol::StateKey,
928 ) -> crate::protocol::StateStoreFuture<'_, bool> {
929 Box::pin(std::future::ready(Ok(false)))
930 }
931 fn load_all(
932 &self,
933 _: u64,
934 _: crate::protocol::StateKind,
935 ) -> crate::protocol::StateStoreFuture<'_, Vec<crate::protocol::StateItem>> {
936 Box::pin(std::future::ready(Ok(Vec::new())))
937 }
938 }
939
940 let result = DeRecProtocol::new(
943 0,
944 NoopChannelStore,
945 NoopShareStore,
946 NoopSecretStore,
947 NoopUserSecretStore,
948 NoopStateStore,
949 NoopTransport,
950 TransportProtocol {
951 uri: String::new(),
952 protocol: 0,
953 },
954 0, 3,
956 30,
957 );
958 assert!(matches!(result, Err(crate::Error::InvalidInput(_))));
959 }
960
961 #[test]
965 fn build_rejects_zero_threshold_via_invalid_input() {
966 use crate::protocol::traits::{
967 ChannelStoreFuture, DeRecChannelStore, DeRecSecretStore, DeRecShareStore,
968 DeRecTransport, DeRecUserSecretStore, SecretStoreFuture, ShareStoreFuture,
969 TransportFuture,
970 };
971 use crate::protocol::types::{
972 Channel, MissingPolicy, SecretKind, SecretValue, Share, UserSecrets,
973 };
974 use crate::types::ChannelId;
975 use derec_proto::TransportProtocol;
976
977 struct NoopChannelStore;
978 impl DeRecChannelStore for NoopChannelStore {
979 fn load(&self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, Option<Channel>> {
980 Box::pin(std::future::ready(Ok(None)))
981 }
982 fn save(&mut self, _: u64, _: Channel) -> ChannelStoreFuture<'_, ()> {
983 Box::pin(std::future::ready(Ok(())))
984 }
985 fn remove(&mut self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, bool> {
986 Box::pin(std::future::ready(Ok(false)))
987 }
988 fn channels(&self, _: u64) -> ChannelStoreFuture<'_, Vec<Channel>> {
989 Box::pin(std::future::ready(Ok(Vec::new())))
990 }
991 fn link_channel(
992 &mut self,
993 _: u64,
994 _: ChannelId,
995 _: ChannelId,
996 ) -> ChannelStoreFuture<'_, ()> {
997 Box::pin(std::future::ready(Ok(())))
998 }
999 fn linked_channels(
1000 &self,
1001 _: u64,
1002 cid: ChannelId,
1003 ) -> ChannelStoreFuture<'_, Vec<ChannelId>> {
1004 Box::pin(std::future::ready(Ok(vec![cid])))
1005 }
1006 }
1007 struct NoopShareStore;
1008 impl DeRecShareStore for NoopShareStore {
1009 fn load(
1010 &self,
1011 _: u64,
1012 _: ChannelId,
1013 _: &[u32],
1014 ) -> ShareStoreFuture<'_, Vec<Share>> {
1015 Box::pin(std::future::ready(Ok(Vec::new())))
1016 }
1017 fn load_many(
1018 &self,
1019 _: u64,
1020 _: &[ChannelId],
1021 _: &[u32],
1022 ) -> ShareStoreFuture<'_, Vec<Share>> {
1023 Box::pin(std::future::ready(Ok(Vec::new())))
1024 }
1025 fn load_all(
1026 &self,
1027 _: u64,
1028 _: &[ChannelId],
1029 ) -> ShareStoreFuture<'_, Vec<Share>> {
1030 Box::pin(std::future::ready(Ok(Vec::new())))
1031 }
1032 fn latest_version(&self, _: u64) -> ShareStoreFuture<'_, Option<u32>> {
1033 Box::pin(std::future::ready(Ok(None)))
1034 }
1035 fn save(&mut self, _: u64, _: ChannelId, _: Share) -> ShareStoreFuture<'_, ()> {
1036 Box::pin(std::future::ready(Ok(())))
1037 }
1038 fn remove_channel(&mut self, _: u64, _: ChannelId) -> ShareStoreFuture<'_, ()> {
1039 Box::pin(std::future::ready(Ok(())))
1040 }
1041 }
1042 struct NoopSecretStore;
1043 impl DeRecSecretStore for NoopSecretStore {
1044 fn load(
1045 &self,
1046 _: u64,
1047 _: ChannelId,
1048 _: SecretKind,
1049 ) -> SecretStoreFuture<'_, Option<SecretValue>> {
1050 Box::pin(std::future::ready(Ok(None)))
1051 }
1052 fn load_many(
1053 &self,
1054 _: u64,
1055 _: &[ChannelId],
1056 _: SecretKind,
1057 _: MissingPolicy,
1058 ) -> SecretStoreFuture<'_, Vec<(ChannelId, SecretValue)>> {
1059 Box::pin(std::future::ready(Ok(Vec::new())))
1060 }
1061 fn save(
1062 &mut self,
1063 _: u64,
1064 _: ChannelId,
1065 _: SecretValue,
1066 ) -> SecretStoreFuture<'_, ()> {
1067 Box::pin(std::future::ready(Ok(())))
1068 }
1069 fn remove(
1070 &mut self,
1071 _: u64,
1072 _: ChannelId,
1073 _: SecretKind,
1074 ) -> SecretStoreFuture<'_, ()> {
1075 Box::pin(std::future::ready(Ok(())))
1076 }
1077 }
1078 struct NoopUserSecretStore;
1079 impl DeRecUserSecretStore for NoopUserSecretStore {
1080 fn load_latest(&self, _: u64) -> ShareStoreFuture<'_, Option<UserSecrets>> {
1081 Box::pin(std::future::ready(Ok(None)))
1082 }
1083 fn save_latest(&mut self, _: u64, _: UserSecrets) -> ShareStoreFuture<'_, ()> {
1084 Box::pin(std::future::ready(Ok(())))
1085 }
1086 fn remove(&mut self, _: u64) -> ShareStoreFuture<'_, ()> {
1087 Box::pin(std::future::ready(Ok(())))
1088 }
1089 }
1090 struct NoopTransport;
1091 impl DeRecTransport for NoopTransport {
1092 fn send(&self, _: &TransportProtocol, _: Vec<u8>) -> TransportFuture<'_> {
1093 Box::pin(std::future::ready(Ok(())))
1094 }
1095 }
1096
1097 struct NoopStateStore;
1098 impl crate::protocol::DeRecStateStore for NoopStateStore {
1099 fn save(
1100 &mut self,
1101 _: u64,
1102 _: crate::protocol::StateItem,
1103 ) -> crate::protocol::StateStoreFuture<'_, ()> {
1104 Box::pin(std::future::ready(Ok(())))
1105 }
1106 fn load(
1107 &self,
1108 _: u64,
1109 _: crate::protocol::StateKey,
1110 ) -> crate::protocol::StateStoreFuture<'_, Option<crate::protocol::StateItem>> {
1111 Box::pin(std::future::ready(Ok(None)))
1112 }
1113 fn remove(
1114 &mut self,
1115 _: u64,
1116 _: crate::protocol::StateKey,
1117 ) -> crate::protocol::StateStoreFuture<'_, bool> {
1118 Box::pin(std::future::ready(Ok(false)))
1119 }
1120 fn load_all(
1121 &self,
1122 _: u64,
1123 _: crate::protocol::StateKind,
1124 ) -> crate::protocol::StateStoreFuture<'_, Vec<crate::protocol::StateItem>> {
1125 Box::pin(std::future::ready(Ok(Vec::new())))
1126 }
1127 }
1128
1129 let result = DeRecProtocolBuilder::new(0)
1130 .with_channel_store(NoopChannelStore)
1131 .with_share_store(NoopShareStore)
1132 .with_secret_store(NoopSecretStore)
1133 .with_user_secret_store(NoopUserSecretStore)
1134 .with_transport(NoopTransport)
1135 .with_state_store(NoopStateStore)
1136 .with_own_transport("https://owner.example/derec")
1137 .with_threshold(1)
1138 .build();
1139 assert!(matches!(result, Err(crate::Error::InvalidInput(_))));
1140 }
1141
1142 #[test]
1146 fn build_rejects_malformed_own_transport_via_transport_error() {
1147 use crate::protocol::traits::{
1148 ChannelStoreFuture, DeRecChannelStore, DeRecSecretStore, DeRecShareStore,
1149 DeRecTransport, DeRecUserSecretStore, SecretStoreFuture, ShareStoreFuture,
1150 TransportFuture,
1151 };
1152 use crate::protocol::types::{
1153 Channel, MissingPolicy, SecretKind, SecretValue, Share, UserSecrets,
1154 };
1155 use crate::types::ChannelId;
1156 use derec_proto::TransportProtocol;
1157
1158 struct NoopChannelStore;
1159 impl DeRecChannelStore for NoopChannelStore {
1160 fn load(&self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, Option<Channel>> {
1161 Box::pin(std::future::ready(Ok(None)))
1162 }
1163 fn save(&mut self, _: u64, _: Channel) -> ChannelStoreFuture<'_, ()> {
1164 Box::pin(std::future::ready(Ok(())))
1165 }
1166 fn remove(&mut self, _: u64, _: ChannelId) -> ChannelStoreFuture<'_, bool> {
1167 Box::pin(std::future::ready(Ok(false)))
1168 }
1169 fn channels(&self, _: u64) -> ChannelStoreFuture<'_, Vec<Channel>> {
1170 Box::pin(std::future::ready(Ok(Vec::new())))
1171 }
1172 fn link_channel(
1173 &mut self,
1174 _: u64,
1175 _: ChannelId,
1176 _: ChannelId,
1177 ) -> ChannelStoreFuture<'_, ()> {
1178 Box::pin(std::future::ready(Ok(())))
1179 }
1180 fn linked_channels(
1181 &self,
1182 _: u64,
1183 cid: ChannelId,
1184 ) -> ChannelStoreFuture<'_, Vec<ChannelId>> {
1185 Box::pin(std::future::ready(Ok(vec![cid])))
1186 }
1187 }
1188 struct NoopShareStore;
1189 impl DeRecShareStore for NoopShareStore {
1190 fn load(
1191 &self,
1192 _: u64,
1193 _: ChannelId,
1194 _: &[u32],
1195 ) -> ShareStoreFuture<'_, Vec<Share>> {
1196 Box::pin(std::future::ready(Ok(Vec::new())))
1197 }
1198 fn load_many(
1199 &self,
1200 _: u64,
1201 _: &[ChannelId],
1202 _: &[u32],
1203 ) -> ShareStoreFuture<'_, Vec<Share>> {
1204 Box::pin(std::future::ready(Ok(Vec::new())))
1205 }
1206 fn load_all(
1207 &self,
1208 _: u64,
1209 _: &[ChannelId],
1210 ) -> ShareStoreFuture<'_, Vec<Share>> {
1211 Box::pin(std::future::ready(Ok(Vec::new())))
1212 }
1213 fn latest_version(&self, _: u64) -> ShareStoreFuture<'_, Option<u32>> {
1214 Box::pin(std::future::ready(Ok(None)))
1215 }
1216 fn save(&mut self, _: u64, _: ChannelId, _: Share) -> ShareStoreFuture<'_, ()> {
1217 Box::pin(std::future::ready(Ok(())))
1218 }
1219 fn remove_channel(&mut self, _: u64, _: ChannelId) -> ShareStoreFuture<'_, ()> {
1220 Box::pin(std::future::ready(Ok(())))
1221 }
1222 }
1223 struct NoopSecretStore;
1224 impl DeRecSecretStore for NoopSecretStore {
1225 fn load(
1226 &self,
1227 _: u64,
1228 _: ChannelId,
1229 _: SecretKind,
1230 ) -> SecretStoreFuture<'_, Option<SecretValue>> {
1231 Box::pin(std::future::ready(Ok(None)))
1232 }
1233 fn load_many(
1234 &self,
1235 _: u64,
1236 _: &[ChannelId],
1237 _: SecretKind,
1238 _: MissingPolicy,
1239 ) -> SecretStoreFuture<'_, Vec<(ChannelId, SecretValue)>> {
1240 Box::pin(std::future::ready(Ok(Vec::new())))
1241 }
1242 fn save(
1243 &mut self,
1244 _: u64,
1245 _: ChannelId,
1246 _: SecretValue,
1247 ) -> SecretStoreFuture<'_, ()> {
1248 Box::pin(std::future::ready(Ok(())))
1249 }
1250 fn remove(
1251 &mut self,
1252 _: u64,
1253 _: ChannelId,
1254 _: SecretKind,
1255 ) -> SecretStoreFuture<'_, ()> {
1256 Box::pin(std::future::ready(Ok(())))
1257 }
1258 }
1259 struct NoopUserSecretStore;
1260 impl DeRecUserSecretStore for NoopUserSecretStore {
1261 fn load_latest(&self, _: u64) -> ShareStoreFuture<'_, Option<UserSecrets>> {
1262 Box::pin(std::future::ready(Ok(None)))
1263 }
1264 fn save_latest(&mut self, _: u64, _: UserSecrets) -> ShareStoreFuture<'_, ()> {
1265 Box::pin(std::future::ready(Ok(())))
1266 }
1267 fn remove(&mut self, _: u64) -> ShareStoreFuture<'_, ()> {
1268 Box::pin(std::future::ready(Ok(())))
1269 }
1270 }
1271 struct NoopTransport;
1272 impl DeRecTransport for NoopTransport {
1273 fn send(&self, _: &TransportProtocol, _: Vec<u8>) -> TransportFuture<'_> {
1274 Box::pin(std::future::ready(Ok(())))
1275 }
1276 }
1277
1278 struct NoopStateStore;
1279 impl crate::protocol::DeRecStateStore for NoopStateStore {
1280 fn save(
1281 &mut self,
1282 _: u64,
1283 _: crate::protocol::StateItem,
1284 ) -> crate::protocol::StateStoreFuture<'_, ()> {
1285 Box::pin(std::future::ready(Ok(())))
1286 }
1287 fn load(
1288 &self,
1289 _: u64,
1290 _: crate::protocol::StateKey,
1291 ) -> crate::protocol::StateStoreFuture<'_, Option<crate::protocol::StateItem>> {
1292 Box::pin(std::future::ready(Ok(None)))
1293 }
1294 fn remove(
1295 &mut self,
1296 _: u64,
1297 _: crate::protocol::StateKey,
1298 ) -> crate::protocol::StateStoreFuture<'_, bool> {
1299 Box::pin(std::future::ready(Ok(false)))
1300 }
1301 fn load_all(
1302 &self,
1303 _: u64,
1304 _: crate::protocol::StateKind,
1305 ) -> crate::protocol::StateStoreFuture<'_, Vec<crate::protocol::StateItem>> {
1306 Box::pin(std::future::ready(Ok(Vec::new())))
1307 }
1308 }
1309
1310 let result = DeRecProtocolBuilder::new(0)
1311 .with_channel_store(NoopChannelStore)
1312 .with_share_store(NoopShareStore)
1313 .with_secret_store(NoopSecretStore)
1314 .with_user_secret_store(NoopUserSecretStore)
1315 .with_transport(NoopTransport)
1316 .with_state_store(NoopStateStore)
1317 .with_own_transport("ws://owner.example/derec")
1318 .with_threshold(2)
1319 .build();
1320 assert!(matches!(
1321 result,
1322 Err(crate::Error::Transport(
1323 crate::transport::TransportValidationError::SchemeMismatch { .. }
1324 ))
1325 ));
1326 }
1327}