-
Notifications
You must be signed in to change notification settings - Fork 3
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
Fix candidate tracking on async backing #675
Conversation
a67d1e1
to
8a2e5bb
Compare
parachain-tracer/src/tracker.rs
Outdated
@@ -40,7 +40,7 @@ pub struct SubxtTracker { | |||
/// A new session index. | |||
new_session: Option<u32>, | |||
/// Information about current parachain block we track. | |||
current_candidate: ParachainBlockInfo, | |||
candidates: Vec<ParachainBlockInfo>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need a vec of these, which wraps a vec of states. There should be one state per parachain that is tracked.
From parachain consensus perspective we now allow a new candidate to be backed at an occupied core (while the previous candidate is pending avilability).
I'd expect to see this reflected here somehow.
@@ -38,58 +34,55 @@ pub struct ParachainBlockInfo { | |||
pub assigned_core: Option<u32>, | |||
/// Core occupation status. | |||
pub core_occupied: bool, | |||
/// The current state. | |||
state: Vec<ParachainBlockState>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why more objects of state instead of one ?
if candidate.is_idle() { | ||
progress.events.push(ParachainConsensusEvent::SkippedSlot); | ||
stats.on_skipped_slot(progress); | ||
metrics.on_skipped_slot(progress); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
insert continue
. we don't need to check next conditions.
parachain-tracer/src/tracker.rs
Outdated
progress.events.push(ParachainConsensusEvent::Backed(candidate_hash)); | ||
stats.on_backed(); | ||
metrics.on_backed(self.para_id); | ||
if candidate.is_backed() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seem to be so many ifs here, a match would be better if we had an enum for the candidate state.
fn is_just_backed(&self) -> bool { | ||
self.last_backed_at_block_number.is_some() && | ||
self.last_backed_at_block_number == self.current_relay_block.map(|v| v.num) | ||
} | ||
|
||
fn is_slow_availability(&self) -> bool { | ||
self.current_candidate.core_occupied && | ||
fn is_slow_availability(&self, core: u32) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is a good time to make sure we have tests covering all of these functions and ensure they work as expected. The condition below seems brittle.
let max_bits = self.validators_indices(block_hash, storage).await?.len() as u32; | ||
let candidate = self.current_candidate_mut(core).expect("Checked above"); | ||
|
||
candidate.current_availability_bits = extract_availability_bits_count(&bitfields, core); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the candidate was backed at current block, the bits should not be set at all. I'd assume we want to do this only if !is_just_backed
, below.
} | ||
} | ||
if last_included.is_some() { | ||
self.relay_forks.last_mut().expect("must have relay fork").included_candidate = last_included; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this expect panic ?
parachain-tracer/src/tracker.rs
Outdated
if let Some(candidate_hash) = candidate.candidate_hash { | ||
if let Some(stored_candidate) = storage.candidate(candidate_hash).await { | ||
if stored_candidate.is_included() { | ||
candidate.set_included(); | ||
last_included = candidate.candidate_hash; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if let Some(candidate_hash) = candidate.candidate_hash { | |
if let Some(stored_candidate) = storage.candidate(candidate_hash).await { | |
if stored_candidate.is_included() { | |
candidate.set_included(); | |
last_included = candidate.candidate_hash; | |
} | |
} | |
} | |
let Some(candidate_hash) = candidate.candidate_hash else { | |
continue | |
} | |
let Some(stored_candidate) = storage.candidate(candidate_hash).await else { | |
continue | |
} | |
if stored_candidate.is_included() { | |
candidate.set_included(); | |
last_included = candidate.candidate_hash; | |
} | |
parachain-tracer/src/tracker.rs
Outdated
.map(|v| ParachainBlockInfo::candidate_hash(&v)); | ||
let mut used_cores = vec![]; | ||
for candidate_hash in candidate_hashes { | ||
if let Some(core) = self.candidate_core(candidate_hash, storage).await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use let Some(..)
to avoid nesting.
parachain-tracer/src/tracker.rs
Outdated
metrics.on_skipped_slot(progress); | ||
}, | ||
ParachainBlockState::Backed => | ||
if let Some(candidate_hash) = candidate.candidate_hash { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we remove the option ? Doesn't seem to make sense to have the state backed but no hash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, removing ParachainBlockState::Idle
.
parachain-tracer/src/tracker.rs
Outdated
metrics.on_backed(self.para_id); | ||
}, | ||
ParachainBlockState::PendingAvailability => { | ||
if self.is_slow_availability(candidate.assigned_core.expect("must be assigned")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When would expect panic ? I'd avoid doing this since it reduces the uptime of the monitor. Let's log errors instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should never panic, because a backed candidate info should include assigned core.
Updated, removing |
Fixes #673
Major changes
included
status based on chain events, which we store in the collector.