Commit 6f103820 authored by Tei Im's avatar Tei Im

Ensure to test all TX types including unprotected tx

parent 46ff55c6
...@@ -19,7 +19,7 @@ import ( ...@@ -19,7 +19,7 @@ import (
) )
func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch {
blockCount := uint64(1 + rng.Int()&0xFF) blockCount := uint64(4 + rng.Int()&0xFF) // at least 4
originBits := new(big.Int) originBits := new(big.Int)
for i := 0; i < int(blockCount); i++ { for i := 0; i < int(blockCount); i++ {
bit := uint(0) bit := uint(0)
...@@ -30,11 +30,8 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { ...@@ -30,11 +30,8 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch {
} }
var blockTxCounts []uint64 var blockTxCounts []uint64
totalblockTxCounts := uint64(0) totalblockTxCounts := uint64(0)
for i := 0; i < int(blockCount); i++ {
blockTxCounts = append(blockTxCounts, 4) blockTxCount := 1 + uint64(rng.Intn(16))
totalblockTxCounts += 4
for i := 1; i < int(blockCount); i++ {
blockTxCount := uint64(rng.Intn(16))
blockTxCounts = append(blockTxCounts, blockTxCount) blockTxCounts = append(blockTxCounts, blockTxCount)
totalblockTxCounts += blockTxCount totalblockTxCounts += blockTxCount
} }
...@@ -42,11 +39,15 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch { ...@@ -42,11 +39,15 @@ func RandomRawSpanBatch(rng *rand.Rand, chainId *big.Int) *RawSpanBatch {
var txs [][]byte var txs [][]byte
for i := 0; i < int(totalblockTxCounts); i++ { for i := 0; i < int(totalblockTxCounts); i++ {
var tx *types.Transaction var tx *types.Transaction
// ensure unprotected txs are included switch i % 4 {
if i < 4 || testutils.RandomBool(rng) { case 0:
tx = testutils.RandomLegacyTxNotProtected(rng) tx = testutils.RandomLegacyTx(rng, types.HomesteadSigner{})
} else { case 1:
tx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), londonSigner) tx = testutils.RandomLegacyTx(rng, londonSigner)
case 2:
tx = testutils.RandomAccessListTx(rng, londonSigner)
case 3:
tx = testutils.RandomDynamicFeeTx(rng, londonSigner)
} }
rawTx, err := tx.MarshalBinary() rawTx, err := tx.MarshalBinary()
if err != nil { if err != nil {
......
...@@ -447,9 +447,10 @@ func TestSpanBatchToSingularBatch(t *testing.T) { ...@@ -447,9 +447,10 @@ func TestSpanBatchToSingularBatch(t *testing.T) {
func TestSpanBatchReadTxData(t *testing.T) { func TestSpanBatchReadTxData(t *testing.T) {
cases := []spanBatchTxTest{ cases := []spanBatchTxTest{
{"legacy tx", 32, testutils.RandomLegacyTx}, {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false},
{"access list tx", 32, testutils.RandomAccessListTx}, {"legacy tx", 32, testutils.RandomLegacyTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, {"access list tx", 32, testutils.RandomAccessListTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true},
} }
for i, testCase := range cases { for i, testCase := range cases {
...@@ -457,6 +458,9 @@ func TestSpanBatchReadTxData(t *testing.T) { ...@@ -457,6 +458,9 @@ func TestSpanBatchReadTxData(t *testing.T) {
rng := rand.New(rand.NewSource(int64(0x109550 + i))) rng := rand.New(rand.NewSource(int64(0x109550 + i)))
chainID := new(big.Int).SetUint64(rng.Uint64()) chainID := new(big.Int).SetUint64(rng.Uint64())
signer := types.NewLondonSigner(chainID) signer := types.NewLondonSigner(chainID)
if !testCase.protected {
signer = types.HomesteadSigner{}
}
var rawTxs [][]byte var rawTxs [][]byte
var txs []*types.Transaction var txs []*types.Transaction
......
...@@ -12,16 +12,18 @@ import ( ...@@ -12,16 +12,18 @@ import (
) )
type spanBatchTxTest struct { type spanBatchTxTest struct {
name string name string
trials int trials int
mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction
protected bool
} }
func TestSpanBatchTxConvert(t *testing.T) { func TestSpanBatchTxConvert(t *testing.T) {
cases := []spanBatchTxTest{ cases := []spanBatchTxTest{
{"legacy tx", 32, testutils.RandomLegacyTx}, {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false},
{"access list tx", 32, testutils.RandomAccessListTx}, {"legacy tx", 32, testutils.RandomLegacyTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, {"access list tx", 32, testutils.RandomAccessListTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true},
} }
for i, testCase := range cases { for i, testCase := range cases {
...@@ -29,6 +31,9 @@ func TestSpanBatchTxConvert(t *testing.T) { ...@@ -29,6 +31,9 @@ func TestSpanBatchTxConvert(t *testing.T) {
rng := rand.New(rand.NewSource(int64(0x1331 + i))) rng := rand.New(rand.NewSource(int64(0x1331 + i)))
chainID := big.NewInt(rng.Int63n(1000)) chainID := big.NewInt(rng.Int63n(1000))
signer := types.NewLondonSigner(chainID) signer := types.NewLondonSigner(chainID)
if !testCase.protected {
signer = types.HomesteadSigner{}
}
for txIdx := 0; txIdx < testCase.trials; txIdx++ { for txIdx := 0; txIdx < testCase.trials; txIdx++ {
tx := testCase.mkTx(rng, signer) tx := testCase.mkTx(rng, signer)
...@@ -54,9 +59,10 @@ func TestSpanBatchTxConvert(t *testing.T) { ...@@ -54,9 +59,10 @@ func TestSpanBatchTxConvert(t *testing.T) {
func TestSpanBatchTxRoundTrip(t *testing.T) { func TestSpanBatchTxRoundTrip(t *testing.T) {
cases := []spanBatchTxTest{ cases := []spanBatchTxTest{
{"legacy tx", 32, testutils.RandomLegacyTx}, {"unprotected legacy tx", 32, testutils.RandomLegacyTx, false},
{"access list tx", 32, testutils.RandomAccessListTx}, {"legacy tx", 32, testutils.RandomLegacyTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx}, {"access list tx", 32, testutils.RandomAccessListTx, true},
{"dynamic fee tx", 32, testutils.RandomDynamicFeeTx, true},
} }
for i, testCase := range cases { for i, testCase := range cases {
...@@ -64,6 +70,9 @@ func TestSpanBatchTxRoundTrip(t *testing.T) { ...@@ -64,6 +70,9 @@ func TestSpanBatchTxRoundTrip(t *testing.T) {
rng := rand.New(rand.NewSource(int64(0x1332 + i))) rng := rand.New(rand.NewSource(int64(0x1332 + i)))
chainID := big.NewInt(rng.Int63n(1000)) chainID := big.NewInt(rng.Int63n(1000))
signer := types.NewLondonSigner(chainID) signer := types.NewLondonSigner(chainID)
if !testCase.protected {
signer = types.HomesteadSigner{}
}
for txIdx := 0; txIdx < testCase.trials; txIdx++ { for txIdx := 0; txIdx < testCase.trials; txIdx++ {
tx := testCase.mkTx(rng, signer) tx := testCase.mkTx(rng, signer)
......
...@@ -14,6 +14,12 @@ import ( ...@@ -14,6 +14,12 @@ import (
"github.com/ethereum-optimism/optimism/op-service/testutils" "github.com/ethereum-optimism/optimism/op-service/testutils"
) )
type txTypeTest struct {
name string
mkTx func(rng *rand.Rand, signer types.Signer) *types.Transaction
signer types.Signer
}
func TestSpanBatchTxsContractCreationBits(t *testing.T) { func TestSpanBatchTxsContractCreationBits(t *testing.T) {
rng := rand.New(rand.NewSource(0x1234567)) rng := rand.New(rand.NewSource(0x1234567))
chainID := big.NewInt(rng.Int63n(1000)) chainID := big.NewInt(rng.Int63n(1000))
...@@ -304,57 +310,61 @@ func TestSpanBatchTxsRecoverV(t *testing.T) { ...@@ -304,57 +310,61 @@ func TestSpanBatchTxsRecoverV(t *testing.T) {
londonSigner := types.NewLondonSigner(chainID) londonSigner := types.NewLondonSigner(chainID)
totalblockTxCount := 20 + rng.Intn(100) totalblockTxCount := 20 + rng.Intn(100)
var spanBatchTxs spanBatchTxs cases := []txTypeTest{
var txTypes []int {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}},
var txSigs []spanBatchSignature {"legacy tx", testutils.RandomLegacyTx, londonSigner},
var originalVs []uint64 {"access list tx", testutils.RandomAccessListTx, londonSigner},
yParityBits := new(big.Int) {"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner},
protectedBits := new(big.Int)
totalLegacyTxCount := 0
for idx := 0; idx < totalblockTxCount; idx++ {
var tx *types.Transaction
// ensure unprotected txs are included
if idx < 4 || testutils.RandomBool(rng) {
tx = testutils.RandomLegacyTxNotProtected(rng)
} else {
tx = testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), londonSigner)
}
txType := tx.Type()
txTypes = append(txTypes, int(txType))
var txSig spanBatchSignature
v, r, s := tx.RawSignatureValues()
if txType == types.LegacyTxType {
protectedBit := uint(0)
if tx.Protected() {
protectedBit = uint(1)
}
protectedBits.SetBit(protectedBits, int(totalLegacyTxCount), protectedBit)
totalLegacyTxCount++
}
// Do not fill in txSig.V
txSig.r, _ = uint256.FromBig(r)
txSig.s, _ = uint256.FromBig(s)
txSigs = append(txSigs, txSig)
originalVs = append(originalVs, v.Uint64())
yParityBit, err := convertVToYParity(v.Uint64(), int(tx.Type()))
require.NoError(t, err)
yParityBits.SetBit(yParityBits, idx, yParityBit)
} }
spanBatchTxs.yParityBits = yParityBits for _, testCase := range cases {
spanBatchTxs.txSigs = txSigs t.Run(testCase.name, func(t *testing.T) {
spanBatchTxs.txTypes = txTypes var spanBatchTxs spanBatchTxs
spanBatchTxs.protectedBits = protectedBits var txTypes []int
// recover txSig.v var txSigs []spanBatchSignature
err := spanBatchTxs.recoverV(chainID) var originalVs []uint64
require.NoError(t, err) yParityBits := new(big.Int)
protectedBits := new(big.Int)
totalLegacyTxCount := 0
for idx := 0; idx < totalblockTxCount; idx++ {
tx := testCase.mkTx(rng, testCase.signer)
txType := tx.Type()
txTypes = append(txTypes, int(txType))
var txSig spanBatchSignature
v, r, s := tx.RawSignatureValues()
if txType == types.LegacyTxType {
protectedBit := uint(0)
if tx.Protected() {
protectedBit = uint(1)
}
protectedBits.SetBit(protectedBits, int(totalLegacyTxCount), protectedBit)
totalLegacyTxCount++
}
// Do not fill in txSig.V
txSig.r, _ = uint256.FromBig(r)
txSig.s, _ = uint256.FromBig(s)
txSigs = append(txSigs, txSig)
originalVs = append(originalVs, v.Uint64())
yParityBit, err := convertVToYParity(v.Uint64(), int(tx.Type()))
require.NoError(t, err)
yParityBits.SetBit(yParityBits, idx, yParityBit)
}
var recoveredVs []uint64 spanBatchTxs.yParityBits = yParityBits
for _, txSig := range spanBatchTxs.txSigs { spanBatchTxs.txSigs = txSigs
recoveredVs = append(recoveredVs, txSig.v) spanBatchTxs.txTypes = txTypes
} spanBatchTxs.protectedBits = protectedBits
// recover txSig.v
err := spanBatchTxs.recoverV(chainID)
require.NoError(t, err)
require.Equal(t, originalVs, recoveredVs, "recovered v mismatch") var recoveredVs []uint64
for _, txSig := range spanBatchTxs.txSigs {
recoveredVs = append(recoveredVs, txSig.v)
}
require.Equal(t, originalVs, recoveredVs, "recovered v mismatch")
})
}
} }
func TestSpanBatchTxsRoundTrip(t *testing.T) { func TestSpanBatchTxsRoundTrip(t *testing.T) {
...@@ -388,24 +398,35 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) { ...@@ -388,24 +398,35 @@ func TestSpanBatchTxsRoundTrip(t *testing.T) {
func TestSpanBatchTxsRoundTripFullTxs(t *testing.T) { func TestSpanBatchTxsRoundTripFullTxs(t *testing.T) {
rng := rand.New(rand.NewSource(0x13377331)) rng := rand.New(rand.NewSource(0x13377331))
chainID := big.NewInt(rng.Int63n(1000)) chainID := big.NewInt(rng.Int63n(1000))
signer := types.NewLondonSigner(chainID) londonSigner := types.NewLondonSigner(chainID)
for i := 0; i < 4; i++ {
totalblockTxCounts := uint64(1 + rng.Int()&0xFF)
var txs [][]byte
for i := 0; i < int(totalblockTxCounts); i++ {
tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer)
rawTx, err := tx.MarshalBinary()
require.NoError(t, err)
txs = append(txs, rawTx)
}
sbt, err := newSpanBatchTxs(txs, chainID)
require.NoError(t, err)
txs2, err := sbt.fullTxs(chainID) cases := []txTypeTest{
require.NoError(t, err) {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}},
{"legacy tx", testutils.RandomLegacyTx, londonSigner},
{"access list tx", testutils.RandomAccessListTx, londonSigner},
{"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner},
}
require.Equal(t, txs, txs2) for _, testCase := range cases {
t.Run(testCase.name, func(t *testing.T) {
for i := 0; i < 4; i++ {
totalblockTxCounts := uint64(1 + rng.Int()&0xFF)
var txs [][]byte
for i := 0; i < int(totalblockTxCounts); i++ {
tx := testCase.mkTx(rng, testCase.signer)
rawTx, err := tx.MarshalBinary()
require.NoError(t, err)
txs = append(txs, rawTx)
}
sbt, err := newSpanBatchTxs(txs, chainID)
require.NoError(t, err)
txs2, err := sbt.fullTxs(chainID)
require.NoError(t, err)
require.Equal(t, txs, txs2)
}
})
} }
} }
...@@ -427,24 +448,35 @@ func TestSpanBatchTxsRecoverVInvalidTxType(t *testing.T) { ...@@ -427,24 +448,35 @@ func TestSpanBatchTxsRecoverVInvalidTxType(t *testing.T) {
func TestSpanBatchTxsFullTxNotEnoughTxTos(t *testing.T) { func TestSpanBatchTxsFullTxNotEnoughTxTos(t *testing.T) {
rng := rand.New(rand.NewSource(0x13572468)) rng := rand.New(rand.NewSource(0x13572468))
chainID := big.NewInt(rng.Int63n(1000)) chainID := big.NewInt(rng.Int63n(1000))
signer := types.NewLondonSigner(chainID) londonSigner := types.NewLondonSigner(chainID)
totalblockTxCounts := uint64(1 + rng.Int()&0xFF) cases := []txTypeTest{
var txs [][]byte {"unprotected legacy tx", testutils.RandomLegacyTx, types.HomesteadSigner{}},
for i := 0; i < int(totalblockTxCounts); i++ { {"legacy tx", testutils.RandomLegacyTx, londonSigner},
tx := testutils.RandomTx(rng, new(big.Int).SetUint64(rng.Uint64()), signer) {"access list tx", testutils.RandomAccessListTx, londonSigner},
rawTx, err := tx.MarshalBinary() {"dynamic fee tx", testutils.RandomDynamicFeeTx, londonSigner},
require.NoError(t, err)
txs = append(txs, rawTx)
} }
sbt, err := newSpanBatchTxs(txs, chainID)
require.NoError(t, err)
// drop single to field for _, testCase := range cases {
sbt.txTos = sbt.txTos[:len(sbt.txTos)-2] t.Run(testCase.name, func(t *testing.T) {
totalblockTxCounts := uint64(1 + rng.Int()&0xFF)
var txs [][]byte
for i := 0; i < int(totalblockTxCounts); i++ {
tx := testCase.mkTx(rng, testCase.signer)
rawTx, err := tx.MarshalBinary()
require.NoError(t, err)
txs = append(txs, rawTx)
}
sbt, err := newSpanBatchTxs(txs, chainID)
require.NoError(t, err)
// drop single to field
sbt.txTos = sbt.txTos[:len(sbt.txTos)-2]
_, err = sbt.fullTxs(chainID) _, err = sbt.fullTxs(chainID)
require.EqualError(t, err, "tx to not enough") require.EqualError(t, err, "tx to not enough")
})
}
} }
func TestSpanBatchTxsMaxContractCreationBitsLength(t *testing.T) { func TestSpanBatchTxsMaxContractCreationBitsLength(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment