diff --git a/packages/taiko-client/driver/chain_syncer/event/blocks_inserter/pacaya.go b/packages/taiko-client/driver/chain_syncer/event/blocks_inserter/pacaya.go index 889d0a3543..b95aa65b78 100644 --- a/packages/taiko-client/driver/chain_syncer/event/blocks_inserter/pacaya.go +++ b/packages/taiko-client/driver/chain_syncer/event/blocks_inserter/pacaya.go @@ -430,28 +430,6 @@ func (i *BlocksInserterPacaya) insertPreconfBlockFromExecutionPayload( return i.rpc.L2.HeaderByHash(ctx, payload.BlockHash) } -// RemovePreconfBlocks removes preconfirmation blocks from the L2 execution engine. -func (i *BlocksInserterPacaya) RemovePreconfBlocks(ctx context.Context, newLastBlockID uint64) error { - i.mutex.Lock() - defer i.mutex.Unlock() - - newHead, err := i.rpc.L2.HeaderByNumber(ctx, new(big.Int).SetUint64(newLastBlockID)) - if err != nil { - return err - } - - fc := &engine.ForkchoiceStateV1{HeadBlockHash: newHead.Hash()} - fcRes, err := i.rpc.L2Engine.ForkchoiceUpdate(ctx, fc, nil) - if err != nil { - return err - } - if fcRes.PayloadStatus.Status != engine.VALID { - return fmt.Errorf("unexpected ForkchoiceUpdate response status: %s", fcRes.PayloadStatus.Status) - } - - return nil -} - // IsBasedOnCanonicalChain checks if the given executable data is based on the canonical chain. func (i *BlocksInserterPacaya) IsBasedOnCanonicalChain( ctx context.Context, diff --git a/packages/taiko-client/driver/driver_test.go b/packages/taiko-client/driver/driver_test.go index 71b484da4d..1038f305bd 100644 --- a/packages/taiko-client/driver/driver_test.go +++ b/packages/taiko-client/driver/driver_test.go @@ -429,34 +429,6 @@ func (s *DriverTestSuite) TestInsertPreconfBlocks() { s.Equal(l2Head2.Hash(), l1Origin2.L2BlockHash) s.Equal(common.Hash{}, l1Origin2.L1BlockHash) s.True(l1Origin2.IsPreconfBlock()) - - // Remove one preconfirmation block - res, err = resty.New(). - R(). - SetBody(&preconfblocks.RemovePreconfBlocksRequestBody{NewLastBlockID: l2Head3.Number().Uint64() - 1}). - Delete(s.preconfServerURL.String() + "/preconfBlocks") - s.Nil(err) - s.True(res.IsSuccess()) - - l2Head4, err := s.d.rpc.L2.BlockByNumber(context.Background(), nil) - s.Nil(err) - s.Equal(l2Head2.Hash(), l2Head4.Hash()) - - // Propose 3 valid L2 blocks - s.ProposeAndInsertEmptyBlocks(s.p, s.d.ChainSyncer().EventSyncer()) - - l2Head5, err := s.d.rpc.L2.BlockByNumber(context.Background(), nil) - s.Nil(err) - s.Equal(l2Head2.Number().Uint64()+2, l2Head5.Number().Uint64()) - s.Equal(1, len(l2Head5.Transactions())) - - l1Origin3, err := s.RPCClient.L2.L1OriginByID(context.Background(), l2Head5.Number()) - s.Nil(err) - s.Equal(l2Head2.Number().Uint64()+2, l1Origin3.BlockID.Uint64()) - s.Equal(l2Head5.Hash(), l1Origin3.L2BlockHash) - s.NotZero(l1Origin3.L1BlockHeight.Uint64()) - s.NotEmpty(l1Origin3.L1BlockHash) - s.False(l1Origin3.IsPreconfBlock()) } func (s *DriverTestSuite) TestInsertPreconfBlocksNotReorg() { diff --git a/packages/taiko-client/driver/preconf_blocks/api.go b/packages/taiko-client/driver/preconf_blocks/api.go index 52e4186c72..19c5cdb436 100644 --- a/packages/taiko-client/driver/preconf_blocks/api.go +++ b/packages/taiko-client/driver/preconf_blocks/api.go @@ -7,7 +7,6 @@ import ( "net/http" "github.com/ethereum-optimism/optimism/op-service/eth" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -268,119 +267,6 @@ func (s *PreconfBlockAPIServer) BuildPreconfBlock(c echo.Context) error { return c.JSON(http.StatusOK, BuildPreconfBlockResponseBody{BlockHeader: header}) } -// RemovePreconfBlocksRequestBody represents a request body when resetting the backend -// L2 execution engine preconfirmation head. -type RemovePreconfBlocksRequestBody struct { - // @param newLastBlockID uint64 New last block ID of the blockchain, it should - // @param not smaller than the canonical chain's highest block ID. - NewLastBlockID uint64 `json:"newLastBlockId"` -} - -// RemovePreconfBlocksResponseBody represents a response body when resetting the backend -// L2 execution engine preconfirmation head. -type RemovePreconfBlocksResponseBody struct { - // @param lastBlockID uint64 Current highest block ID of the blockchain (including preconfirmation blocks) - LastBlockID uint64 `json:"lastBlockId"` - // @param lastProposedBlockID uint64 Highest block ID of the cnonical chain - LastProposedBlockID uint64 `json:"lastProposedBlockID"` - // @param headsRemoved uint64 Number of preconfirmation heads removed - HeadsRemoved uint64 `json:"headsRemoved"` -} - -// RemovePreconfBlocks removes the backend L2 execution engine preconfirmation head. -// -// @Description Remove all preconfirmation blocks from the blockchain beyond the specified block height, -// @Description ensuring the latest block ID does not exceed the given height. This method will fail if -// @Description the block with an ID one greater than the specified height is not a preconfirmation block. If the -// @Description specified block height is greater than the latest preconfirmation block ID, the method will succeed -// @Description without modifying the blockchain. -// @Param body body RemovePreconfBlocksRequestBody true "preconfirmation blocks removing request body" -// @Accept json -// @Produce json -// @Success 200 {object} RemovePreconfBlocksResponseBody -// @Router /preconfBlocks [delete] -func (s *PreconfBlockAPIServer) RemovePreconfBlocks(c echo.Context) error { - if s.rpc.PacayaClients.TaikoWrapper != nil { - // Check if the preconfirmation is enabled. - preconfRouter, err := s.rpc.GetPreconfRouterPacaya(&bind.CallOpts{Context: c.Request().Context()}) - if err != nil { - return s.returnError(c, http.StatusInternalServerError, err) - } - if preconfRouter == rpc.ZeroAddress { - log.Warn("Preconfirmation is disabled via taikoWrapper", "preconfRouter", preconfRouter.Hex()) - return s.returnError( - c, - http.StatusInternalServerError, - errors.New("preconfirmation is disabled via taikoWrapper"), - ) - } - } - - // Parse the request body. - reqBody := new(RemovePreconfBlocksRequestBody) - if err := c.Bind(reqBody); err != nil { - return s.returnError(c, http.StatusUnprocessableEntity, err) - } - - // Request body validation. - canonicalHeadL1Origin, err := s.rpc.L2.HeadL1Origin(c.Request().Context()) - if err != nil && err.Error() != ethereum.NotFound.Error() { - return s.returnError(c, http.StatusInternalServerError, err) - } - - currentHead, err := s.rpc.L2.HeaderByNumber(c.Request().Context(), nil) - if err != nil { - return s.returnError(c, http.StatusInternalServerError, err) - } - - if canonicalHeadL1Origin != nil && reqBody.NewLastBlockID < canonicalHeadL1Origin.BlockID.Uint64() { - return s.returnError( - c, - http.StatusBadRequest, - errors.New("newLastBlockId must not be smaller than the canonical chain's highest block ID"), - ) - } - - log.Info( - "New preconfirmation block removing request", - "newLastBlockId", reqBody.NewLastBlockID, - "currentHead", currentHead.Number.Uint64(), - ) - - if err := s.chainSyncer.RemovePreconfBlocks(c.Request().Context(), reqBody.NewLastBlockID); err != nil { - return s.returnError(c, http.StatusBadRequest, err) - } - - newHead, err := s.rpc.L2.HeaderByNumber(c.Request().Context(), nil) - if err != nil { - return s.returnError(c, http.StatusInternalServerError, err) - } - - var lastBlockID uint64 - if canonicalHeadL1Origin != nil { - lastBlockID = canonicalHeadL1Origin.BlockID.Uint64() - } - - // If current block number is less than the highest unsafe L2 payload block ID, - // update the highest unsafe L2 payload block ID. - if newHead.Number.Uint64() < s.highestUnsafeL2PayloadBlockID { - s.updateHighestUnsafeL2Payload(newHead.Number.Uint64()) - } - - log.Debug( - "Removed preconfirmation blocks", - "newHead", newHead.Number.Uint64(), - "lastBlockID", lastBlockID, - "headsRemoved", currentHead.Number.Uint64()-newHead.Number.Uint64(), - ) - - return c.JSON(http.StatusOK, RemovePreconfBlocksResponseBody{ - LastBlockID: newHead.Number.Uint64(), - LastProposedBlockID: lastBlockID, - HeadsRemoved: currentHead.Number.Uint64() - newHead.Number.Uint64(), - }) -} - // HealthCheck is the endpoints for probes. // // @Summary Get current server health status diff --git a/packages/taiko-client/driver/preconf_blocks/server.go b/packages/taiko-client/driver/preconf_blocks/server.go index 5738480582..5a6782329d 100644 --- a/packages/taiko-client/driver/preconf_blocks/server.go +++ b/packages/taiko-client/driver/preconf_blocks/server.go @@ -41,7 +41,6 @@ var ( // preconfBlockChainSyncer is an interface for preconfirmation block chain syncer. type preconfBlockChainSyncer interface { InsertPreconfBlocksFromExecutionPayloads(context.Context, []*eth.ExecutionPayload, bool) ([]*types.Header, error) - RemovePreconfBlocks(ctx context.Context, newLastBlockID uint64) error } // @title Taiko Preconfirmation Block Server API @@ -186,7 +185,6 @@ func (s *PreconfBlockAPIServer) configureRoutes() { s.echo.GET("/healthz", s.HealthCheck) s.echo.GET("/status", s.GetStatus) s.echo.POST("/preconfBlocks", s.BuildPreconfBlock) - s.echo.DELETE("/preconfBlocks", s.RemovePreconfBlocks) // WebSocket routes s.echo.GET("/ws", s.ws.handleWebSocket)