Skip to content

Commit 71e93cf

Browse files
committed
duty_tracker: track finalized block
1 parent ec7e742 commit 71e93cf

File tree

3 files changed

+91
-47
lines changed

3 files changed

+91
-47
lines changed

crates/consensus-logic/src/duties.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ impl BlockSigningDuty {
5858
pub struct DutyTracker {
5959
next_id: u64,
6060
duties: Vec<DutyEntry>,
61+
finalized_block: Option<L2BlockId>,
6162
}
6263

6364
impl DutyTracker {
@@ -66,6 +67,7 @@ impl DutyTracker {
6667
Self {
6768
next_id: 1,
6869
duties: Vec::new(),
70+
finalized_block: None,
6971
}
7072
}
7173

@@ -78,6 +80,10 @@ impl DutyTracker {
7880
pub fn update(&mut self, update: &StateUpdate) -> usize {
7981
let mut kept_duties = Vec::new();
8082

83+
if update.latest_finalized_block.is_some() {
84+
self.set_finalized_block(update.latest_finalized_block);
85+
}
86+
8187
for d in self.duties.drain(..) {
8288
match d.duty.expiry() {
8389
Expiry::NextBlock => {
@@ -120,6 +126,14 @@ impl DutyTracker {
120126
}));
121127
}
122128

129+
pub fn set_finalized_block(&mut self, blkid: Option<L2BlockId>) {
130+
self.finalized_block = blkid;
131+
}
132+
133+
pub fn get_finalized_block(&self) -> Option<L2BlockId> {
134+
self.finalized_block
135+
}
136+
123137
/// Returns the slice of duties we're keeping around.
124138
pub fn duties(&self) -> &[DutyEntry] {
125139
&self.duties
@@ -162,6 +176,9 @@ pub struct StateUpdate {
162176

163177
/// Newly finalized blocks, must be sorted.
164178
newly_finalized_blocks: Vec<L2BlockId>,
179+
180+
/// Latest finalized block.
181+
latest_finalized_block: Option<L2BlockId>,
165182
}
166183

167184
impl StateUpdate {
@@ -170,11 +187,16 @@ impl StateUpdate {
170187
cur_timestamp: time::Instant,
171188
mut newly_finalized_blocks: Vec<L2BlockId>,
172189
) -> Self {
190+
// Extract latest finalized block before sorting
191+
let latest_finalized_block = newly_finalized_blocks.first().cloned();
192+
173193
newly_finalized_blocks.sort();
194+
174195
Self {
175196
last_block_slot,
176197
cur_timestamp,
177198
newly_finalized_blocks,
199+
latest_finalized_block,
178200
}
179201
}
180202

crates/consensus-logic/src/duty_executor.rs

Lines changed: 66 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,11 @@ pub fn duty_tracker_task<D: Database>(
5959

6060
let idx = database.client_state_provider().get_last_checkpoint_idx()?;
6161
let last_checkpoint_state = database.client_state_provider().get_state_checkpoint(idx)?;
62-
let mut last_finalized_blk = match last_checkpoint_state {
62+
let last_finalized_blk = match last_checkpoint_state {
6363
Some(state) => state.sync().map(|sync| *sync.finalized_blkid()),
6464
None => None,
6565
};
66+
duties_tracker.set_finalized_block(last_finalized_blk);
6667

6768
loop {
6869
let update = match cupdate_rx.blocking_recv() {
@@ -82,13 +83,7 @@ pub fn duty_tracker_task<D: Database>(
8283
trace!(%ev_idx, "new consensus state, updating duties");
8384
trace!("STATE: {new_state:#?}");
8485

85-
if let Err(e) = update_tracker(
86-
&mut duties_tracker,
87-
new_state,
88-
&ident,
89-
database.as_ref(),
90-
&mut last_finalized_blk,
91-
) {
86+
if let Err(e) = update_tracker(&mut duties_tracker, new_state, &ident, database.as_ref()) {
9287
error!(err = %e, "failed to update duties tracker");
9388
}
9489

@@ -109,7 +104,6 @@ fn update_tracker<D: Database>(
109104
state: &ClientState,
110105
ident: &Identity,
111106
database: &D,
112-
last_finalized_block: &mut Option<L2BlockId>,
113107
) -> Result<(), Error> {
114108
let Some(ss) = state.sync() else {
115109
return Ok(());
@@ -129,8 +123,11 @@ fn update_tracker<D: Database>(
129123

130124
// Figure out which blocks were finalized
131125
let new_finalized = state.sync().map(|sync| *sync.finalized_blkid());
132-
let newly_finalized_blocks: Vec<L2BlockId> =
133-
get_finalized_blocks(new_finalized, l2prov.as_ref(), last_finalized_block)?;
126+
let newly_finalized_blocks: Vec<L2BlockId> = get_finalized_blocks(
127+
tracker.get_finalized_block(),
128+
l2prov.as_ref(),
129+
new_finalized,
130+
)?;
134131

135132
let tracker_update = duties::StateUpdate::new(block_idx, ts, newly_finalized_blocks);
136133
let n_evicted = tracker.update(&tracker_update);
@@ -143,36 +140,30 @@ fn update_tracker<D: Database>(
143140
}
144141

145142
fn get_finalized_blocks(
146-
finalized: Option<L2BlockId>,
143+
last_finalized_block: Option<L2BlockId>,
147144
l2prov: &impl L2DataProvider,
148-
last_finalized_block: &mut Option<L2BlockId>,
145+
finalized: Option<L2BlockId>,
149146
) -> Result<Vec<L2BlockId>, Error> {
150147
// Figure out which blocks were finalized
151148
let mut newly_finalized_blocks: Vec<L2BlockId> = Vec::new();
152149
let mut new_finalized = finalized;
153150

154-
loop {
155-
if let Some(finalized) = new_finalized {
156-
// If the last finalized block is equal to the new finalized block,
157-
// it means that no new blocks are finalized
158-
if *last_finalized_block == Some(finalized) {
159-
break;
160-
}
161-
162-
// else loop till we reach to the last finalized block or go all the way
163-
// as long as we get some block data
164-
// TODO: verify if this works as expected
165-
newly_finalized_blocks.push(finalized);
151+
while let Some(finalized) = new_finalized {
152+
// If the last finalized block is equal to the new finalized block,
153+
// it means that no new blocks are finalized
154+
if last_finalized_block == Some(finalized) {
155+
break;
156+
}
166157

167-
match l2prov.get_block_data(finalized)? {
168-
Some(block) => new_finalized = Some(*block.header().parent()),
169-
None => break,
170-
}
158+
// else loop till we reach to the last finalized block or go all the way
159+
// as long as we get some block data
160+
match l2prov.get_block_data(finalized)? {
161+
Some(block) => new_finalized = Some(*block.header().parent()),
162+
None => break,
171163
}
172-
}
173164

174-
// Update the last_finalized_block with the new_finalized value
175-
*last_finalized_block = finalized;
165+
newly_finalized_blocks.push(finalized);
166+
}
176167

177168
Ok(newly_finalized_blocks)
178169
}
@@ -455,18 +446,50 @@ mod tests {
455446

456447
let block_ids: Vec<_> = chain.iter().map(|b| b.header().get_blockid()).collect();
457448

458-
let mut last_finalized_block = Some(block_ids[0]);
459-
let new_finalized = Some(block_ids[4]);
460-
let finalized_blocks = get_finalized_blocks(
461-
new_finalized,
462-
db.l2_provider().as_ref(),
463-
&mut last_finalized_block,
464-
)
465-
.unwrap();
449+
{
450+
let last_finalized_block = Some(block_ids[0]);
451+
let new_finalized = Some(block_ids[4]);
452+
let finalized_blocks = get_finalized_blocks(
453+
last_finalized_block,
454+
db.l2_provider().as_ref(),
455+
new_finalized,
456+
)
457+
.unwrap();
458+
459+
let expected_finalized_blocks: Vec<_> =
460+
block_ids[1..=4].iter().rev().cloned().collect();
461+
462+
assert_eq!(finalized_blocks, expected_finalized_blocks);
463+
}
466464

467-
let expected_finalized_blocks: Vec<_> = block_ids[1..=4].iter().rev().cloned().collect();
465+
{
466+
let last_finalized_block = None;
467+
let new_finalized = Some(block_ids[4]);
468+
let finalized_blocks = get_finalized_blocks(
469+
last_finalized_block,
470+
db.l2_provider().as_ref(),
471+
new_finalized,
472+
)
473+
.unwrap();
468474

469-
assert_eq!(finalized_blocks, expected_finalized_blocks);
470-
assert_eq!(last_finalized_block, new_finalized);
475+
let expected_finalized_blocks: Vec<_> =
476+
block_ids[0..=4].iter().rev().cloned().collect();
477+
478+
assert_eq!(finalized_blocks, expected_finalized_blocks);
479+
}
480+
481+
{
482+
let last_finalized_block = None;
483+
let new_finalized = None;
484+
let finalized_blocks = get_finalized_blocks(
485+
last_finalized_block,
486+
db.l2_provider().as_ref(),
487+
new_finalized,
488+
)
489+
.unwrap();
490+
491+
let expected_finalized_blocks: Vec<_> = vec![];
492+
assert_eq!(finalized_blocks, expected_finalized_blocks);
493+
}
471494
}
472495
}

crates/test-utils/src/l2.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@ pub fn gen_block(parent: Option<&SignedL2BlockHeader>) -> L2BlockBundle {
1414
let body: L2BlockBody = arb.generate();
1515
let accessory: L2BlockAccessory = arb.generate();
1616

17-
let start = SystemTime::now();
18-
let since_the_epoch = start
17+
let current_timestamp = SystemTime::now()
1918
.duration_since(UNIX_EPOCH)
20-
.expect("Time went backwards");
21-
let current_timestamp = since_the_epoch.as_millis() as u64;
19+
.unwrap()
20+
.as_millis() as u64;
2221

2322
let block_idx = parent.map(|h| h.blockidx() + 1).unwrap_or(0);
2423
let prev_block = parent.map(|h| h.get_blockid()).unwrap_or_default();

0 commit comments

Comments
 (0)