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

feat(consensus): eliminate block ties #673

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

msbrogli
Copy link
Member

@msbrogli msbrogli commented Jun 16, 2023

Motivation

We've always supported "block ties", meaning that blocks that have the same score will tie and both void each other, while at the same time having to remain as "best block tips" (which always had to be a list). This pushes some unnecessary complexity throughout the code. There are no disadvantages to using the block hash as a tie-breaker and simplifying this complexity.

In practice there's a slight difference in the consensus of certain situations, the difference is that before some tied block chains would be voided all the way back until they weren't tied anymore, now one of them would be picked as best chain. This situation does not cause any incompatibility in how nodes sync and any new block with higher score will cause the same state on both chains.

This PR is the first step, that only focuses on removing ties at the consensus level. Subsequent PRs will focus on refactoring out the complexity of supporting multiple tips.

Acceptance criteria

  • update block consensus' update_voided_info so when testing if a new block might be a winner, and its score is neither higher or lower than the current winner (that is, a tie), the hash is used as a tie breaker
  • update block consensus' update_voided_info so when a new block is not a winner, only the tip with highest score and lowest hash is stored as "best block tips" cache
  • update transaction storage's get_best_block_tips so it only ever returns a list of size 1, when the block tips index returns more than one tip with the highest score, the one if lowest hash is selected
  • update test_split_brain_only_blocks_different_height so it checks the node will correctly not void everything back to the genesis and tie the two blocks (when before it used to)
  • update test_single_fork_not_best similarly, so it checks that the best chain is considered

@msbrogli msbrogli requested a review from jansegre as a code owner June 16, 2023 07:14
@msbrogli msbrogli self-assigned this Jun 16, 2023
@msbrogli msbrogli force-pushed the feat/consensus-change branch 3 times, most recently from 5598803 to 8abec23 Compare June 16, 2023 08:51
@msbrogli msbrogli force-pushed the feat/consensus-change branch from 8abec23 to 5026f34 Compare July 12, 2023 12:07
@msbrogli msbrogli force-pushed the feat/consensus-change branch from 5026f34 to d4dc39e Compare October 17, 2023 20:16
@jansegre jansegre assigned jansegre and unassigned msbrogli Jul 10, 2024
@jansegre jansegre force-pushed the feat/consensus-change branch from d4dc39e to 807d778 Compare July 10, 2024 16:37
@jansegre jansegre force-pushed the feat/consensus-change branch 5 times, most recently from 7e4b8b8 to e516014 Compare August 1, 2024 16:36
@jansegre jansegre changed the base branch from master to feat/score-acc-weight-types August 1, 2024 16:36
Copy link

codecov bot commented Aug 1, 2024

Codecov Report

Attention: Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.

Project coverage is 84.61%. Comparing base (123166e) to head (2aa27e6).

Files with missing lines Patch % Lines
hathor/transaction/storage/transaction_storage.py 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #673      +/-   ##
==========================================
- Coverage   84.70%   84.61%   -0.10%     
==========================================
  Files         313      313              
  Lines       24249    24256       +7     
  Branches     3690     3693       +3     
==========================================
- Hits        20541    20525      -16     
- Misses       2997     3009      +12     
- Partials      711      722      +11     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

for tx in txs2:
meta = tx.get_metadata(force_reload=True)
self.assertIsNone(meta.first_block)
# for tx in txs2:
Copy link
Member Author

Choose a reason for hiding this comment

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

Why is this part of the code commented out?

Copy link
Member

Choose a reason for hiding this comment

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

I'm actually not too sure, I'll review this part.

@@ -624,6 +624,11 @@ def get_best_block_tips(self, timestamp: Optional[float] = None, *, skip_cache:
elif meta.score > best_score:
best_score = meta.score
best_tip_blocks = [block_hash]

# XXX: if there's more than one we filter it so it's the smallest hash
if len(best_tip_blocks) > 1:
Copy link
Member Author

Choose a reason for hiding this comment

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

Should we allow the caller to choose whether they want to get just one or all of them?

Copy link
Member

Choose a reason for hiding this comment

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

I think that could make sense as a new method, like get_all_block_tips, instead of get_best_block_tips. But currently that method wouldn't be used anywhere else, and when removing the tips indexes, it would be more convenient if we didn't have to maintain that method.

@@ -624,6 +624,11 @@ def get_best_block_tips(self, timestamp: Optional[float] = None, *, skip_cache:
elif meta.score > best_score:
best_score = meta.score
best_tip_blocks = [block_hash]

# XXX: if there's more than one we filter it so it's the smallest hash
if len(best_tip_blocks) > 1:
Copy link
Member Author

Choose a reason for hiding this comment

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

Should we create an issue to refactor this method and simply store the current best block in the storage?

Copy link
Member

Choose a reason for hiding this comment

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

#540 sort of does this by using the height-index, but because it's not using this PR as a base it does this incorrectly and hides other tips, after this PR that change would be correct

@jansegre jansegre changed the title feat(consensus): Change feat(consensus): eliminate block ties Aug 12, 2024
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from 17c1ffc to 93d9f89 Compare August 21, 2024 13:18
@jansegre jansegre force-pushed the feat/consensus-change branch from e516014 to 1b93f4d Compare August 21, 2024 13:25
@jansegre jansegre requested a review from glevco August 22, 2024 00:36
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from 93d9f89 to da4ac0d Compare August 22, 2024 21:45
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from da4ac0d to b74fa0d Compare September 3, 2024 15:44
@jansegre jansegre force-pushed the feat/consensus-change branch from 1b93f4d to b9b2390 Compare September 3, 2024 16:34
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from b74fa0d to 45884e3 Compare September 10, 2024 16:05
@jansegre jansegre force-pushed the feat/consensus-change branch from b9b2390 to 2dddd20 Compare September 10, 2024 16:20
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from 45884e3 to b21d67c Compare September 24, 2024 14:30
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch 2 times, most recently from 2f2d7a8 to 1a3e1d0 Compare October 3, 2024 21:51
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch 2 times, most recently from 4a182f4 to d870605 Compare October 8, 2024 13:54
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch 2 times, most recently from fb35bfb to 17eac7c Compare October 18, 2024 16:38
@jansegre jansegre force-pushed the feat/consensus-change branch from 2dddd20 to 3f18210 Compare October 18, 2024 16:39
@jansegre jansegre force-pushed the feat/score-acc-weight-types branch from 17eac7c to 26a36c0 Compare October 23, 2024 12:54
@jansegre jansegre force-pushed the feat/consensus-change branch from 3f18210 to e7b3d46 Compare October 23, 2024 12:55
Base automatically changed from feat/score-acc-weight-types to master October 24, 2024 16:41
@jansegre jansegre force-pushed the feat/consensus-change branch from e7b3d46 to 2aa27e6 Compare October 25, 2024 15:11
Copy link

github-actions bot commented Oct 25, 2024

🐰 Bencher Report

Branchfeat/consensus-change
Testbedubuntu-22.04

🚨 1 Alert

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Lower Boundary
(Limit %)
sync-v2 (up to 20000 blocks)Latency
minutes (m)
📈 plot
🚨 alert (🔔)
🚷 threshold
1.48
(-10.71%)
1.49
(100.79%)
Click to view all benchmark results
BenchmarkLatencyBenchmark Result
minutes (m)
(Result Δ%)
Lower Boundary
minutes (m)
(Limit %)
Upper Boundary
minutes (m)
(Limit %)
sync-v2 (up to 20000 blocks)📈 view plot
🚨 view alert (🔔)
🚷 view threshold
1.48
(-10.71%)
1.49
(100.79%)
1.82
(81.18%)
🐰 View full continuous benchmarking report in Bencher

Copy link
Member Author

@msbrogli msbrogli left a comment

Choose a reason for hiding this comment

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

Approved!

@jansegre jansegre force-pushed the feat/consensus-change branch from a0b589a to 4bf80a4 Compare January 9, 2025 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Review (WIP)
Development

Successfully merging this pull request may close these issues.

2 participants