github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/derive/l1_block_info_tob_test.go (about)

     1  package derive
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/ethereum-optimism/optimism/op-node/rollup"
     7  	"github.com/ethereum-optimism/optimism/op-service/eth"
     8  	"github.com/ethereum-optimism/optimism/op-service/testutils"
     9  	"github.com/ethereum-optimism/optimism/op-service/testutils/fuzzerutils"
    10  	fuzz "github.com/google/gofuzz"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  // FuzzParseL1InfoDepositTxDataValid is a fuzz test built from TestParseL1InfoDepositTxData, which constructs random
    15  // L1 deposit tx info and derives a tx from it, then derives the info back from the tx, to ensure round-trip
    16  // derivation is upheld. This generates "valid" data and ensures it is always derived back to original values.
    17  func FuzzParseL1InfoDepositTxDataValid(f *testing.F) {
    18  	f.Fuzz(func(t *testing.T, fuzzedData []byte) {
    19  		// Create our fuzzer wrapper to generate complex values
    20  		typeProvider := fuzz.NewFromGoFuzz(fuzzedData).NilChance(0).MaxDepth(10000).NumElements(0, 0x100)
    21  		fuzzerutils.AddFuzzerFunctions(typeProvider)
    22  
    23  		var l1Info testutils.MockBlockInfo
    24  		typeProvider.Fuzz(&l1Info)
    25  		var seqNr uint64
    26  		typeProvider.Fuzz(&seqNr)
    27  		var sysCfg eth.SystemConfig
    28  		typeProvider.Fuzz(&sysCfg)
    29  		var rollupCfg rollup.Config
    30  
    31  		// Create our deposit tx from our info
    32  		depTx, err := L1InfoDeposit(&rollupCfg, sysCfg, seqNr, &l1Info, 0)
    33  		require.NoError(t, err, "error creating deposit tx from L1 info")
    34  
    35  		// Get our info from out deposit tx
    36  		res, err := L1BlockInfoFromBytes(&rollupCfg, l1Info.InfoTime, depTx.Data)
    37  		require.NoError(t, err, "expected valid deposit info")
    38  
    39  		// Verify all parameters match in our round trip deriving operations
    40  		require.Equal(t, res.Number, l1Info.NumberU64())
    41  		require.Equal(t, res.Time, l1Info.Time())
    42  		require.True(t, res.BaseFee.Sign() >= 0)
    43  		require.Equal(t, res.BaseFee.Bytes(), l1Info.BaseFee().Bytes())
    44  		require.Equal(t, res.BlockHash, l1Info.Hash())
    45  		require.Equal(t, res.SequenceNumber, seqNr)
    46  		require.Equal(t, res.BatcherAddr, sysCfg.BatcherAddr)
    47  		require.Equal(t, res.L1FeeOverhead, sysCfg.Overhead)
    48  		require.Equal(t, res.L1FeeScalar, sysCfg.Scalar)
    49  	})
    50  }
    51  
    52  // Reverse of the above test. Accepts a random byte string and attempts to extract L1Info from it,
    53  // then attempts to convert that info back into the tx data and compare it with the original input.
    54  func FuzzDecodeDepositTxDataToL1Info(f *testing.F) {
    55  	var rollupCfg rollup.Config
    56  	f.Fuzz(func(t *testing.T, fuzzedData []byte) {
    57  		// Get our info from out deposit tx
    58  		res, err := L1BlockInfoFromBytes(&rollupCfg, 0, fuzzedData)
    59  		if err != nil {
    60  			return
    61  		}
    62  
    63  		l1Info := testutils.MockBlockInfo{
    64  			InfoHash:    res.BlockHash,
    65  			InfoNum:     res.Number,
    66  			InfoTime:    res.Time,
    67  			InfoBaseFee: res.BaseFee,
    68  		}
    69  
    70  		sysCfg := eth.SystemConfig{
    71  			BatcherAddr: res.BatcherAddr,
    72  			Overhead:    res.L1FeeOverhead,
    73  			Scalar:      res.L1FeeScalar,
    74  			GasLimit:    uint64(0),
    75  		}
    76  
    77  		depTx, err := L1InfoDeposit(&rollupCfg, sysCfg, res.SequenceNumber, &l1Info, 0)
    78  		require.NoError(t, err, "error creating deposit tx from L1 info")
    79  		require.Equal(t, depTx.Data, fuzzedData)
    80  	})
    81  }
    82  
    83  // FuzzParseL1InfoDepositTxDataBadLength is a fuzz test built from TestParseL1InfoDepositTxData, which constructs
    84  // random L1 deposit tx info and derives a tx from it, then derives the info back from the tx, to ensure round-trip
    85  // derivation is upheld. This generates "invalid" data and ensures it always throws an error where expected.
    86  func FuzzParseL1InfoDepositTxDataBadLength(f *testing.F) {
    87  	var rollupCfg rollup.Config
    88  	const expectedDepositTxDataLength = 4 + 32 + 32 + 32 + 32 + 32
    89  	f.Fuzz(func(t *testing.T, fuzzedData []byte) {
    90  		// Derive a transaction from random fuzzed data
    91  		_, err := L1BlockInfoFromBytes(&rollupCfg, 0, fuzzedData)
    92  
    93  		// If the data is null, or too short or too long, we expect an error
    94  		if fuzzedData == nil || len(fuzzedData) != expectedDepositTxDataLength {
    95  			require.Error(t, err)
    96  		}
    97  	})
    98  }