l1_block_info_test.go 3.82 KB
Newer Older
1 2 3
package derive

import (
4
	crand "crypto/rand"
5 6 7 8
	"math/big"
	"math/rand"
	"testing"

9 10 11
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

12 13
	"github.com/ethereum/go-ethereum/common"

14
	"github.com/ethereum-optimism/optimism/op-service/eth"
Sabnock01's avatar
Sabnock01 committed
15
	"github.com/ethereum-optimism/optimism/op-service/testutils"
16 17
)

18
var _ eth.BlockInfo = (*testutils.MockBlockInfo)(nil)
19 20

type infoTest struct {
21 22 23 24 25 26 27 28 29 30 31
	name    string
	mkInfo  func(rng *rand.Rand) *testutils.MockBlockInfo
	mkL1Cfg func(rng *rand.Rand, l1Info eth.BlockInfo) eth.SystemConfig
	seqNr   func(rng *rand.Rand) uint64
}

func randomL1Cfg(rng *rand.Rand, l1Info eth.BlockInfo) eth.SystemConfig {
	return eth.SystemConfig{
		BatcherAddr: testutils.RandomAddress(rng),
		Overhead:    [32]byte{},
		Scalar:      [32]byte{},
32
		GasLimit:    1234567,
33
	}
34 35 36 37 38
}

var MockDepositContractAddr = common.HexToAddress("0xdeadbeefdeadbeefdeadbeefdeadbeef00000000")

func TestParseL1InfoDepositTxData(t *testing.T) {
39 40 41
	randomSeqNr := func(rng *rand.Rand) uint64 {
		return rng.Uint64()
	}
42 43
	// Go 1.18 will have native fuzzing for us to use, until then, we cover just the below cases
	cases := []infoTest{
44
		{"random", testutils.MakeBlockInfo(nil), randomL1Cfg, randomSeqNr},
45
		{"zero basefee", testutils.MakeBlockInfo(func(l *testutils.MockBlockInfo) {
46
			l.InfoBaseFee = new(big.Int)
47
		}), randomL1Cfg, randomSeqNr},
48
		{"zero time", testutils.MakeBlockInfo(func(l *testutils.MockBlockInfo) {
49
			l.InfoTime = 0
50
		}), randomL1Cfg, randomSeqNr},
51
		{"zero num", testutils.MakeBlockInfo(func(l *testutils.MockBlockInfo) {
52
			l.InfoNum = 0
53 54
		}), randomL1Cfg, randomSeqNr},
		{"zero seq", testutils.MakeBlockInfo(nil), randomL1Cfg, func(rng *rand.Rand) uint64 {
55 56 57 58
			return 0
		}},
		{"all zero", func(rng *rand.Rand) *testutils.MockBlockInfo {
			return &testutils.MockBlockInfo{InfoBaseFee: new(big.Int)}
59
		}, randomL1Cfg, func(rng *rand.Rand) uint64 {
60
			return 0
61 62 63 64
		}},
	}
	for i, testCase := range cases {
		t.Run(testCase.name, func(t *testing.T) {
65 66
			rng := rand.New(rand.NewSource(int64(1234 + i)))
			info := testCase.mkInfo(rng)
67
			l1Cfg := testCase.mkL1Cfg(rng, info)
68
			seqNr := testCase.seqNr(rng)
69
			depTx, err := L1InfoDeposit(seqNr, info, l1Cfg, false)
70 71 72
			require.NoError(t, err)
			res, err := L1InfoDepositTxData(depTx.Data)
			require.NoError(t, err, "expected valid deposit info")
73 74
			assert.Equal(t, res.Number, info.NumberU64())
			assert.Equal(t, res.Time, info.Time())
75
			assert.True(t, res.BaseFee.Sign() >= 0)
76 77
			assert.Equal(t, res.BaseFee.Bytes(), info.BaseFee().Bytes())
			assert.Equal(t, res.BlockHash, info.Hash())
78
			assert.Equal(t, res.SequenceNumber, seqNr)
79 80 81
			assert.Equal(t, res.BatcherAddr, l1Cfg.BatcherAddr)
			assert.Equal(t, res.L1FeeOverhead, l1Cfg.Overhead)
			assert.Equal(t, res.L1FeeScalar, l1Cfg.Scalar)
82 83 84 85 86 87 88 89 90 91 92 93 94 95
		})
	}
	t.Run("no data", func(t *testing.T) {
		_, err := L1InfoDepositTxData(nil)
		assert.Error(t, err)
	})
	t.Run("not enough data", func(t *testing.T) {
		_, err := L1InfoDepositTxData([]byte{1, 2, 3, 4})
		assert.Error(t, err)
	})
	t.Run("too much data", func(t *testing.T) {
		_, err := L1InfoDepositTxData(make([]byte, 4+32+32+32+32+32+1))
		assert.Error(t, err)
	})
96 97 98
	t.Run("invalid selector", func(t *testing.T) {
		rng := rand.New(rand.NewSource(1234))
		info := testutils.MakeBlockInfo(nil)(rng)
99
		depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), false)
100
		require.NoError(t, err)
101
		_, err = crand.Read(depTx.Data[0:4])
102 103 104 105
		require.NoError(t, err)
		_, err = L1InfoDepositTxData(depTx.Data)
		require.ErrorContains(t, err, "function signature")
	})
106 107 108 109 110 111 112 113
	t.Run("regolith", func(t *testing.T) {
		rng := rand.New(rand.NewSource(1234))
		info := testutils.MakeBlockInfo(nil)(rng)
		depTx, err := L1InfoDeposit(randomSeqNr(rng), info, randomL1Cfg(rng, info), true)
		require.NoError(t, err)
		require.False(t, depTx.IsSystemTransaction)
		require.Equal(t, depTx.Gas, uint64(RegolithSystemTxGas))
	})
114
}