@@ -131,6 +131,90 @@ func TestFullInterop(gt *testing.T) {
131131 require .Equal (t , head , status .FinalizedL2 .ID ())
132132}
133133
134+ // TestFinality confirms that when L1 finality is updated on the supervisor,
135+ // the L2 finality signal updates to the appropriate value.
136+ // Sub-tests control how many additional blocks might be submitted to the L1 chain,
137+ // affecting the way Finality would be determined.
138+ func TestFinality (gt * testing.T ) {
139+ testFinality := func (t helpers.StatefulTesting , extraBlocks int ) {
140+ is := SetupInterop (t )
141+ actors := is .CreateActors ()
142+
143+ // set up a blank ChainA
144+ actors .ChainA .Sequencer .ActL2PipelineFull (t )
145+ actors .ChainA .Sequencer .SyncSupervisor (t )
146+
147+ actors .Supervisor .ProcessFull (t )
148+
149+ // Build L2 block on chain A
150+ actors .ChainA .Sequencer .ActL2StartBlock (t )
151+ actors .ChainA .Sequencer .ActL2EndBlock (t )
152+
153+ // Sync and process the supervisor, updating cross-unsafe
154+ actors .ChainA .Sequencer .SyncSupervisor (t )
155+ actors .Supervisor .ProcessFull (t )
156+ actors .ChainA .Sequencer .ActL2PipelineFull (t )
157+
158+ // Submit the L2 block, sync the local-safe data
159+ actors .ChainA .Batcher .ActSubmitAll (t )
160+ actors .L1Miner .ActL1StartBlock (12 )(t )
161+ actors .L1Miner .ActL1IncludeTx (actors .ChainA .BatcherAddr )(t )
162+ actors .L1Miner .ActL1EndBlock (t )
163+ actors .L1Miner .ActL1SafeNext (t )
164+
165+ // Run the node until the L1 is exhausted
166+ // and have the supervisor provide the latest L1 block
167+ actors .ChainA .Sequencer .ActL2EventsUntil (t , event .Is [derive .ExhaustedL1Event ], 100 , false )
168+ actors .Supervisor .SignalLatestL1 (t )
169+ actors .ChainA .Sequencer .SyncSupervisor (t )
170+ actors .ChainA .Sequencer .ActL2PipelineFull (t )
171+ actors .ChainA .Sequencer .ActL1HeadSignal (t )
172+ // Make the supervisor aware of the new L1 block
173+ actors .Supervisor .SignalLatestL1 (t )
174+ // Ingest the new local-safe event
175+ actors .ChainA .Sequencer .SyncSupervisor (t )
176+ // Cross-safe verify it
177+ actors .Supervisor .ProcessFull (t )
178+ actors .ChainA .Sequencer .ActL2PipelineFull (t )
179+
180+ // Submit more blocks to the L1, to bury the L2 block
181+ for i := 0 ; i < extraBlocks ; i ++ {
182+ actors .L1Miner .ActL1StartBlock (12 )(t )
183+ actors .L1Miner .ActL1EndBlock (t )
184+ actors .L1Miner .ActL1SafeNext (t )
185+ actors .Supervisor .SignalLatestL1 (t )
186+ actors .Supervisor .ProcessFull (t )
187+ }
188+
189+ tip := actors .L1Miner .SafeNum ()
190+
191+ // Update finality on the supervisor to the latest block
192+ actors .L1Miner .ActL1Finalize (t , tip )
193+ actors .Supervisor .SignalFinalizedL1 (t )
194+
195+ // Process the supervisor to update the finality, and pull L1, L2 finality
196+ actors .Supervisor .ProcessFull (t )
197+ l1Finalized := actors .Supervisor .backend .FinalizedL1 ()
198+ l2Finalized , err := actors .Supervisor .backend .Finalized (context .Background (), actors .ChainA .ChainID )
199+ require .NoError (t , err )
200+ require .Equal (t , uint64 (tip ), l1Finalized .Number )
201+ // the L2 finality is the latest L2 block, because L1 finality is beyond anything the L2 used to derive
202+ require .Equal (t , uint64 (1 ), l2Finalized .Number )
203+
204+ // confirm the node also sees the finality
205+ actors .ChainA .Sequencer .ActL2PipelineFull (t )
206+ status := actors .ChainA .Sequencer .SyncStatus ()
207+ require .Equal (t , uint64 (1 ), status .FinalizedL2 .Number )
208+ }
209+ statefulT := helpers .NewDefaultTesting (gt )
210+ gt .Run ("FinalizeBeyondDerived" , func (t * testing.T ) {
211+ testFinality (statefulT , 10 )
212+ })
213+ gt .Run ("Finalize" , func (t * testing.T ) {
214+ testFinality (statefulT , 0 )
215+ })
216+ }
217+
134218func TestInteropFaultProofs (gt * testing.T ) {
135219 t := helpers .NewDefaultTesting (gt )
136220
0 commit comments