1#![warn(missing_docs)]
3use std::sync::Arc;
4use std::sync::Mutex;
5use std::sync::MutexGuard;
6
7use async_trait::async_trait;
8use serde::Deserialize;
9use serde::Serialize;
10
11use super::did::BiasId;
12use super::entry::Entry;
13use super::entry::EntryLookupEvidence;
14use super::entry::EntryLookupKey;
15use super::entry::EntryOperation;
16use super::entry::PlacedEntry;
17use super::entry::PlacementMiss;
18use super::finger::DEFAULT_FINGER_TABLE_SIZE;
19use super::successor::SuccessorSeq;
20use super::topology;
21use super::topology::FindSuccessorStep;
22use super::topology::TopologyAction;
23use super::topology::TopologyEvent;
24use super::topology::TopologyState;
25use super::types::Chord;
26use super::types::ChordStorage;
27use super::types::ChordStorageCache;
28use super::types::CorrectChord;
29use super::FingerTable;
30use crate::dht::Did;
31use crate::dht::LiveDid;
32use crate::dht::SuccessorReader;
33use crate::dht::SuccessorWriter;
34use crate::error::Error;
35use crate::error::Result;
36use crate::storage::KvStorageInterface;
37use crate::storage::MemStorage;
38
39#[cfg(feature = "wasm")]
42pub type EntryStorage = Box<dyn KvStorageInterface<Entry>>;
43
44#[cfg(not(feature = "wasm"))]
47pub type EntryStorage = Box<dyn KvStorageInterface<Entry> + Send + Sync>;
48
49pub struct PeerRing {
55 pub did: Did,
57 pub finger: Arc<Mutex<FingerTable>>,
59 pub successor_seq: SuccessorSeq,
63 pub predecessor: Arc<Mutex<Option<Did>>>,
65 pub storage: EntryStorage,
67 pub cache: EntryStorage,
69}
70
71type Target = Did;
73
74#[derive(Clone, Debug, PartialEq)]
77pub enum PeerRingAction {
78 None,
80 SomeEntry(EntryLookupEvidence),
82 EntryMisses(Vec<PlacementMiss>),
84 Some(Did),
86 RemoteAction(Target, RemoteAction),
88 MultiActions(Vec<PeerRingAction>),
90}
91
92#[derive(Clone, Debug, PartialEq, Eq)]
99pub enum RemoteAction {
100 FindSuccessor(Did),
102 FindEntry(EntryLookupKey),
104 FindEntryForOperate(EntryOperation),
106 Notify(Did),
111 SyncEntriesWithSuccessor(Vec<PlacedEntry>),
117
118 FindSuccessorForConnect(Did),
120
121 FindSuccessorForFix {
123 did: Did,
125 index: usize,
127 },
128
129 QueryForSuccessorList,
131 QueryForSuccessorListAndPred,
133 TryConnect,
135}
136
137#[derive(Debug, PartialEq, Eq, Deserialize, Serialize, Clone)]
139pub struct TopoInfo {
140 pub successors: Vec<Did>,
142 pub predecessor: Option<Did>,
144}
145
146impl TryFrom<&PeerRing> for TopoInfo {
147 type Error = Error;
148 fn try_from(dht: &PeerRing) -> Result<TopoInfo> {
149 let successors = dht.successors().list()?;
150 let predecessor = *dht.lock_predecessor()?;
151 Ok(TopoInfo {
152 successors,
153 predecessor,
154 })
155 }
156}
157
158impl PeerRingAction {
159 pub fn is_none(&self) -> bool {
161 if let Self::None = self {
162 return true;
163 }
164 false
165 }
166
167 pub fn is_some(&self) -> bool {
169 if let Self::Some(_) = self {
170 return true;
171 }
172 false
173 }
174
175 pub fn is_some_entry(&self) -> bool {
177 if let Self::SomeEntry(_) = self {
178 return true;
179 }
180 false
181 }
182
183 pub fn is_remote(&self) -> bool {
185 if let Self::RemoteAction(..) = self {
186 return true;
187 }
188 false
189 }
190
191 pub fn is_multi(&self) -> bool {
193 if let Self::MultiActions(..) = self {
194 return true;
195 }
196 false
197 }
198}
199
200impl From<Vec<PeerRingAction>> for PeerRingAction {
201 fn from(acts: Vec<PeerRingAction>) -> Self {
202 if !acts.is_empty() {
203 Self::MultiActions(acts)
204 } else {
205 Self::None
206 }
207 }
208}
209
210impl PeerRing {
211 pub fn new_with_storage(did: Did, succ_max: u8, storage: EntryStorage) -> Self {
213 Self::new_with_storage_and_finger_table_size(
214 did,
215 succ_max,
216 storage,
217 DEFAULT_FINGER_TABLE_SIZE,
218 )
219 }
220
221 pub fn new_with_storage_and_finger_table_size(
226 did: Did,
227 succ_max: u8,
228 storage: EntryStorage,
229 finger_table_size: usize,
230 ) -> Self {
231 Self {
232 successor_seq: SuccessorSeq::new(did, succ_max),
233 predecessor: Arc::new(Mutex::new(None)),
234 finger: Arc::new(Mutex::new(FingerTable::new(did, finger_table_size))),
235 storage,
236 cache: Box::new(MemStorage::new()),
237 did,
238 }
239 }
240
241 #[deprecated]
243 pub fn lock_successor(&self) -> Result<SuccessorSeq> {
244 Ok(self.successor_seq.clone())
245 }
246
247 pub fn successors(&self) -> SuccessorSeq {
249 self.successor_seq.clone()
250 }
251
252 pub fn lock_finger(&self) -> Result<MutexGuard<FingerTable>> {
254 self.finger.lock().map_err(|_| Error::DHTSyncLockError)
255 }
256
257 pub fn lock_predecessor(&self) -> Result<MutexGuard<Option<Did>>> {
259 self.predecessor.lock().map_err(|_| Error::DHTSyncLockError)
260 }
261
262 pub fn remove(&self, did: Did) -> Result<()> {
266 let next = topology::step(
267 &self.topology_state()?,
268 TopologyEvent::Remove { peer: did },
269 self.successors().capacity(),
270 );
271 self.interpret_topology_state(&next.state)
272 }
273
274 pub fn bias(&self, did: Did) -> BiasId {
276 BiasId::new(self.did, did)
277 }
278
279 fn topology_state(&self) -> Result<TopologyState> {
280 let finger = self.lock_finger()?;
281 Ok(TopologyState::new(
282 self.did,
283 self.successors().list()?,
284 *self.lock_predecessor()?,
285 finger.list().clone(),
286 finger.fix_finger_index(),
287 ))
288 }
289
290 fn interpret_topology_state(&self, next: &TopologyState) -> Result<()> {
291 let successors = self.successors();
292 for did in successors.list()? {
293 successors.remove(did)?;
294 }
295 successors.extend(&next.successors)?;
296 *self.lock_predecessor()? = next.predecessor;
297 self.lock_finger()?
298 .replace_state(&next.fingers, next.fix_finger_index);
299 Ok(())
300 }
301
302 fn topology_action(&self, action: TopologyAction) -> PeerRingAction {
303 match action {
304 TopologyAction::FindSuccessorForConnect { next, did } => {
305 PeerRingAction::RemoteAction(next, RemoteAction::FindSuccessorForConnect(did))
306 }
307 TopologyAction::FindSuccessorForFix { next, did, index } => {
308 PeerRingAction::RemoteAction(next, RemoteAction::FindSuccessorForFix { did, index })
309 }
310 TopologyAction::QuerySuccessorList(did) => {
311 PeerRingAction::RemoteAction(did, RemoteAction::QueryForSuccessorList)
312 }
313 TopologyAction::Notify(did) => {
314 PeerRingAction::RemoteAction(did, RemoteAction::Notify(self.did))
315 }
316 }
317 }
318
319 fn topology_leaf_actions(&self, actions: Vec<TopologyAction>) -> PeerRingAction {
320 let mut actions = actions
321 .into_iter()
322 .map(|action| self.topology_action(action))
323 .collect::<Vec<_>>();
324 match actions.len() {
325 0 => PeerRingAction::None,
326 1 => actions.pop().unwrap_or(PeerRingAction::None),
327 _ => PeerRingAction::MultiActions(actions),
328 }
329 }
330
331 fn topology_multi_actions(&self, actions: Vec<TopologyAction>) -> PeerRingAction {
332 PeerRingAction::MultiActions(
333 actions
334 .into_iter()
335 .map(|action| self.topology_action(action))
336 .collect(),
337 )
338 }
339
340 pub(crate) fn apply_fixed_finger(&self, index: usize, successor: Did) -> Result<()> {
342 let next = topology::step(
343 &self.topology_state()?,
344 TopologyEvent::ApplyFinger { index, successor },
345 self.successors().capacity(),
346 );
347 self.interpret_topology_state(&next.state)
348 }
349
350 pub(crate) async fn join_storage_entry(&self, key: Did, incoming: Entry) -> Result<Entry> {
356 let incoming = incoming.try_into_storage_entry()?;
357 let stored = if let Some(local) = self.storage.get(&key.to_string()).await? {
358 local.join(incoming)?
359 } else {
360 incoming
361 }
362 .try_into_storage_entry()?;
363 self.storage.put(&key.to_string(), &stored).await?;
364 Ok(stored)
365 }
366}
367
368impl Chord<PeerRingAction> for PeerRing {
369 fn join(&self, did: Did) -> Result<PeerRingAction> {
377 let next = topology::step(
378 &self.topology_state()?,
379 TopologyEvent::Join { peer: did },
380 self.successors().capacity(),
381 );
382 self.interpret_topology_state(&next.state)?;
383 Ok(self.topology_leaf_actions(next.actions))
384 }
385
386 fn find_successor(&self, did: Did) -> Result<PeerRingAction> {
389 let state = self.topology_state()?;
390 let succ = match topology::find_successor(&state, did) {
391 FindSuccessorStep::Local(successor) => {
392 Ok(PeerRingAction::Some(successor))
397 }
398 FindSuccessorStep::Remote { next, did } => Ok(PeerRingAction::RemoteAction(
399 next,
400 RemoteAction::FindSuccessor(did),
401 )),
402 };
403
404 tracing::debug!(
405 "find_successor: self: {}, did: {}, successor: {:?}, result: {:?}",
406 self.did,
407 did,
408 state.successors,
409 succ
410 );
411
412 succ
413 }
414
415 fn notify(&self, did: Did) -> Result<Did> {
420 let next = topology::step(
421 &self.topology_state()?,
422 TopologyEvent::Notify { predecessor: did },
423 self.successors().capacity(),
424 );
425 let Some(predecessor) = next.state.predecessor else {
426 return Err(Error::PeerRingInvalidAction);
427 };
428 self.interpret_topology_state(&next.state)?;
429 Ok(predecessor)
430 }
431
432 fn fix_fingers(&self) -> Result<PeerRingAction> {
436 let next = topology::step(
437 &self.topology_state()?,
438 TopologyEvent::FixFinger,
439 self.successors().capacity(),
440 );
441 self.interpret_topology_state(&next.state)?;
442 Ok(self.topology_leaf_actions(next.actions))
443 }
444}
445
446#[cfg_attr(feature = "wasm", async_trait(?Send))]
447#[cfg_attr(not(feature = "wasm"), async_trait)]
448impl<const REDUNDANT: u16> ChordStorage<PeerRingAction, REDUNDANT> for PeerRing {
449 async fn entry_lookup(&self, entry_key: Did) -> Result<PeerRingAction> {
454 let mut ret = vec![];
455 let mut misses = vec![];
456 for placement_key in entry_key.rotate_affine(REDUNDANT)? {
463 let query = EntryLookupKey::new(entry_key, placement_key);
464 let act = match self.find_successor(placement_key) {
465 Ok(PeerRingAction::Some(succ)) => {
467 match self.storage.get(&placement_key.to_string()).await {
468 Ok(Some(v)) => {
469 let observed_misses = std::mem::take(&mut misses);
470 Ok(PeerRingAction::SomeEntry(EntryLookupEvidence::new(
471 v,
472 observed_misses,
473 )))
474 }
475 Ok(None) => {
476 tracing::debug!(
477 "Cannot find entry in local storage, try to query from successor"
478 );
479 if succ == self.did {
482 misses.push(PlacementMiss::new(placement_key, succ));
483 Ok(PeerRingAction::None)
484 } else {
485 Ok(PeerRingAction::RemoteAction(
486 succ,
487 RemoteAction::FindEntry(query),
488 ))
489 }
490 }
491 Err(e) => Err(e),
492 }
493 }
494 Ok(PeerRingAction::RemoteAction(n, RemoteAction::FindSuccessor(id))) => {
497 Ok(PeerRingAction::RemoteAction(
498 n,
499 RemoteAction::FindEntry(EntryLookupKey::new(entry_key, id)),
500 ))
501 }
502 Ok(a) => Err(Error::unexpected_peer_ring_action(a)),
503 Err(e) => Err(e),
504 }?;
505 if act.is_remote() {
506 ret.push(act);
507 } else {
508 if act.is_some_entry() {
510 return Ok(act);
511 }
512 }
513 }
514 if !misses.is_empty() {
515 ret.push(PeerRingAction::EntryMisses(misses));
516 }
517 Ok(ret.into())
518 }
519
520 async fn entry_operate(&self, op: EntryOperation) -> Result<PeerRingAction> {
524 let op = op.stamped(self.did)?;
525 let entry_key = op.did()?;
526 let mut ret = vec![];
527 for entry_key in entry_key.rotate_affine(REDUNDANT)? {
536 let act = match self.find_successor(entry_key) {
537 Ok(PeerRingAction::Some(_)) => {
539 let this = match self.storage.get(&entry_key.to_string()).await? {
540 Some(this) => this,
541 None => op.clone().gen_default_entry()?,
542 };
543 let entry = this.operate(op.clone(), self.did)?;
544 self.join_storage_entry(entry_key, entry).await?;
545 Ok(PeerRingAction::None)
546 }
547 Ok(PeerRingAction::RemoteAction(n, RemoteAction::FindSuccessor(_))) => Ok(
550 PeerRingAction::RemoteAction(n, RemoteAction::FindEntryForOperate(op.clone())),
551 ),
552 Ok(a) => Err(Error::unexpected_peer_ring_action(a)),
553 Err(e) => Err(e),
554 }?;
555 if act.is_remote() {
556 ret.push(act);
557 }
558 }
559 Ok(ret.into())
560 }
561}
562
563mod storage_repair;
564mod storage_sync;
565
566#[cfg_attr(feature = "wasm", async_trait(?Send))]
567#[cfg_attr(not(feature = "wasm"), async_trait)]
568impl ChordStorageCache<PeerRingAction> for PeerRing {
569 async fn local_cache_put(&self, entry: Entry) -> Result<()> {
571 self.cache.put(&entry.did.to_string(), &entry).await
572 }
573
574 async fn local_cache_get(&self, entry_key: Did) -> Result<Option<Entry>> {
576 self.cache.get(&entry_key.to_string()).await
577 }
578}
579
580#[cfg_attr(feature = "wasm", async_trait(?Send))]
581#[cfg_attr(not(feature = "wasm"), async_trait)]
582impl CorrectChord<PeerRingAction> for PeerRing {
583 async fn update_successor(&self, did: impl LiveDid) -> Result<PeerRingAction> {
585 let is_live = did.live().await;
586 if !is_live {
587 return Ok(PeerRingAction::RemoteAction(
588 did.into(),
589 RemoteAction::TryConnect,
590 ));
591 }
592 let next = topology::step(
593 &self.topology_state()?,
594 TopologyEvent::UpdateSuccessor {
595 successor: did.into(),
596 },
597 self.successors().capacity(),
598 );
599 self.interpret_topology_state(&next.state)?;
600 Ok(self.topology_leaf_actions(next.actions))
601 }
602
603 async fn extend_successor(&self, dids: &[impl LiveDid]) -> Result<PeerRingAction> {
604 let mut ret: Vec<PeerRingAction> = vec![];
605 for did in dids {
606 if let PeerRingAction::RemoteAction(r, act) = self.update_successor(did.clone()).await?
607 {
608 ret.push(PeerRingAction::RemoteAction(r, act))
609 }
610 }
611 Ok(PeerRingAction::MultiActions(ret))
612 }
613
614 async fn join_then_sync(&self, did: impl LiveDid) -> Result<PeerRingAction> {
618 let is_live = did.live().await;
619 if !is_live {
620 return Ok(PeerRingAction::None);
621 }
622 let mut ret: Vec<PeerRingAction> = vec![];
623 let succ_act = self.update_successor(did.clone()).await?;
624 if succ_act.is_remote() {
625 ret.push(succ_act)
626 }
627 let join_act = self.join(did.into())?;
628 ret.push(join_act);
629
630 Ok(PeerRingAction::MultiActions(ret))
631 }
632
633 fn rectify(&self, pred: Did) -> Result<()> {
639 let next = topology::step(
647 &self.topology_state()?,
648 TopologyEvent::Notify { predecessor: pred },
649 self.successors().capacity(),
650 );
651 self.interpret_topology_state(&next.state)
652 }
653
654 fn pre_stabilize(&self) -> Result<PeerRingAction> {
658 let successor = self.successors();
659 if successor.is_empty()? {
660 return Ok(PeerRingAction::None);
661 }
662 let head = successor.min()?;
663 Ok(PeerRingAction::RemoteAction(
664 head,
665 RemoteAction::QueryForSuccessorListAndPred,
666 ))
667 }
668
669 fn stabilize(&self, info: TopoInfo) -> Result<PeerRingAction> {
677 let next = topology::step(
678 &self.topology_state()?,
679 TopologyEvent::Stabilize {
680 successors: info.successors,
681 predecessor: info.predecessor,
682 },
683 self.successors().capacity(),
684 );
685 self.interpret_topology_state(&next.state)?;
686 Ok(self.topology_multi_actions(next.actions))
687 }
688
689 fn topo_info(&self) -> Result<TopoInfo> {
691 self.try_into()
692 }
693}
694
695#[cfg(all(not(feature = "wasm"), test))]
696mod storage_tests;
697
698#[cfg(all(not(feature = "wasm"), test))]
699mod tests {
700 use std::str::FromStr;
702
703 use num_bigint::BigUint;
704
705 use super::*;
706 use crate::ecc::SecretKey;
707 use crate::tests::default::gen_sorted_dht;
708
709 #[tokio::test]
710 async fn test_chord_finger() -> Result<()> {
711 let a = Did::from_str("0x00E807fcc88dD319270493fB2e822e388Fe36ab0").unwrap();
713 let b = Did::from_str("0x119999cf1046e68e36E1aA2E0E07105eDDD1f08E").unwrap();
714 let c = Did::from_str("0xccffee254729296a45a3885639AC7E10F9d54979").unwrap();
715 let d = Did::from_str("0xffffee254729296a45a3885639AC7E10F9d54979").unwrap();
716
717 let mut seq = vec![a, b, c, d];
728 seq.sort();
729 assert_eq!(seq, vec![a, b, c, d]);
730
731 let node_a = PeerRing::new_with_storage(a, 3, Box::new(MemStorage::new()));
733 assert!(node_a.successors().is_empty()?);
734 assert!(node_a.lock_finger()?.is_empty());
735
736 assert_eq!(node_a.join(a)?, PeerRingAction::None);
738 assert!(node_a.successors().is_empty()?);
739 assert!(node_a.lock_finger()?.is_empty());
740
741 let result = node_a.join(b)?;
744
745 assert_eq!(
748 result,
749 PeerRingAction::RemoteAction(b, RemoteAction::FindSuccessorForConnect(a))
750 );
751
752 assert!(BigUint::from(b) > BigUint::from(2u16).pow(156));
755 assert!(BigUint::from(b) < BigUint::from(2u16).pow(157));
756
757 let mut expected_finger_list = std::iter::repeat_n(Some(b), 157).collect::<Vec<_>>();
760 expected_finger_list.extend(std::iter::repeat_n(None, 3));
761 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
762
763 assert_eq!(node_a.successors().list()?, vec![b]);
765
766 node_a.join(b)?;
768 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
769 assert_eq!(node_a.successors().list()?, vec![b]);
770 node_a.join(b)?;
771 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
772 assert_eq!(node_a.successors().list()?, vec![b]);
773
774 let result = node_a.join(c)?;
777
778 assert_eq!(
781 result,
782 PeerRingAction::RemoteAction(c, RemoteAction::FindSuccessorForConnect(a))
783 );
784
785 assert!(BigUint::from(c) > BigUint::from(2u16).pow(159));
788 assert!(BigUint::from(c) < BigUint::from(2u16).pow(160));
789
790 let mut expected_finger_list = std::iter::repeat_n(Some(b), 157).collect::<Vec<_>>();
793 expected_finger_list.extend(std::iter::repeat_n(Some(c), 3));
794 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
795
796 assert_eq!(node_a.successors().list()?, vec![b, c]);
799
800 assert_eq!(
802 node_a.find_successor(d).unwrap(),
803 PeerRingAction::RemoteAction(c, RemoteAction::FindSuccessor(d))
804 );
805 assert_eq!(
807 node_a.find_successor(c).unwrap(),
808 PeerRingAction::RemoteAction(b, RemoteAction::FindSuccessor(c))
809 );
810
811 let node_a = PeerRing::new_with_storage(a, 3, Box::new(MemStorage::new()));
813
814 assert_eq!(
816 node_a.join(c)?,
817 PeerRingAction::RemoteAction(c, RemoteAction::FindSuccessorForConnect(a))
818 );
819 let expected_finger_list = std::iter::repeat_n(Some(c), 160).collect::<Vec<_>>();
820 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
821 assert_eq!(node_a.successors().list()?, vec![c]);
822
823 assert_eq!(
825 node_a.join(b)?,
826 PeerRingAction::RemoteAction(b, RemoteAction::FindSuccessorForConnect(a))
827 );
828 let mut expected_finger_list = std::iter::repeat_n(Some(b), 157).collect::<Vec<_>>();
829 expected_finger_list.extend(std::iter::repeat_n(Some(c), 3));
830 assert_eq!(node_a.lock_finger()?.list(), &expected_finger_list);
831 assert_eq!(node_a.successors().list()?, vec![b, c]);
832
833 let node_d = PeerRing::new_with_storage(d, 1, Box::new(MemStorage::new()));
835 assert_eq!(
836 node_d.join(a)?,
837 PeerRingAction::RemoteAction(a, RemoteAction::FindSuccessorForConnect(d))
838 );
839
840 assert!(d + Did::from(BigUint::from(2u16).pow(151)) < a);
843 assert!(d + Did::from(BigUint::from(2u16).pow(152)) > a);
844
845 let mut expected_finger_list = std::iter::repeat_n(Some(a), 152).collect::<Vec<_>>();
848 expected_finger_list.extend(std::iter::repeat_n(None, 8));
849 assert_eq!(node_d.lock_finger()?.list(), &expected_finger_list);
850
851 assert_eq!(node_d.successors().list()?, vec![a]);
853
854 assert_eq!(
856 node_d.join(b)?,
857 PeerRingAction::RemoteAction(b, RemoteAction::FindSuccessorForConnect(d))
858 );
859
860 assert!(d + Did::from(BigUint::from(2u16).pow(156)) < b);
863 assert!(d + Did::from(BigUint::from(2u16).pow(157)) > b);
864
865 let mut expected_finger_list = std::iter::repeat_n(Some(a), 152).collect::<Vec<_>>();
868 expected_finger_list.extend(std::iter::repeat_n(Some(b), 5));
869 expected_finger_list.extend(std::iter::repeat_n(None, 3));
870 assert_eq!(node_d.lock_finger()?.list(), &expected_finger_list);
871
872 assert_eq!(node_d.successors().list()?, vec![a]);
876
877 Ok(())
878 }
879
880 #[tokio::test]
881 async fn test_two_node_finger() -> Result<()> {
882 let mut key1 = SecretKey::random();
883 let mut key2 = SecretKey::random();
884 if key1.address() > key2.address() {
885 (key1, key2) = (key2, key1)
886 }
887 let did1: Did = key1.address().into();
888 let did2: Did = key2.address().into();
889 let node1 = PeerRing::new_with_storage(did1, 3, Box::new(MemStorage::new()));
890 let node2 = PeerRing::new_with_storage(did2, 3, Box::new(MemStorage::new()));
891
892 node1.join(did2)?;
893 node2.join(did1)?;
894 assert!(node1.successors().list()?.contains(&did2));
895 assert!(node2.successors().list()?.contains(&did1));
896
897 assert!(
898 node1.lock_finger()?.contains(Some(did2)),
899 "did1:{did1:?}; did2:{did2:?}"
900 );
901 assert!(
902 node2.lock_finger()?.contains(Some(did1)),
903 "did1:{did1:?}; did2:{did2:?}"
904 );
905
906 Ok(())
907 }
908
909 #[tokio::test]
910 async fn test_two_node_finger_failed_case() -> Result<()> {
911 let did1 = Did::from_str("0x051cf4f8d020cb910474bef3e17f153fface2b5f").unwrap();
912 let did2 = Did::from_str("0x54baa7dc9e28f41da5d71af8fa6f2a302be1c1bf").unwrap();
913 let max = Did::from(BigUint::from(2u16).pow(160) - 1u16);
914 let zero = Did::from(BigUint::from(2u16).pow(160));
915
916 let node1 = PeerRing::new_with_storage(did1, 3, Box::new(MemStorage::new()));
917 let node2 = PeerRing::new_with_storage(did2, 3, Box::new(MemStorage::new()));
918
919 node1.join(did2)?;
920 node2.join(did1)?;
921 assert!(node1.successors().list()?.contains(&did2));
922 assert!(node2.successors().list()?.contains(&did1));
923 let pos_159 = did2 + Did::from(BigUint::from(2u16).pow(159));
924 assert!(pos_159 > did2);
925 assert!(pos_159 < max, "{pos_159:?};{max:?}");
926 let pos_160 = did2 + zero;
927 assert_eq!(pos_160, did2);
928 assert!(pos_160 > did1);
929
930 assert!(
931 node1.lock_finger()?.contains(Some(did2)),
932 "did1:{did1:?}; did2:{did2:?}"
933 );
934 assert!(
935 node2.lock_finger()?.contains(Some(did1)),
936 "did2:{did2:?} dont contains did1:{did1:?}"
937 );
938
939 Ok(())
940 }
941
942 #[test]
943 fn test_correct_chord_stabilize_handles_empty_successor_info() -> Result<()> {
944 let did = Did::from_str("0x051cf4f8d020cb910474bef3e17f153fface2b5f").unwrap();
945 let node = PeerRing::new_with_storage(did, 3, Box::new(MemStorage::new()));
946
947 assert_eq!(
948 node.stabilize(TopoInfo {
949 successors: vec![],
950 predecessor: None,
951 })?,
952 PeerRingAction::MultiActions(vec![])
953 );
954
955 Ok(())
956 }
957
958 #[tokio::test]
960 async fn test_correct_chord_impl() -> Result<()> {
961 fn assert_successor(dht: &PeerRing, did: &Did) -> bool {
962 let succ_list = dht.successors();
963 succ_list.list().unwrap().contains(did)
964 }
965
966 fn check_is_mutual_successors(dht1: &PeerRing, dht2: &PeerRing) {
968 let succ_list_1 = dht1.successors();
969 let succ_list_2 = dht2.successors();
970 assert_eq!(succ_list_1.min().unwrap(), dht2.did);
971 assert_eq!(succ_list_2.min().unwrap(), dht1.did);
972 }
973
974 fn check_succ_is_including(dht: &PeerRing, dids: Vec<Did>) {
975 let succ_list = dht.successors();
976 for did in dids {
977 assert!(succ_list.list().unwrap().contains(&did));
978 }
979 }
980
981 let dhts = gen_sorted_dht(5);
982 let [n1, n2, n3, n4, n5] = dhts.as_slice() else {
983 panic!("wrong dhts length");
984 };
985 n1.join(n2.did).unwrap();
990 n2.join(n1.did).unwrap();
991 check_is_mutual_successors(n1, n2);
993 n1.join(n3.did).unwrap();
996 n1.join(n4.did).unwrap();
997 check_succ_is_including(n1, vec![n2.did, n3.did, n4.did]);
999
1000 n1.join(n5.did).unwrap();
1001 assert!(!assert_successor(n1, &n5.did));
1003
1004 #[allow(non_local_definitions)]
1005 #[cfg_attr(feature = "wasm", async_trait(?Send))]
1006 #[cfg_attr(not(feature = "wasm"), async_trait)]
1007 impl LiveDid for Did {
1008 async fn live(&self) -> bool {
1009 true
1010 }
1011 }
1012
1013 if let PeerRingAction::MultiActions(rets) = n5.join_then_sync(n1.did).await.unwrap() {
1014 for r in rets {
1015 if let PeerRingAction::RemoteAction(t, _) = r {
1016 assert_eq!(t, n1.did.clone())
1017 } else {
1018 panic!("wrong remote");
1019 }
1020 }
1021 } else {
1022 panic!("Wrong ret");
1023 }
1024 Ok(())
1025 }
1026}