@@ -39,12 +39,7 @@ impl F3LightClientActor {
3939 pub fn constructor ( rt : & impl Runtime , params : ConstructorParams ) -> Result < ( ) , ActorError > {
4040 rt. validate_immediate_caller_is ( std:: iter:: once ( & SYSTEM_ACTOR_ADDR ) ) ?;
4141
42- let state = State :: new (
43- rt. store ( ) ,
44- params. latest_instance_id ,
45- params. latest_finalized_height ,
46- params. power_table ,
47- ) ?;
42+ let state = State :: new ( rt. store ( ) , params. processed_instance_id , params. power_table ) ?;
4843
4944 rt. create ( & state) ?;
5045 Ok ( ( ) )
@@ -61,41 +56,28 @@ impl F3LightClient for F3LightClientActor {
6156 // Basic monotonicity checks to prevent accidental rewinds or no-op updates.
6257 //
6358 // Note: multiple epochs can be proven under the same certificate instance, so
64- // `latest_instance_id ` may stay the same across updates, but it must never go
59+ // `processed_instance_id ` may stay the same across updates, but it must never go
6560 // backwards and must not jump by more than 1.
6661 //
6762 // Also, we allow re-applying the same update (idempotency) by permitting equality.
68- if params. latest_finalized_height < st. light_client_state . latest_finalized_height {
63+ if params. processed_instance_id < st. light_client_state . processed_instance_id {
6964 return Err ( actor_error ! (
7065 illegal_argument,
71- "latest_finalized_height went backwards: {} < {}" ,
72- params. latest_finalized_height ,
73- st. light_client_state. latest_finalized_height
66+ "processed_instance_id went backwards: {} < {}" ,
67+ params. processed_instance_id ,
68+ st. light_client_state. processed_instance_id
7469 ) ) ;
7570 }
76- if params. latest_instance_id < st. light_client_state . latest_instance_id {
71+ if params. processed_instance_id > st. light_client_state . processed_instance_id + 1 {
7772 return Err ( actor_error ! (
7873 illegal_argument,
79- "latest_instance_id went backwards: {} < {}" ,
80- params. latest_instance_id,
81- st. light_client_state. latest_instance_id
82- ) ) ;
83- }
84- if params. latest_instance_id > st. light_client_state . latest_instance_id + 1 {
85- return Err ( actor_error ! (
86- illegal_argument,
87- "latest_instance_id jumped: {} > {}" ,
88- params. latest_instance_id,
89- st. light_client_state. latest_instance_id + 1
74+ "processed_instance_id jumped: {} > {}" ,
75+ params. processed_instance_id,
76+ st. light_client_state. processed_instance_id + 1
9077 ) ) ;
9178 }
9279
93- st. update_state (
94- rt,
95- params. latest_instance_id ,
96- params. latest_finalized_height ,
97- params. power_table ,
98- ) ?;
80+ st. update_state ( rt, params. processed_instance_id , params. power_table ) ?;
9981 Ok ( ( ) )
10082 } )
10183 }
@@ -129,8 +111,7 @@ impl F3LightClient for F3LightClientActor {
129111 } ;
130112
131113 Ok ( GetStateResponse {
132- latest_instance_id : lc. latest_instance_id ,
133- latest_finalized_height : lc. latest_finalized_height ,
114+ processed_instance_id : lc. processed_instance_id ,
134115 power_table_root : lc. power_table_root . clone ( ) ,
135116 power_table,
136117 } )
@@ -159,7 +140,6 @@ mod tests {
159140 use fil_actors_runtime:: SYSTEM_ACTOR_ADDR ;
160141 use fvm_ipld_encoding:: ipld_block:: IpldBlock ;
161142 use fvm_shared:: address:: Address ;
162- use fvm_shared:: clock:: ChainEpoch ;
163143 use fvm_shared:: error:: ExitCode ;
164144
165145 /// Helper function to create test power entries
@@ -191,7 +171,6 @@ mod tests {
191171 pub fn construct_and_verify (
192172 current_instance_id : u64 ,
193173 power_table : Vec < PowerEntry > ,
194- latest_finalized_epoch : ChainEpoch ,
195174 ) -> MockRuntime {
196175 let rt = MockRuntime {
197176 receiver : Address :: new_id ( 10 ) ,
@@ -203,8 +182,7 @@ mod tests {
203182 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
204183
205184 let constructor_params = ConstructorParams {
206- latest_instance_id : current_instance_id,
207- latest_finalized_height : latest_finalized_epoch,
185+ processed_instance_id : current_instance_id,
208186 power_table,
209187 } ;
210188
@@ -224,28 +202,27 @@ mod tests {
224202
225203 #[ test]
226204 fn test_constructor_empty_power_table ( ) {
227- let _rt = construct_and_verify ( 0 , vec ! [ ] , 10 ) ;
205+ let _rt = construct_and_verify ( 0 , vec ! [ ] ) ;
228206 // Constructor test passed if we get here without panicking
229207 }
230208
231209 #[ test]
232210 fn test_constructor_with_power_table ( ) {
233211 let power_entries = create_test_power_entries ( ) ;
234- let _rt = construct_and_verify ( 1 , power_entries, 10 ) ;
212+ let _rt = construct_and_verify ( 1 , power_entries) ;
235213 // Constructor test passed if we get here without panicking
236214 }
237215
238216 #[ test]
239217 fn test_update_state_success ( ) {
240- let rt = construct_and_verify ( 1 , create_test_power_entries ( ) , 10 ) ;
218+ let rt = construct_and_verify ( 1 , create_test_power_entries ( ) ) ;
241219
242220 // Set caller to system actor
243221 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
244222 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
245223
246224 let update_params = UpdateStateParams {
247- latest_instance_id : 1 ,
248- latest_finalized_height : 11 ,
225+ processed_instance_id : 1 ,
249226 power_table : create_test_power_entries ( ) ,
250227 } ;
251228
@@ -261,15 +238,13 @@ mod tests {
261238 }
262239
263240 #[ test]
264- fn test_update_state_non_advancing_height ( ) {
265- let rt = construct_and_verify ( 1 , create_test_power_entries ( ) , 10 ) ;
241+ fn test_update_state_idempotent_allowed ( ) {
242+ let rt = construct_and_verify ( 1 , create_test_power_entries ( ) ) ;
266243
267- // First update to advance the finalized height.
268244 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
269245 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
270246 let initial_params = UpdateStateParams {
271- latest_instance_id : 1 ,
272- latest_finalized_height : 11 ,
247+ processed_instance_id : 1 ,
273248 power_table : create_test_power_entries ( ) ,
274249 } ;
275250 rt. call :: < F3LightClientActor > (
@@ -279,12 +254,11 @@ mod tests {
279254 . unwrap ( ) ;
280255 rt. reset ( ) ;
281256
282- // Try to update with same height
257+ // Try to update with same instance
283258 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
284259 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
285260 let update_params = UpdateStateParams {
286- latest_instance_id : 1 ,
287- latest_finalized_height : 11 ,
261+ processed_instance_id : 1 ,
288262 power_table : create_test_power_entries ( ) ,
289263 } ;
290264
@@ -299,16 +273,15 @@ mod tests {
299273
300274 #[ test]
301275 fn test_update_state_unauthorized_caller ( ) {
302- let rt = construct_and_verify ( 1 , create_test_power_entries ( ) , 10 ) ;
276+ let rt = construct_and_verify ( 1 , create_test_power_entries ( ) ) ;
303277
304278 // Set caller to non-system actor
305279 let unauthorized_caller = Address :: new_id ( 999 ) ;
306280 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , unauthorized_caller) ;
307281 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
308282
309283 let update_params = UpdateStateParams {
310- latest_instance_id : 1 ,
311- latest_finalized_height : 11 ,
284+ processed_instance_id : 1 ,
312285 power_table : create_test_power_entries ( ) ,
313286 } ;
314287
@@ -326,14 +299,13 @@ mod tests {
326299 #[ test]
327300 fn test_get_state ( ) {
328301 let power_entries = create_test_power_entries ( ) ;
329- let rt = construct_and_verify ( 42 , power_entries. clone ( ) , 10 ) ;
302+ let rt = construct_and_verify ( 42 , power_entries. clone ( ) ) ;
330303
331304 // Update state first
332305 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
333306 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
334307 let update_params = UpdateStateParams {
335- latest_instance_id : 42 ,
336- latest_finalized_height : 11 ,
308+ processed_instance_id : 42 ,
337309 power_table : power_entries. clone ( ) ,
338310 } ;
339311 rt. call :: < F3LightClientActor > (
@@ -351,14 +323,13 @@ mod tests {
351323 . unwrap ( ) ;
352324
353325 let response = result. deserialize :: < GetStateResponse > ( ) . unwrap ( ) ;
354- assert_eq ! ( response. latest_instance_id, 42 ) ;
355- assert_eq ! ( response. latest_finalized_height, 11 ) ;
326+ assert_eq ! ( response. processed_instance_id, 42 ) ;
356327 assert_eq ! ( response. power_table, power_entries) ;
357328 }
358329
359330 #[ test]
360331 fn test_power_table_root_changes_on_update ( ) {
361- let rt = construct_and_verify ( 42 , create_test_power_entries ( ) , 10 ) ;
332+ let rt = construct_and_verify ( 42 , create_test_power_entries ( ) ) ;
362333
363334 // Read initial state.
364335 rt. expect_validate_caller_any ( ) ;
@@ -393,8 +364,7 @@ mod tests {
393364 } ,
394365 ] ;
395366 let update_params = UpdateStateParams {
396- latest_instance_id : 42 ,
397- latest_finalized_height : 11 ,
367+ processed_instance_id : 42 ,
398368 power_table : new_power_table. clone ( ) ,
399369 } ;
400370 rt. call :: < F3LightClientActor > (
@@ -422,14 +392,13 @@ mod tests {
422392
423393 #[ test]
424394 fn test_state_progression ( ) {
425- let rt = construct_and_verify ( 1 , create_test_power_entries ( ) , 10 ) ;
395+ let rt = construct_and_verify ( 1 , create_test_power_entries ( ) ) ;
426396
427397 // Update with first state
428398 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
429399 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
430400 let params1 = UpdateStateParams {
431- latest_instance_id : 1 ,
432- latest_finalized_height : 100 ,
401+ processed_instance_id : 1 ,
433402 power_table : create_test_power_entries ( ) ,
434403 } ;
435404 rt. call :: < F3LightClientActor > (
@@ -439,12 +408,11 @@ mod tests {
439408 . unwrap ( ) ;
440409 rt. reset ( ) ;
441410
442- // Update with second state (higher height )
411+ // Update with same instance again (idempotent allowed )
443412 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
444413 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
445414 let params2 = UpdateStateParams {
446- latest_instance_id : 1 ,
447- latest_finalized_height : 200 ,
415+ processed_instance_id : 1 ,
448416 power_table : create_test_power_entries ( ) ,
449417 } ;
450418 let result = rt. call :: < F3LightClientActor > (
@@ -456,14 +424,13 @@ mod tests {
456424
457425 #[ test]
458426 fn test_instance_id_progression_next_instance ( ) {
459- let rt = construct_and_verify ( 100 , create_test_power_entries ( ) , 10 ) ;
427+ let rt = construct_and_verify ( 100 , create_test_power_entries ( ) ) ;
460428
461429 // First state at instance 100
462430 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
463431 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
464432 let initial_params = UpdateStateParams {
465- latest_instance_id : 100 ,
466- latest_finalized_height : 11 ,
433+ processed_instance_id : 100 ,
467434 power_table : create_test_power_entries ( ) ,
468435 } ;
469436 rt. call :: < F3LightClientActor > (
@@ -477,8 +444,7 @@ mod tests {
477444 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
478445 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
479446 let update_params = UpdateStateParams {
480- latest_instance_id : 101 ,
481- latest_finalized_height : 12 ,
447+ processed_instance_id : 101 ,
482448 power_table : create_test_power_entries ( ) ,
483449 } ;
484450
@@ -491,14 +457,13 @@ mod tests {
491457
492458 #[ test]
493459 fn test_instance_id_skip_rejected ( ) {
494- let rt = construct_and_verify ( 100 , create_test_power_entries ( ) , 10 ) ;
460+ let rt = construct_and_verify ( 100 , create_test_power_entries ( ) ) ;
495461
496462 // First state at instance 100
497463 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
498464 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
499465 let initial_params = UpdateStateParams {
500- latest_instance_id : 100 ,
501- latest_finalized_height : 11 ,
466+ processed_instance_id : 100 ,
502467 power_table : create_test_power_entries ( ) ,
503468 } ;
504469 rt. call :: < F3LightClientActor > (
@@ -512,8 +477,7 @@ mod tests {
512477 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
513478 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
514479 let update_params = UpdateStateParams {
515- latest_instance_id : 102 ,
516- latest_finalized_height : 12 ,
480+ processed_instance_id : 102 ,
517481 power_table : create_test_power_entries ( ) ,
518482 } ;
519483
@@ -526,26 +490,5 @@ mod tests {
526490 assert_eq ! ( err. exit_code( ) , ExitCode :: USR_ILLEGAL_ARGUMENT ) ;
527491 }
528492
529- #[ test]
530- fn test_height_rewind_rejected ( ) {
531- let rt = construct_and_verify ( 1 , create_test_power_entries ( ) , 10 ) ;
532-
533- rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
534- rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
535-
536- // Try to update with a lower finalized height (rewind).
537- let update_params = UpdateStateParams {
538- latest_instance_id : 1 ,
539- latest_finalized_height : 9 ,
540- power_table : create_test_power_entries ( ) ,
541- } ;
542-
543- let result = rt. call :: < F3LightClientActor > (
544- Method :: UpdateState as u64 ,
545- IpldBlock :: serialize_cbor ( & update_params) . unwrap ( ) ,
546- ) ;
547- assert ! ( result. is_err( ) ) ;
548- let err = result. unwrap_err ( ) ;
549- assert_eq ! ( err. exit_code( ) , ExitCode :: USR_ILLEGAL_ARGUMENT ) ;
550- }
493+ // Note: the epoch cursor is tracked in the gateway contract; the actor no longer stores height.
551494}
0 commit comments