Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Estimate network chain tip height based on local node time and current best tip #3492

Merged
merged 15 commits into from
Feb 11, 2022

Conversation

jvff
Copy link
Contributor

@jvff jvff commented Feb 8, 2022

Motivation

In order to properly estimate if chain synchronization has finished, we need to calculate an estimate of the network's chain tip height. This prepares for the work to add a test for mainnet full chain synchronization.

Solution

The estimate is calculated based on the current local node's system time and the current best tip's height and block time. The time difference between the current best tip's block time and the current time is calculated, and then the number of remaining blocks is calculated using the target spacing between blocks. Because Zcash has more than one target spacing, all of them are considered for their respective block height ranges.

The API for estimation is provided as a default method in the ChainTip method. The actual estimation code is in a separate NetworkChainTipEstimator type in a separate module. I ended up deciding to separate the code to avoid making the actual ChainTip trait hard to read.

This closes #3161.

Review

@teor2345 can take a look. I'd especially like to know if the solution I've implemented is too generic and complicated, and if I should change it to a simpler one.

Reviewer Checklist

  • Code implements Specs and Designs
  • Tests for Expected Behaviour
  • Tests for Errors

Follow Up Work

@jvff jvff requested a review from teor2345 February 8, 2022 22:54
@zfnd-bot zfnd-bot bot assigned jvff Feb 8, 2022
@jvff jvff force-pushed the estimate-network-chain-tip-height branch from 6ddb5ef to f604225 Compare February 8, 2022 23:00
@codecov
Copy link

codecov bot commented Feb 9, 2022

Codecov Report

Merging #3492 (9a5b634) into main (499ae89) will increase coverage by 0.12%.
The diff coverage is 75.31%.

@@            Coverage Diff             @@
##             main    #3492      +/-   ##
==========================================
+ Coverage   78.34%   78.46%   +0.12%     
==========================================
  Files         267      274       +7     
  Lines       31526    32032     +506     
==========================================
+ Hits        24698    25134     +436     
- Misses       6828     6898      +70     

@jvff jvff force-pushed the estimate-network-chain-tip-height branch from f604225 to dbfaf34 Compare February 9, 2022 01:50
@teor2345
Copy link
Contributor

teor2345 commented Feb 9, 2022

Coverage failed due to #3489

teor2345
teor2345 previously approved these changes Feb 9, 2022
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great.

I wanted to check if the estimate was actually accurate when used in zebrad, so I added a quick progress log in PR #3495. (This will also help us diagnose full sync failures.)

I have some optional suggestions, but feel free to merge the PR as it is.

jvff added 15 commits February 10, 2022 23:26
The documentation was exactly the same as the documentation from the
trait.
Simulate a block being added to the chain with a random block time based
on the previous block time and the target spacing time.
Store the block time so that it's ready for a future chain that allows
obtaining the chain tip's block time.
Allow obtaining the bes chain tip's block time.
Prevent any data races by returning both values so that they refer to
the same chain tip.
Returns all the target spacings defined for a network.
Isolate the code to calculate the height estimation in a new type, so
that it's easier to understand and doesn't decrease the readability of
the `chain_tip.rs` file.
This is more of an extension method than a trait method. It uses the
`NetworkChainTipHeightEstimator` to actually perform the estimation, but
obtains the initial information from the current best chain tip.
There was an extra closing bracket in the summary line.
Prepare to allow mocking the block time of the best tip as well as the
block height.
Add a separate `watch` channel to send the best tip block times from a
`MockChainTipSender` to a `MockChainTip`.

The `best_tip_height_and_block_time` implementation will only return a
value if there's a height and a block time value for the best tip.
Use Euclidean division to force the division result to round down
instead of rounding towards zero. This fixes an off-by-one error when
estimating a height that is lower than the current height, because the
fractionary result was being discarded, and it should have forced the
height to go one block back.
Detect situations that might cause the block height estimate to
underflow, and return the genesis height instead.
The implementation of `chrono::Duration::num_seconds` adds one to the
number of seconds if it's negative. This breaks the division
calculation, so it has to be compensated for.
Generate pairs of block heights and check that it's possible to estimate
the larger height from the smaller height and a displaced time
difference.
@jvff jvff force-pushed the estimate-network-chain-tip-height branch from dbfaf34 to 9a5b634 Compare February 10, 2022 23:27
Copy link
Contributor

@teor2345 teor2345 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks for the fix!

I couldn't find the minor fix commit on GitHub, and there wasn't a "changes since last revw" button on GitHub. So instead I reviewed the difference between the force push heads:

git diff  dbfaf34 9a5b634 

@teor2345 teor2345 added P-Medium ⚡ A-diagnostics Area: Diagnosing issues or monitoring performance C-enhancement Category: This is an improvement labels Feb 10, 2022
mergify bot added a commit that referenced this pull request Feb 10, 2022
@mergify mergify bot merged commit eb98b7a into ZcashFoundation:main Feb 11, 2022
@jvff jvff deleted the estimate-network-chain-tip-height branch February 11, 2022 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Diagnosing issues or monitoring performance C-enhancement Category: This is an improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Estimate the current chain height from the chain tip and local time
2 participants