Skip to content

Commit 9705881

Browse files
committed
feat: add more tx list checks in ValidateExecutionPayload
1 parent a169228 commit 9705881

File tree

5 files changed

+76
-26
lines changed

5 files changed

+76
-26
lines changed

packages/taiko-client/driver/chain_syncer/chain_syncer.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,7 @@ func New(
4747
go tracker.Track(ctx)
4848

4949
beaconSyncer := beaconsync.NewSyncer(ctx, rpc, state, tracker)
50-
blobSyncer, err := blob.NewSyncer(
51-
ctx,
52-
rpc,
53-
state,
54-
tracker,
55-
blobServerEndpoint,
56-
)
50+
blobSyncer, err := blob.NewSyncer(ctx, rpc, state, tracker, blobServerEndpoint)
5751
if err != nil {
5852
return nil, err
5953
}

packages/taiko-client/driver/driver.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ func (d *Driver) InitFromConfig(ctx context.Context, cfg *Config) (err error) {
118118
if d.preconfBlockServer, err = preconfBlocks.New(
119119
d.PreconfBlockServerCORSOrigins,
120120
d.PreconfBlockServerJWTSecret,
121+
d.TaikoL2Address,
121122
d.l2ChainSyncer.BlobSyncer().BlocksInserterPacaya(),
122123
d.rpc,
123124
); err != nil {

packages/taiko-client/driver/driver_test.go

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ func (s *DriverTestSuite) TestOnUnsafeL2Payload() {
564564
b, err := utils.EncodeAndCompressTxList(types.Transactions{anchorTx})
565565
s.Nil(err)
566566

567-
// failed to decode txList: rlp: expected input list for types.Transactions
568567
payload := &eth.ExecutionPayload{
569568
ParentHash: l2Head1.Hash(),
570569
FeeRecipient: s.TestAddr,
@@ -597,6 +596,45 @@ func (s *DriverTestSuite) TestOnUnsafeL2Payload() {
597596
s.Equal(anchorTx.Hash(), l2Head2.Transactions()[0].Hash())
598597
}
599598

599+
func (s *DriverTestSuite) TestOnUnsafeL2PayloadWithInvalidPayload() {
600+
s.ForkIntoPacaya(s.p, s.d.ChainSyncer().BlobSyncer())
601+
// Propose some valid L2 blocks
602+
s.ProposeAndInsertEmptyBlocks(s.p, s.d.ChainSyncer().BlobSyncer())
603+
604+
l2Head1, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil)
605+
s.Nil(err)
606+
607+
b, err := utils.Compress(testutils.RandomBytes(32))
608+
s.Nil(err)
609+
610+
baseFee, overflow := uint256.FromBig(common.Big256)
611+
s.False(overflow)
612+
613+
payload := &eth.ExecutionPayload{
614+
ParentHash: l2Head1.Hash(),
615+
FeeRecipient: s.TestAddr,
616+
PrevRandao: eth.Bytes32(testutils.RandomHash()),
617+
BlockNumber: eth.Uint64Quantity(l2Head1.Number.Uint64() + 1),
618+
GasLimit: eth.Uint64Quantity(l2Head1.GasLimit),
619+
Timestamp: eth.Uint64Quantity(time.Now().Unix()),
620+
ExtraData: l2Head1.Extra,
621+
BaseFeePerGas: eth.Uint256Quantity(*baseFee),
622+
Transactions: []eth.Data{b},
623+
Withdrawals: &types.Withdrawals{},
624+
}
625+
626+
s.Nil(s.d.preconfBlockServer.OnUnsafeL2Payload(
627+
context.Background(),
628+
peer.ID(testutils.RandomBytes(32)),
629+
&eth.ExecutionPayloadEnvelope{ExecutionPayload: payload},
630+
))
631+
632+
l2Head2, err := s.d.rpc.L2.BlockByNumber(context.Background(), nil)
633+
s.Nil(err)
634+
s.Equal(l2Head1.Number.Uint64(), l2Head2.Number().Uint64())
635+
s.Equal(l2Head1.Hash(), l2Head2.Hash())
636+
}
637+
600638
func (s *DriverTestSuite) TestOnUnsafeL2PayloadWithMissingAncients() {
601639
s.ForkIntoPacaya(s.p, s.d.ChainSyncer().BlobSyncer())
602640
// Propose some valid L2 blocks

packages/taiko-client/driver/preconf_blocks/server.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ import (
1515
"github.com/ethereum/go-ethereum/core/rawdb"
1616
"github.com/ethereum/go-ethereum/core/types"
1717
"github.com/ethereum/go-ethereum/log"
18+
"github.com/ethereum/go-ethereum/rlp"
1819
"github.com/holiman/uint256"
1920
echojwt "github.com/labstack/echo-jwt/v4"
2021
"github.com/labstack/echo/v4"
2122
"github.com/labstack/echo/v4/middleware"
2223
"github.com/libp2p/go-libp2p/core/peer"
2324

24-
txListDecompressor "github.com/taikoxyz/taiko-mono/packages/taiko-client/driver/txlist_decompressor"
2525
"github.com/taikoxyz/taiko-mono/packages/taiko-client/internal/metrics"
2626
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/rpc"
27+
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/utils"
28+
validator "github.com/taikoxyz/taiko-mono/packages/taiko-client/prover/anchor_tx_validator"
2729
)
2830

2931
// preconfBlockChainSyncer is an interface for preconf block chain syncer.
@@ -44,10 +46,10 @@ type preconfBlockChainSyncer interface {
4446
// @license.url https://github.com/taikoxyz/taiko-mono/blob/main/LICENSE.md
4547
// PreconfBlockAPIServer represents a preconfirmation block server instance.
4648
type PreconfBlockAPIServer struct {
47-
echo *echo.Echo
48-
chainSyncer preconfBlockChainSyncer
49-
rpc *rpc.Client
50-
txListDecompressor *txListDecompressor.TxListDecompressor
49+
echo *echo.Echo
50+
chainSyncer preconfBlockChainSyncer
51+
rpc *rpc.Client
52+
anchorValidator *validator.AnchorTxValidator
5153
// P2P network for preconf block propagation
5254
p2pNode *p2p.NodeP2P
5355
p2pSigner p2p.Signer
@@ -60,25 +62,22 @@ type PreconfBlockAPIServer struct {
6062
func New(
6163
cors string,
6264
jwtSecret []byte,
65+
taikoAnchorAddress common.Address,
6366
chainSyncer preconfBlockChainSyncer,
6467
cli *rpc.Client,
6568
) (*PreconfBlockAPIServer, error) {
66-
protocolConfigs, err := cli.GetProtocolConfigs(nil)
69+
anchorValidator, err := validator.New(taikoAnchorAddress, cli.L2.ChainID, cli)
6770
if err != nil {
68-
return nil, fmt.Errorf("failed to fetch protocol configs: %w", err)
71+
return nil, err
6972
}
7073

7174
server := &PreconfBlockAPIServer{
72-
echo: echo.New(),
73-
chainSyncer: chainSyncer,
74-
txListDecompressor: txListDecompressor.NewTxListDecompressor(
75-
uint64(protocolConfigs.BlockMaxGasLimit()),
76-
uint64(rpc.BlobBytes),
77-
cli.L2.ChainID,
78-
),
79-
rpc: cli,
80-
payloadsCache: newPayloadQueue(),
81-
lookahead: &Lookahead{},
75+
echo: echo.New(),
76+
anchorValidator: anchorValidator,
77+
chainSyncer: chainSyncer,
78+
rpc: cli,
79+
payloadsCache: newPayloadQueue(),
80+
lookahead: &Lookahead{},
8281
}
8382

8483
server.echo.HideBanner = true
@@ -375,6 +374,22 @@ func (s *PreconfBlockAPIServer) ValidateExecutionPayload(payload *eth.ExecutionP
375374
if len(payload.Transactions[0]) > eth.MaxBlobDataSize {
376375
return errors.New("compressed transactions size exceeds max blob data size")
377376
}
377+
378+
var txs types.Transactions
379+
b, err := utils.DecompressPacaya(payload.Transactions[0])
380+
if err != nil {
381+
return fmt.Errorf("invalid zlib bytes for transactions: %w", err)
382+
}
383+
if err := rlp.DecodeBytes(b, &txs); err != nil {
384+
return fmt.Errorf("invalid RLP bytes for transactions: %w", err)
385+
}
386+
if len(txs) == 0 {
387+
return errors.New("empty transactions list, missing anchor transaction")
388+
}
389+
if err := s.anchorValidator.ValidateAnchorTx(txs[0]); err != nil {
390+
return fmt.Errorf("invalid anchor transaction: %w", err)
391+
}
392+
378393
return nil
379394
}
380395

packages/taiko-client/driver/preconf_blocks/server_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ package preconfblocks
22

33
import (
44
"context"
5+
"os"
56
"testing"
67

8+
"github.com/ethereum/go-ethereum/common"
79
"github.com/ethereum/go-ethereum/log"
810
"github.com/stretchr/testify/suite"
911

@@ -17,7 +19,7 @@ type PreconfBlockAPIServerTestSuite struct {
1719

1820
func (s *PreconfBlockAPIServerTestSuite) SetupTest() {
1921
s.ClientTestSuite.SetupTest()
20-
server, err := New("*", nil, nil, s.RPCClient)
22+
server, err := New("*", nil, common.HexToAddress(os.Getenv("TAIKO_ANCHOR")), nil, s.RPCClient)
2123
s.Nil(err)
2224
s.s = server
2325
go func() {

0 commit comments

Comments
 (0)