From 797bd616c95871ad2965c55803e423f77151aa62 Mon Sep 17 00:00:00 2001 From: Marek Date: Wed, 1 Sep 2021 21:31:02 +0200 Subject: [PATCH 1/7] Decide if Zebra is at the chain tip --- zebrad/src/components/sync/status.rs | 24 +++++++++++++++++++--- zebrad/src/components/sync/status/tests.rs | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/zebrad/src/components/sync/status.rs b/zebrad/src/components/sync/status.rs index 64db08a65d2..f5b29ac4fb4 100644 --- a/zebrad/src/components/sync/status.rs +++ b/zebrad/src/components/sync/status.rs @@ -17,6 +17,13 @@ pub struct SyncStatus { } impl SyncStatus { + /// The threshold that determines if the synchronization is at the chain + /// tip. + /// + /// This is based on the fact that sync lengths are around 2-20 blocks long + /// once Zebra reaches the tip. + const MIN_DIST_FROM_TIP: usize = 20; + /// Create an instance of [`SyncStatus`]. /// /// The status is determined based on the latest counts of synchronized blocks, observed @@ -41,9 +48,20 @@ impl SyncStatus { /// Check if the synchronization is likely close to the chain tip. pub fn is_close_to_tip(&self) -> bool { - let _sync_lengths = self.latest_sync_length.borrow(); + let sync_lengths = self.latest_sync_length.borrow(); + + // Compute the sum of the `sync_lengths`. + // The sum is computed by saturating addition in order to avoid overflowing. + let sum = sync_lengths + .iter() + .fold(0usize, |sum, rhs| sum.saturating_add(*rhs)); + + // Compute the average sync length. + // This value effectively represents a simple moving average. + let avg = sum / sync_lengths.len(); - // TODO: Determine if the synchronization is actually close to the tip (#2592). - true + // The synchronization process is close to the chain tip once the + // average sync length falls below the threshold. + avg < Self::MIN_DIST_FROM_TIP } } diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index 203b6798751..3b77fb75775 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -120,7 +120,7 @@ proptest! { /// looping repeatedly while [`SyncStatus`] reports that it is close to the chain tip. /// 2. Waits until [`SyncStatus`] reports that it is close to the chain tip. /// 3. Notifies the main task that it awoke, i.e., that the [`SyncStatus`] has finished - /// wating until it was close to the chain tip. + /// waiting until it was close to the chain tip. async fn wait_task( mut status: SyncStatus, update_events: Arc, From 8453a33a71e523c9b88f1b09aee2e474ff029248 Mon Sep 17 00:00:00 2001 From: Marek Date: Wed, 1 Sep 2021 23:04:49 +0200 Subject: [PATCH 2/7] Avoid division by zero --- zebrad/src/components/sync/status.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zebrad/src/components/sync/status.rs b/zebrad/src/components/sync/status.rs index f5b29ac4fb4..eac751b1f9c 100644 --- a/zebrad/src/components/sync/status.rs +++ b/zebrad/src/components/sync/status.rs @@ -50,6 +50,11 @@ impl SyncStatus { pub fn is_close_to_tip(&self) -> bool { let sync_lengths = self.latest_sync_length.borrow(); + // Return early if sync_lengths is empty. + if sync_lengths.is_empty() { + return false; + } + // Compute the sum of the `sync_lengths`. // The sum is computed by saturating addition in order to avoid overflowing. let sum = sync_lengths From 288efd51903dc999e0091f0e9a2acb20ccc29f30 Mon Sep 17 00:00:00 2001 From: Marek Date: Wed, 1 Sep 2021 23:58:32 +0200 Subject: [PATCH 3/7] Try increasing EVENT_TIMEOUT --- zebrad/src/components/sync/status/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index 3b77fb75775..1e0218067b9 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -17,7 +17,7 @@ const MAX_TEST_EXECUTION: Duration = Duration::from_secs(1); /// The maximum time to wait for an event to be received. /// /// If an event is not received in this time, it is considered that it will never be received. -const EVENT_TIMEOUT: Duration = Duration::from_millis(5); +const EVENT_TIMEOUT: Duration = Duration::from_millis(10); proptest! { #![proptest_config( From 52baeb36078ce8f5e634e3c8b5c495d94bac7ff3 Mon Sep 17 00:00:00 2001 From: Marek Date: Thu, 2 Sep 2021 20:44:58 +0200 Subject: [PATCH 4/7] Increase MAX_TEST_EXECUTION --- zebrad/src/components/sync/status/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index 1e0218067b9..79dfaa4b349 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -12,12 +12,12 @@ const DEFAULT_ASYNC_SYNCHRONIZED_TASKS_PROPTEST_CASES: u32 = 32; /// The maximum time one test instance should run. /// /// If the test exceeds this time it is considered to have failed. -const MAX_TEST_EXECUTION: Duration = Duration::from_secs(1); +const MAX_TEST_EXECUTION: Duration = Duration::from_secs(10); /// The maximum time to wait for an event to be received. /// /// If an event is not received in this time, it is considered that it will never be received. -const EVENT_TIMEOUT: Duration = Duration::from_millis(10); +const EVENT_TIMEOUT: Duration = Duration::from_millis(5); proptest! { #![proptest_config( From 1bc56161216bd775e03c4cc885e136adb96f4da9 Mon Sep 17 00:00:00 2001 From: Marek Date: Mon, 6 Sep 2021 22:37:49 +0200 Subject: [PATCH 5/7] Implement basic tests --- zebrad/src/components/sync/status/tests.rs | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index 79dfaa4b349..fb256161e05 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -138,3 +138,35 @@ proptest! { } } } + +/// Test if totally empty sync lengths array is not near tip. +#[test] +fn empty_sync_lengths() { + let (status, _recent_sync_lengths) = SyncStatus::new(); + + assert!(status.is_close_to_tip() == false); +} + +/// Test if sync lengths array with all zeroes is near tip. +#[test] +fn zero_sync_lengths() { + let (status, mut recent_sync_lengths) = SyncStatus::new(); + + for _ in 0..RecentSyncLengths::MAX_RECENT_LENGTHS { + recent_sync_lengths.push_extend_tips_length(0); + } + + assert!(status.is_close_to_tip() == true); +} + +/// Test if sync lengths array with high values is not near tip. +#[test] +fn high_sync_lengths() { + let (status, mut recent_sync_lengths) = SyncStatus::new(); + + for _ in 0..RecentSyncLengths::MAX_RECENT_LENGTHS { + recent_sync_lengths.push_extend_tips_length(500); + } + + assert!(status.is_close_to_tip() == false); +} From ab1588392cfecccf883e0d83c0f46b6d8ef5e560 Mon Sep 17 00:00:00 2001 From: Marek Date: Mon, 6 Sep 2021 23:49:52 +0200 Subject: [PATCH 6/7] Resolve Clippy's erorrs --- zebrad/src/components/sync/status/tests.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index fb256161e05..8ca80772ef5 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -144,7 +144,7 @@ proptest! { fn empty_sync_lengths() { let (status, _recent_sync_lengths) = SyncStatus::new(); - assert!(status.is_close_to_tip() == false); + assert!(!status.is_close_to_tip()); } /// Test if sync lengths array with all zeroes is near tip. @@ -156,7 +156,7 @@ fn zero_sync_lengths() { recent_sync_lengths.push_extend_tips_length(0); } - assert!(status.is_close_to_tip() == true); + assert!(status.is_close_to_tip()); } /// Test if sync lengths array with high values is not near tip. @@ -164,9 +164,11 @@ fn zero_sync_lengths() { fn high_sync_lengths() { let (status, mut recent_sync_lengths) = SyncStatus::new(); + /// The value 500 is based on the fact that sync lengths are around 500 + /// blocks long when Zebra is syncing. for _ in 0..RecentSyncLengths::MAX_RECENT_LENGTHS { recent_sync_lengths.push_extend_tips_length(500); } - assert!(status.is_close_to_tip() == false); + assert!(!status.is_close_to_tip()); } From 66408a729de2e7f05542e34eabb6bbbe86b990b5 Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Mon, 6 Sep 2021 19:13:13 -0300 Subject: [PATCH 7/7] change doc comments to normal --- zebrad/src/components/sync/status/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebrad/src/components/sync/status/tests.rs b/zebrad/src/components/sync/status/tests.rs index 8ca80772ef5..978043ea9d5 100644 --- a/zebrad/src/components/sync/status/tests.rs +++ b/zebrad/src/components/sync/status/tests.rs @@ -164,8 +164,8 @@ fn zero_sync_lengths() { fn high_sync_lengths() { let (status, mut recent_sync_lengths) = SyncStatus::new(); - /// The value 500 is based on the fact that sync lengths are around 500 - /// blocks long when Zebra is syncing. + // The value 500 is based on the fact that sync lengths are around 500 + // blocks long when Zebra is syncing. for _ in 0..RecentSyncLengths::MAX_RECENT_LENGTHS { recent_sync_lengths.push_extend_tips_length(500); }