Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Port unconfirmed duplicate tracking logic from ProgressMap to ForkChoice #17779

Merged
merged 6 commits into from
Jun 11, 2021

Conversation

carllin
Copy link
Contributor

@carllin carllin commented Jun 7, 2021

Problem

Keeping the duplicate/duplicate confirmed tracking logic in ProgressMap is unwieldy for a number of reasons:

  1. Requires a separate update in cluster_slot_state_verifier to update the ProgressMap, and then separately mark certain forks valid/invalid in ForkChoice:

    progress.set_unconfirmed_duplicate_slot(
    slot,
    descendants.get(&slot).unwrap_or(&HashSet::default()),
    );
    fork_choice.mark_fork_invalid_candidate(&(slot, bank_frozen_hash));
    }

  2. Updating the ProgressMap for duplicate/duplicate confirmed tracking requires passing in ancestors/descendants:

    pub fn set_unconfirmed_duplicate_slot(&mut self, slot: Slot, descendants: &HashSet<u64>) {
    because it doesn't know about fork structure. This means ancestors/descendants have to be passed along to cluster_slot_state_verifier::check_slot_agrees_with_cluster()
    ancestors: &HashMap<Slot, HashSet<Slot>>,
    descendants: &HashMap<Slot, HashSet<Slot>>,
    and a variety of ReplayStage functions that call down to that function

Furthermore, there are correctness issues that can arise because we track all the duplicate ancestor information in the ProgressMap and not ForkChoice. These stem from the fact that the fork choice only knows that a specific block was marked valid/invalid, but doesn't know if descendants of that block are valid/invalid. For example, consider the following order of events:

Given a fork 0 -> 1 -> 2 -> 3

  1. Fork 1 is marked duplicate. Currently, we set the is_candidate flag to false
    fork_info.is_candidate = false;
    and then removes the entire subtree from fork choice.
  2. Fork 2 is marked duplicate, and removes its entire subtree from fork choice, similar to 1) above.
  3. Fork 1 is marked valid. At this point, without searching all of its ancestors, fork 3 has no idea whether it is part of fork choice because its own is_candidate flag is not set.

Now 3) is not an issue when considering the overall best slot returned by fork choice:

pub fn best_overall_slot(&self) -> SlotHashKey {
self.best_slot(&self.root).unwrap()
}
, because that looks at the best slot field at the root node, and the root node contains aggregate information from the invalid fork 2. However, functions like heaviest_slot_on_same_voted_fork():
let heaviest_slot_hash_on_same_voted_fork = self.best_slot(&last_voted_slot_hash);
, look at the best slot field of a node that is potentially in the subtree of 2, and didn't contain the aggregate information that 2 was marked invalid.

Summary of Changes

Port duplicate fork/duplicate confirmed status tracking and tests to fork choice

Fixes #

@carllin carllin added the v1.7 label Jun 7, 2021
@carllin carllin requested review from sakridge and jstarry June 7, 2021 08:02
Comment on lines 97 to 99
// The latest ancestor of this node that has been marked invalid
latest_invalid_ancestor: Option<Slot>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you also mention that this will be set to the ForkInfo's own slot if it's a duplicate?

@carllin carllin force-pushed the FixReplayStage branch 4 times, most recently from f1f0f3f to 7a62cc1 Compare June 10, 2021 23:36
@codecov
Copy link

codecov bot commented Jun 11, 2021

Codecov Report

Merging #17779 (5ce142b) into master (afafa62) will increase coverage by 0.0%.
The diff coverage is 97.7%.

@@           Coverage Diff            @@
##           master   #17779    +/-   ##
========================================
  Coverage    82.6%    82.6%            
========================================
  Files         431      431            
  Lines      121044   121178   +134     
========================================
+ Hits       100035   100167   +132     
- Misses      21009    21011     +2     

jstarry
jstarry previously approved these changes Jun 11, 2021
Copy link
Contributor

@jstarry jstarry left a comment

Choose a reason for hiding this comment

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

lgtm

@mergify mergify bot dismissed jstarry’s stale review June 11, 2021 05:31

Pull request has been modified.

@carllin carllin merged commit c8535be into solana-labs:master Jun 11, 2021
mergify bot pushed a commit that referenced this pull request Jun 11, 2021
mergify bot added a commit that referenced this pull request Jun 11, 2021
@brooksprumo brooksprumo mentioned this pull request Aug 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants