span_batch_tx_test.go 4.11 KB
Newer Older
1 2 3 4 5 6 7
package derive

import (
	"math/big"
	"math/rand"
	"testing"

Tei Im's avatar
Tei Im committed
8
	"github.com/ethereum-optimism/optimism/op-service/testutils"
9 10
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/stretchr/testify/assert"
11
	"github.com/stretchr/testify/require"
12 13
)

14
type spanBatchTxTest struct {
15 16 17 18
	name      string
	trials    int
	mkTx      func(rng *rand.Rand, signer types.Signer) *types.Transaction
	protected bool
19 20
}

21
func TestSpanBatchTxConvert(t *testing.T) {
22
	cases := []spanBatchTxTest{
23 24 25 26
		{"unprotected legacy tx", 32, testutils.RandomLegacyTx, false},
		{"legacy tx", 32, testutils.RandomLegacyTx, true},
		{"access list tx", 32, testutils.RandomAccessListTx, true},
		{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true},
27 28
	}

29 30 31 32 33
	for i, testCase := range cases {
		t.Run(testCase.name, func(t *testing.T) {
			rng := rand.New(rand.NewSource(int64(0x1331 + i)))
			chainID := big.NewInt(rng.Int63n(1000))
			signer := types.NewLondonSigner(chainID)
34 35 36
			if !testCase.protected {
				signer = types.HomesteadSigner{}
			}
37

38 39
			for txIdx := 0; txIdx < testCase.trials; txIdx++ {
				tx := testCase.mkTx(rng, signer)
40

41
				v, r, s := tx.RawSignatureValues()
42
				sbtx, err := newSpanBatchTx(tx)
43
				require.NoError(t, err)
44

45 46
				tx2, err := sbtx.convertToFullTx(tx.Nonce(), tx.Gas(), tx.To(), chainID, v, r, s)
				require.NoError(t, err)
47

48 49 50 51 52 53 54 55 56
				// compare after marshal because we only need inner field of transaction
				txEncoded, err := tx.MarshalBinary()
				require.NoError(t, err)
				tx2Encoded, err := tx2.MarshalBinary()
				require.NoError(t, err)

				assert.Equal(t, txEncoded, tx2Encoded)
			}
		})
57 58 59
	}
}

60 61
func TestSpanBatchTxRoundTrip(t *testing.T) {
	cases := []spanBatchTxTest{
62 63 64 65
		{"unprotected legacy tx", 32, testutils.RandomLegacyTx, false},
		{"legacy tx", 32, testutils.RandomLegacyTx, true},
		{"access list tx", 32, testutils.RandomAccessListTx, true},
		{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true},
66 67 68 69 70 71 72
	}

	for i, testCase := range cases {
		t.Run(testCase.name, func(t *testing.T) {
			rng := rand.New(rand.NewSource(int64(0x1332 + i)))
			chainID := big.NewInt(rng.Int63n(1000))
			signer := types.NewLondonSigner(chainID)
73 74 75
			if !testCase.protected {
				signer = types.HomesteadSigner{}
			}
76 77 78 79

			for txIdx := 0; txIdx < testCase.trials; txIdx++ {
				tx := testCase.mkTx(rng, signer)

80
				sbtx, err := newSpanBatchTx(tx)
81 82 83 84 85 86 87 88 89 90 91 92
				require.NoError(t, err)

				sbtxEncoded, err := sbtx.MarshalBinary()
				require.NoError(t, err)

				var sbtx2 spanBatchTx
				err = sbtx2.UnmarshalBinary(sbtxEncoded)
				require.NoError(t, err)

				assert.Equal(t, sbtx, &sbtx2)
			}
		})
93 94 95 96 97 98
	}
}

type spanBatchDummyTxData struct{}

func (txData *spanBatchDummyTxData) txType() byte { return types.DepositTxType }
99

100 101 102
func TestSpanBatchTxInvalidTxType(t *testing.T) {
	// span batch never contain deposit tx
	depositTx := types.NewTx(&types.DepositTx{})
103
	_, err := newSpanBatchTx(depositTx)
104
	require.ErrorContains(t, err, "invalid tx type")
105 106 107 108

	var sbtx spanBatchTx
	sbtx.inner = &spanBatchDummyTxData{}
	_, err = sbtx.convertToFullTx(0, 0, nil, nil, nil, nil, nil)
109
	require.ErrorContains(t, err, "invalid tx type")
110 111 112 113 114
}

func TestSpanBatchTxDecodeInvalid(t *testing.T) {
	var sbtx spanBatchTx
	_, err := sbtx.decodeTyped([]byte{})
115
	require.ErrorIs(t, err, ErrTypedTxTooShort)
116 117 118

	tx := types.NewTx(&types.LegacyTx{})
	txEncoded, err := tx.MarshalBinary()
119
	require.NoError(t, err)
120 121 122

	// legacy tx is not typed tx
	_, err = sbtx.decodeTyped(txEncoded)
123
	require.EqualError(t, err, types.ErrTxTypeNotSupported.Error())
124 125 126

	tx2 := types.NewTx(&types.AccessListTx{})
	tx2Encoded, err := tx2.MarshalBinary()
127
	require.NoError(t, err)
128 129 130

	tx2Encoded[0] = types.DynamicFeeTxType
	_, err = sbtx.decodeTyped(tx2Encoded)
131
	require.ErrorContains(t, err, "failed to decode spanBatchDynamicFeeTxData")
132 133 134

	tx3 := types.NewTx(&types.DynamicFeeTx{})
	tx3Encoded, err := tx3.MarshalBinary()
135
	require.NoError(t, err)
136 137 138

	tx3Encoded[0] = types.AccessListTxType
	_, err = sbtx.decodeTyped(tx3Encoded)
139
	require.ErrorContains(t, err, "failed to decode spanBatchAccessListTxData")
140 141 142

	invalidLegacyTxDecoded := []byte{0xFF, 0xFF}
	err = sbtx.UnmarshalBinary(invalidLegacyTxDecoded)
143
	require.ErrorContains(t, err, "failed to decode spanBatchLegacyTxData")
144
}