@@ -207,6 +207,77 @@ func TestProcessHeightEvent_SyncsAndUpdatesState(t *testing.T) {
207207 assert .Equal (t , uint64 (1 ), st1 .LastBlockHeight )
208208}
209209
210+ func TestSyncer_PersistsDAHeightMapping_WhenSyncingFromDA (t * testing.T ) {
211+ ds := dssync .MutexWrap (datastore .NewMapDatastore ())
212+ st := store .New (ds )
213+
214+ cm , err := cache .NewManager (config .DefaultConfig (), st , zerolog .Nop ())
215+ require .NoError (t , err )
216+
217+ addr , pub , signer := buildSyncTestSigner (t )
218+
219+ cfg := config .DefaultConfig ()
220+ gen := genesis.Genesis {ChainID : "tchain" , InitialHeight : 1 , StartTime : time .Now ().Add (- time .Second ), ProposerAddress : addr }
221+
222+ mockExec := testmocks .NewMockExecutor (t )
223+ mockExec .EXPECT ().InitChain (mock .Anything , mock .Anything , uint64 (1 ), "tchain" ).Return ([]byte ("app0" ), nil ).Once ()
224+
225+ errChan := make (chan error , 1 )
226+ s := NewSyncer (
227+ st ,
228+ mockExec ,
229+ nil ,
230+ cm ,
231+ common .NopMetrics (),
232+ cfg ,
233+ gen ,
234+ extmocks.NewMockStore [* types.P2PSignedHeader ](t ),
235+ extmocks.NewMockStore [* types.P2PData ](t ),
236+ zerolog .Nop (),
237+ common .DefaultBlockOptions (),
238+ errChan ,
239+ nil ,
240+ )
241+
242+ require .NoError (t , s .initializeState ())
243+ s .ctx = t .Context ()
244+
245+ // Create signed header & data for height 1
246+ lastState := s .getLastState ()
247+ data := makeData (gen .ChainID , 1 , 0 )
248+ _ , hdr := makeSignedHeaderBytes (t , gen .ChainID , 1 , addr , pub , signer , lastState .AppHash , data , nil )
249+
250+ // Expect ExecuteTxs call for height 1
251+ mockExec .EXPECT ().ExecuteTxs (mock .Anything , mock .Anything , uint64 (1 ), mock .Anything , lastState .AppHash ).
252+ Return ([]byte ("app1" ), nil ).Once ()
253+
254+ // Process event with DA source and a specific DA height
255+ daHeight := uint64 (42 )
256+ evt := common.DAHeightEvent {Header : hdr , Data : data , DaHeight : daHeight , Source : common .SourceDA }
257+ s .processHeightEvent (t .Context (), & evt )
258+
259+ requireEmptyChan (t , errChan )
260+
261+ // Verify block was synced
262+ h , err := st .Height (t .Context ())
263+ require .NoError (t , err )
264+ assert .Equal (t , uint64 (1 ), h )
265+
266+ // Verify DA height mapping was persisted for header
267+ headerDABytes , err := st .GetMetadata (t .Context (), store .GetHeightToDAHeightHeaderKey (1 ))
268+ require .NoError (t , err )
269+ require .Len (t , headerDABytes , 8 )
270+ headerDAHeight := binary .LittleEndian .Uint64 (headerDABytes )
271+ assert .Equal (t , daHeight , headerDAHeight )
272+
273+ // Verify DA height mapping was persisted for data
274+ dataDABytes , err := st .GetMetadata (t .Context (), store .GetHeightToDAHeightDataKey (1 ))
275+ require .NoError (t , err )
276+ require .Len (t , dataDABytes , 8 )
277+ dataDAHeight := binary .LittleEndian .Uint64 (dataDABytes )
278+ assert .Equal (t , daHeight , dataDAHeight )
279+ }
280+
210281func TestSequentialBlockSync (t * testing.T ) {
211282 ds := dssync .MutexWrap (datastore .NewMapDatastore ())
212283 st := store .New (ds )
0 commit comments