Skip to content

Commit

Permalink
preconf api as its own service
Browse files Browse the repository at this point in the history
  • Loading branch information
cyberhorsey committed Jul 2, 2024
1 parent 7e4e83a commit d798b17
Show file tree
Hide file tree
Showing 19 changed files with 310 additions and 215 deletions.
15 changes: 8 additions & 7 deletions packages/taiko-client/cmd/flags/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
)

var (
commonCategory = "COMMON"
metricsCategory = "METRICS"
loggingCategory = "LOGGING"
driverCategory = "DRIVER"
proposerCategory = "PROPOSER"
proverCategory = "PROVER"
txmgrCategory = "TX_MANAGER"
commonCategory = "COMMON"
metricsCategory = "METRICS"
loggingCategory = "LOGGING"
driverCategory = "DRIVER"
proposerCategory = "PROPOSER"
proverCategory = "PROVER"
txmgrCategory = "TX_MANAGER"
preconfApiCategory = "PRECONF_API"
)

// Required flags used by all client software.
Expand Down
24 changes: 24 additions & 0 deletions packages/taiko-client/cmd/flags/preconfapi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package flags

import (
"github.com/urfave/cli/v2"
)

// Required flags used by preconfirmations api.
var (
PreconfAPIHTTPServerPort = &cli.Uint64Flag{
Name: "preconfapi.port",
Usage: "Port to expose for http server",
Category: preconfApiCategory,
Value: 9871,
EnvVars: []string{"PRECONFAPI_PORT"},
}
)

// PreconfAPIFlags contains all preconfirmations API flags.
var PreconfAPIFlags = []cli.Flag{
TaikoL1Address,
TxGasLimit,
PreconfAPIHTTPServerPort,
BlobAllowed,
}
8 changes: 0 additions & 8 deletions packages/taiko-client/cmd/flags/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,6 @@ var (
Category: proposerCategory,
EnvVars: []string{"PRECONFIRMATION_RPC"},
}
ProposerHTTPServerPort = &cli.Uint64Flag{
Name: "proposer.port",
Usage: "Port to expose for http server",
Category: proverCategory,
Value: 9871,
EnvVars: []string{"PROPOSER_PORT"},
}
)

// ProposerFlags All proposer flags.
Expand Down Expand Up @@ -180,5 +173,4 @@ var ProposerFlags = MergeFlags(CommonFlags, []cli.Flag{
BlobAllowed,
L1BlockBuilderTip,
PreconfirmationRPC,
ProposerHTTPServerPort,
}, TxmgrFlags)
8 changes: 8 additions & 0 deletions packages/taiko-client/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/taikoxyz/taiko-mono/packages/taiko-client/cmd/utils"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/driver"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/internal/version"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/preconfapi"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/proposer"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/prover"
)
Expand Down Expand Up @@ -48,6 +49,13 @@ func main() {
Description: "Taiko prover software",
Action: utils.SubcommandAction(new(prover.Prover)),
},
{
Name: "preconfapi",
Flags: flags.PreconfAPIFlags,
Usage: "Starts the preconfirmation API software",
Description: "Taiko preconfirmation API software",
Action: utils.SubcommandAction(new(preconfapi.PreconfAPI)),
},
}

if err := app.Run(os.Args); err != nil {
Expand Down
69 changes: 69 additions & 0 deletions packages/taiko-client/preconfapi/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package preconfapi

import (
"context"
"errors"
"fmt"
"net/http"

"github.com/ethereum/go-ethereum/log"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/preconfapi/builder"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/preconfapi/server"
"github.com/urfave/cli/v2"
)

type PreconfAPI struct {
*Config
server *server.PreconfAPIServer
}

// InitFromCli New initializes the given proposer instance based on the command line flags.
func (p *PreconfAPI) InitFromCli(ctx context.Context, c *cli.Context) error {
cfg, err := NewConfigFromCliContext(c)
if err != nil {
return err
}

return p.InitFromConfig(ctx, cfg)
}

func (p *PreconfAPI) InitFromConfig(ctx context.Context, cfg *Config) (err error) {
var txBuilder builder.TxBuilder
if cfg.BlobAllowed {
txBuilder = builder.NewBlobTransactionBuilder(
cfg.TaikoL1Address,
cfg.ProposeBlockTxGasLimit,
)
} else {
// TODO: calldata builder
}

// Prover server
if p.server, err = server.New(&server.NewPreconfAPIServerOpts{
TxBuilder: txBuilder,
}); err != nil {
return err
}

return nil
}

func (p *PreconfAPI) Start() error {
go func() {
if err := p.server.Start(fmt.Sprintf(":%v", p.HTTPPort)); !errors.Is(err, http.ErrServerClosed) {
log.Crit("Failed to start http server", "error", err)
}
}()
return nil
}

// Close closes the proposer instance.
func (p *PreconfAPI) Close(ctx context.Context) {
if err := p.server.Shutdown(ctx); err != nil {
log.Error("Failed to shut down prover server", "error", err)
}
}

func (p *PreconfAPI) Name() string {
return "preconfapi"
}
92 changes: 92 additions & 0 deletions packages/taiko-client/preconfapi/builder/blob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package builder

import (
"context"

"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"

"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/encoding"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/internal/utils"
)

// BlobTransactionBuilder is responsible for building a TaikoL1.proposeBlock transaction with txList
// bytes saved in blob.
type BlobTransactionBuilder struct {
taikoL1Address common.Address
gasLimit uint64
}

// NewBlobTransactionBuilder creates a new BlobTransactionBuilder instance based on giving configurations.
func NewBlobTransactionBuilder(
taikoL1Address common.Address,
gasLimit uint64,
) *BlobTransactionBuilder {
return &BlobTransactionBuilder{
taikoL1Address,
gasLimit,
}
}

// BuildUnsigned implements the ProposeBlockTransactionBuilder interface to
// return an unsigned transaction, intended for preconfirmations.
func (b *BlobTransactionBuilder) BuildUnsigned(
ctx context.Context,
txListBytes []byte,
l1StateBlockNumber uint32,
timestamp uint64,
coinbase common.Address,
extraData [32]byte,
) (*types.Transaction, error) {
compressedTxListBytes, err := utils.Compress(txListBytes)
if err != nil {
return nil, err
}

var blob = &eth.Blob{}
if err := blob.FromData(compressedTxListBytes); err != nil {
return nil, err
}

var (
to = &b.taikoL1Address
data []byte
)

// ABI encode the TaikoL1.proposeBlock parameters.
encodedParams, err := encoding.EncodeBlockParams(&encoding.BlockParams{
ExtraData: extraData,
Coinbase: coinbase,
Signature: []byte{}, // no longer checked
L1StateBlockNumber: l1StateBlockNumber,
Timestamp: timestamp,
})
if err != nil {
return nil, err
}

data, err = encoding.TaikoL1ABI.Pack("proposeBlock", encodedParams, []byte{})
if err != nil {
return nil, err
}

sidecar, blobHashes, err := txmgr.MakeSidecar([]*eth.Blob{blob})
if err != nil {
return nil, err
}

blobTx := &types.BlobTx{
To: *to,
Value: nil, // maxFee / prover selecting no longer happens
Gas: b.gasLimit,
Data: data,
Sidecar: sidecar,
BlobHashes: blobHashes,
}

tx := types.NewTx(blobTx)

return tx, nil
}
39 changes: 39 additions & 0 deletions packages/taiko-client/preconfapi/builder/calldata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package builder

import (
"context"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

// CalldataTransactionBuilder is responsible for building a TaikoL1.proposeBlock transaction with txList
// bytes saved in blob.
type CalldataTransactionBuilder struct {
taikoL1Address common.Address
gasLimit uint64
}

// NewCalldataTransactionBuilder creates a new CalldataTransactionBuilder instance based on giving configurations.
func NewCalldataTransactionBuilder(
taikoL1Address common.Address,
gasLimit uint64,
) *CalldataTransactionBuilder {
return &CalldataTransactionBuilder{
taikoL1Address,
gasLimit,
}
}

// BuildUnsigned implements the ProposeBlockTransactionBuilder interface to
// return an unsigned transaction, intended for preconfirmations.
func (b *CalldataTransactionBuilder) BuildUnsigned(
_ context.Context,
_ []byte,
_ uint32,
_ uint64,
_ common.Address,
_ [32]byte,
) (*types.Transaction, error) {
return &types.Transaction{}, nil
}
19 changes: 19 additions & 0 deletions packages/taiko-client/preconfapi/builder/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package builder

import (
"context"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)

type TxBuilder interface {
BuildUnsigned(
ctx context.Context,
txListBytes []byte,
l1StateBlockNumber uint32,
timestamp uint64,
coinbase common.Address,
extraData [32]byte,
) (*types.Transaction, error)
}
25 changes: 25 additions & 0 deletions packages/taiko-client/preconfapi/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package preconfapi

import (
"github.com/ethereum/go-ethereum/common"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/cmd/flags"
"github.com/urfave/cli/v2"
)

type Config struct {
TaikoL1Address common.Address
BlobAllowed bool
HTTPPort uint64
ProposeBlockTxGasLimit uint64
}

// NewConfigFromCliContext initializes a Config instance from
// command line flags.
func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
return &Config{
TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)),
BlobAllowed: c.Bool(flags.BlobAllowed.Name),
HTTPPort: c.Uint64(flags.PreconfAPIHTTPServerPort.Name),
ProposeBlockTxGasLimit: c.Uint64(flags.TxGasLimit.Name),
}, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,6 @@ import (
// @license.name MIT
// @license.url https://github.com/taikoxyz/taiko-mono/packages/taiko-client/blob/main/LICENSE.md

// Status represents the current proposer server status.
type Status struct {
}

// GetStatus handles a query to the current proposer server status.
//
// @Summary Get current proposer server status
// @ID get-status
// @Accept json
// @Produce json
// @Success 200 {object} Status
// @Router /status [get]
func (s *ProposerServer) GetStatus(c echo.Context) error {
return c.JSON(http.StatusOK, &Status{})
}

type buildBlockRequest struct {
L1StateBlockNumber uint32 `json:"l1StateBlockNumber"`
Timestamp uint64 `json:"timestamp"`
Expand All @@ -62,7 +46,7 @@ type buildBlockResponse struct {
// @Produce json
// @Success 200 {object} BuildBlockResponse
// @Router /block/build [get]
func (s *ProposerServer) BuildBlock(c echo.Context) error {
func (s *PreconfAPIServer) BuildBlock(c echo.Context) error {
req := &buildBlockRequest{}
if err := c.Bind(req); err != nil {
return c.JSON(http.StatusUnprocessableEntity, err)
Expand Down
Loading

0 comments on commit d798b17

Please sign in to comment.