@@ -500,3 +500,93 @@ func TestIsValidSignedData(t *testing.T) {
500500 assert .False (t , m .isValidSignedData (signedData ))
501501 })
502502}
503+
504+ // TestManager_execValidate tests the execValidate method for various header/data/state conditions.
505+ func TestManager_execValidate (t * testing.T ) {
506+ require := require .New (t )
507+ genesis , _ , _ := types .GetGenesisWithPrivkey ("TestChain" )
508+ m , _ := getManager (t , nil , - 1 , - 1 )
509+
510+ // Helper to create a valid state/header/data triplet
511+ makeValid := func () (types.State , * types.SignedHeader , * types.Data , crypto.PrivKey ) {
512+ state := types.State {
513+ Version : types.Version {Block : 1 , App : 1 },
514+ ChainID : genesis .ChainID ,
515+ InitialHeight : genesis .InitialHeight ,
516+ LastBlockHeight : genesis .InitialHeight - 1 ,
517+ LastBlockTime : time .Now ().Add (- time .Minute ),
518+ AppHash : []byte ("apphash" ),
519+ }
520+ newHeight := state .LastBlockHeight + 1
521+ // Build header and data
522+ header , data , privKey := types .GenerateRandomBlockCustomWithAppHash (& types.BlockConfig {Height : newHeight , NTxs : 1 }, state .ChainID , state .AppHash )
523+ require .NotNil (header )
524+ require .NotNil (data )
525+ require .NotNil (privKey )
526+ return state , header , data , privKey
527+ }
528+
529+ t .Run ("valid header and data" , func (t * testing.T ) {
530+ state , header , data , _ := makeValid ()
531+ err := m .execValidate (state , header , data )
532+ require .NoError (err )
533+ })
534+
535+ t .Run ("invalid header (ValidateBasic fails)" , func (t * testing.T ) {
536+ state , header , data , _ := makeValid ()
537+ header .ProposerAddress = []byte ("bad" ) // breaks proposer address check
538+ err := m .execValidate (state , header , data )
539+ require .ErrorContains (err , "invalid header" )
540+ })
541+
542+ t .Run ("header/data mismatch (types.Validate fails)" , func (t * testing.T ) {
543+ state , header , data , _ := makeValid ()
544+ data .Metadata .ChainID = "otherchain" // breaks types.Validate
545+ err := m .execValidate (state , header , data )
546+ require .ErrorContains (err , "validation failed" )
547+ })
548+
549+ t .Run ("chain ID mismatch" , func (t * testing.T ) {
550+ state , header , data , _ := makeValid ()
551+ state .ChainID = "wrongchain"
552+ err := m .execValidate (state , header , data )
553+ require .ErrorContains (err , "chain ID mismatch" )
554+ })
555+
556+ t .Run ("height mismatch" , func (t * testing.T ) {
557+ state , header , data , _ := makeValid ()
558+ state .LastBlockHeight += 2
559+ err := m .execValidate (state , header , data )
560+ require .ErrorContains (err , "invalid height" )
561+ })
562+
563+ t .Run ("non-monotonic block time at height 1 does not error" , func (t * testing.T ) {
564+ state , header , data , _ := makeValid ()
565+ state .LastBlockTime = header .Time ()
566+ err := m .execValidate (state , header , data )
567+ require .NoError (err )
568+ })
569+
570+ // TODO: https://github.com/rollkit/rollkit/issues/2250
571+
572+ // t.Run("non-monotonic block time with height > 1", func(t *testing.T) {
573+ // state, header, data, privKey := makeValid()
574+ // state.LastBlockTime = time.Now().Add(time.Minute)
575+ // state.LastBlockHeight = 1
576+ // header.BaseHeader.Height = state.LastBlockHeight + 1
577+ // data.Metadata.Height = state.LastBlockHeight + 1
578+ // signer, err := noopsigner.NewNoopSigner(privKey)
579+ // require.NoError(err)
580+ // header.Signature, err = types.GetSignature(header.Header, signer)
581+ // require.NoError(err)
582+ // err = m.execValidate(state, header, data)
583+ // require.ErrorContains(err, "block time must be strictly increasing")
584+ // })
585+
586+ // t.Run("app hash mismatch", func(t *testing.T) {
587+ // state, header, data, _ := makeValid()
588+ // state.AppHash = []byte("different")
589+ // err := m.execValidate(state, header, data)
590+ // require.ErrorContains(err, "app hash mismatch")
591+ // })
592+ }
0 commit comments