@@ -87,6 +87,10 @@ impl ChainFollower {
87
87
async fn next_from_mithril ( & mut self ) -> Option < ChainUpdate > {
88
88
let current_mithril_tip = latest_mithril_snapshot_id ( self . chain ) . tip ( ) ;
89
89
90
+ // Return an ImmutableBlockRollForward event as soon as we can after one occurs.
91
+ // This is not an advancement in the followers sequential block iterating state.
92
+ // BUT it is a necessary status to return to a follower, so it can properly handle
93
+ // when immutable state advances (if it so requires)
90
94
if let Some ( previous_mithril_tip) = & self . mithril_tip {
91
95
if current_mithril_tip != * previous_mithril_tip {
92
96
debug ! (
@@ -102,12 +106,14 @@ impl ChainFollower {
102
106
false , // Tip is Live chain tip, not Mithril Tip, and this is Mithril Tip.
103
107
block,
104
108
) ;
105
- // Update the new Mithril Tip in the followers state before we report it to the
106
- // following task..
107
- self . mithril_tip = Some ( current_mithril_tip) ;
108
109
return Some ( update) ;
109
110
}
110
111
112
+ // This can only happen if the snapshot does not contain the tip block.
113
+ // So its effectively impossible.
114
+ // However, IF it does happen, nothing bad (other than a delay to reporting
115
+ // immutable roll forward) will occur, so we log this impossible
116
+ // error, and continue processing.
111
117
error ! (
112
118
tip = ?self . mithril_tip,
113
119
current = ?current_mithril_tip,
@@ -116,8 +122,6 @@ impl ChainFollower {
116
122
}
117
123
}
118
124
119
- self . mithril_tip = Some ( current_mithril_tip. clone ( ) ) ;
120
-
121
125
if current_mithril_tip > self . current {
122
126
if self . mithril_follower . is_none ( ) {
123
127
self . mithril_follower = self
@@ -128,9 +132,7 @@ impl ChainFollower {
128
132
129
133
if let Some ( follower) = self . mithril_follower . as_mut ( ) {
130
134
if let Some ( next) = follower. next ( ) . await {
131
- // debug!("Pre Previous update 3 : {:?}", self.previous);
132
135
self . previous = self . current . clone ( ) ;
133
- // debug!("Post Previous update 3 : {:?}", self.previous);
134
136
self . current = next. point ( ) ;
135
137
self . fork = Fork :: IMMUTABLE ; // Mithril Immutable data is always Fork 0.
136
138
let update = ChainUpdate :: new ( chain_update:: Kind :: Block , false , next) ;
@@ -139,30 +141,6 @@ impl ChainFollower {
139
141
}
140
142
}
141
143
142
- // let roll_forward_condition = if let Some(mithril_tip) = &self.mithril_tip {
143
- // current_mithril_tip > *mithril_tip && *mithril_tip > self.current
144
- // } else {
145
- // true
146
- // };
147
- //
148
- // if roll_forward_condition {
149
- // let snapshot = MithrilSnapshot::new(self.chain);
150
- // if let Some(block) = snapshot.read_block_at(¤t_mithril_tip).await {
151
- // The Mithril Tip has moved forwards.
152
- // self.mithril_tip = Some(current_mithril_tip);
153
- // Get the mithril tip block.
154
- // debug!("The other ImmutableBlockRollForward");
155
- // let update =
156
- // ChainUpdate::new(chain_update::Kind::ImmutableBlockRollForward, false, block);
157
- // return Some(update);
158
- // }
159
- // error!(
160
- // tip = ?self.mithril_tip,
161
- // current = ?current_mithril_tip,
162
- // "Mithril Tip Block is not in snapshot. Should not happen."
163
- // );
164
- // }
165
-
166
144
None
167
145
}
168
146
@@ -248,8 +226,12 @@ impl ChainFollower {
248
226
fn update_current ( & mut self , update : Option < & ChainUpdate > ) -> bool {
249
227
if let Some ( update) = update {
250
228
if update. kind == Kind :: ImmutableBlockRollForward {
251
- // We DO NOT update anything for this kind of update, as its informational.
252
- // It does not advance any follower, otherwise.
229
+ // The ImmutableBlockRollForward includes the Mithril TIP Block.
230
+ // Update the mithril_tip state to the point of it.
231
+ self . mithril_tip = Some ( update. data . point ( ) ) ;
232
+ // We DO NOT update anything else for this kind of update, as its informational and
233
+ // does not advance the state of the follower to a new block.
234
+ // It is still a valid update, and so return true, but don't update more state.
253
235
return true ;
254
236
}
255
237
let decoded = update. block_data ( ) . decode ( ) ;
@@ -272,10 +254,6 @@ impl ChainFollower {
272
254
273
255
// We will loop here until we can successfully return a new block
274
256
loop {
275
- // Check if Immutable TIP has advanced, and if so, send a ChainUpdate about it.
276
- // Should only happen once every ~6hrs.
277
- // TODO.
278
-
279
257
// Try and get the next update from the mithril chain, and return it if we are
280
258
// successful.
281
259
update = self . next_from_mithril ( ) . await ;
@@ -293,16 +271,24 @@ impl ChainFollower {
293
271
// wait for something to change which might mean we can get the next block.
294
272
// Note, this is JUST a trigger, we don't process based on it other than to allow
295
273
// a blocked follower to continue.
296
- let update_result = self . sync_updates . recv ( ) . await ;
297
- match update_result {
274
+ let changed_data_trigger = self . sync_updates . recv ( ) . await ;
275
+ match changed_data_trigger {
298
276
Ok ( kind) => {
277
+ // The KIND of event signaling changed data is not important, but we do log it
278
+ // to help with debugging in case an update stops.
299
279
debug ! ( "Update kind: {kind}" ) ;
300
280
} ,
301
281
Err ( tokio:: sync:: broadcast:: error:: RecvError :: Lagged ( distance) ) => {
282
+ // The update queue is small, its possible that it fills before a task can
283
+ // read from it, this will cause this Lagged error.
284
+ // BUT, because we don't care what the event was, this is as good as the missed
285
+ // event. Therefore its not an error, and just log it at debug to help with
286
+ // debugging the logic only.
302
287
debug ! ( "Lagged by {} updates" , distance) ;
303
288
} ,
304
289
Err ( tokio:: sync:: broadcast:: error:: RecvError :: Closed ) => {
305
- // We are closed, so we need to wait for the next update.
290
+ // The queue is closed, so we need to return that its no longer possible to
291
+ // get data from this follower.
306
292
// This is not an error.
307
293
return None ;
308
294
} ,
0 commit comments