Skip to content

feat(taiko-client): introduce --prover.localProposerAddresses flag #19517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions packages/taiko-client/cmd/flags/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ var (
Value: 10 * time.Second,
EnvVars: []string{"PROVER_PROOF_POLLING_INTERVAL"},
}
LocalProposerAddresses = &cli.StringSliceFlag{
Name: "prover.localProposerAddresses",
Usage: "Comma separated list of local proposer addresses, " +
"if set, prover will prove the batches proposed by these addresses before the assignment expiration time",
Category: proverCategory,
EnvVars: []string{"PROVER_LOCAL_PROPOSER_ADDRESSES"},
}
// Confirmations specific flag
BlockConfirmations = &cli.Uint64Flag{
Name: "prover.blockConfirmations",
Expand Down Expand Up @@ -128,6 +135,7 @@ var ProverFlags = MergeFlags(CommonFlags, []cli.Flag{
TaikoTokenAddress,
Allowance,
ProofPollingInterval,
LocalProposerAddresses,
BlockConfirmations,
RaikoRequestTimeout,
RaikoZKVMHostEndpoint,
Expand Down
57 changes: 35 additions & 22 deletions packages/taiko-client/prover/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/urfave/cli/v2"

"github.com/taikoxyz/taiko-mono/packages/taiko-client/cmd/flags"
Expand Down Expand Up @@ -38,6 +39,7 @@ type Config struct {
RaikoZKVMHostEndpoint string
RaikoJWT string
RaikoRequestTimeout time.Duration
LocalProposerAddresses []common.Address
BlockConfirmations uint64
TxmgrConfigs *txmgr.CLIConfig
PrivateTxmgrConfigs *txmgr.CLIConfig
Expand Down Expand Up @@ -80,29 +82,40 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
}
}

var localProposerAddresses []common.Address
for _, localProposerAddress := range c.StringSlice(flags.LocalProposerAddresses.Name) {
if !common.IsHexAddress(localProposerAddress) {
log.Debug("Invalid local proposer address", "address", localProposerAddress)
continue
}
addr := common.HexToAddress(localProposerAddress)
localProposerAddresses = append(localProposerAddresses, addr)
}

return &Config{
L1WsEndpoint: c.String(flags.L1WSEndpoint.Name),
L2WsEndpoint: c.String(flags.L2WSEndpoint.Name),
L2HttpEndpoint: c.String(flags.L2HTTPEndpoint.Name),
TaikoInboxAddress: common.HexToAddress(c.String(flags.TaikoInboxAddress.Name)),
TaikoAnchorAddress: common.HexToAddress(c.String(flags.TaikoAnchorAddress.Name)),
TaikoTokenAddress: common.HexToAddress(c.String(flags.TaikoTokenAddress.Name)),
ProverSetAddress: common.HexToAddress(c.String(flags.ProverSetAddress.Name)),
L1ProverPrivKey: l1ProverPrivKey,
RaikoHostEndpoint: c.String(flags.RaikoHostEndpoint.Name),
RaikoZKVMHostEndpoint: c.String(flags.RaikoZKVMHostEndpoint.Name),
RaikoJWT: common.Bytes2Hex(jwtSecret),
RaikoRequestTimeout: c.Duration(flags.RaikoRequestTimeout.Name),
StartingBatchID: startingBatchID,
Dummy: c.Bool(flags.Dummy.Name),
BackOffMaxRetries: c.Uint64(flags.BackOffMaxRetries.Name),
BackOffRetryInterval: c.Duration(flags.BackOffRetryInterval.Name),
ProveUnassignedBlocks: c.Bool(flags.ProveUnassignedBlocks.Name),
RPCTimeout: c.Duration(flags.RPCTimeout.Name),
ProveBatchesGasLimit: c.Uint64(flags.TxGasLimit.Name),
Allowance: allowance,
BlockConfirmations: c.Uint64(flags.BlockConfirmations.Name),
TxmgrConfigs: pkgFlags.InitTxmgrConfigsFromCli(c.String(flags.L1WSEndpoint.Name), l1ProverPrivKey, c),
L1WsEndpoint: c.String(flags.L1WSEndpoint.Name),
L2WsEndpoint: c.String(flags.L2WSEndpoint.Name),
L2HttpEndpoint: c.String(flags.L2HTTPEndpoint.Name),
TaikoInboxAddress: common.HexToAddress(c.String(flags.TaikoInboxAddress.Name)),
TaikoAnchorAddress: common.HexToAddress(c.String(flags.TaikoAnchorAddress.Name)),
TaikoTokenAddress: common.HexToAddress(c.String(flags.TaikoTokenAddress.Name)),
ProverSetAddress: common.HexToAddress(c.String(flags.ProverSetAddress.Name)),
L1ProverPrivKey: l1ProverPrivKey,
RaikoHostEndpoint: c.String(flags.RaikoHostEndpoint.Name),
RaikoZKVMHostEndpoint: c.String(flags.RaikoZKVMHostEndpoint.Name),
RaikoJWT: common.Bytes2Hex(jwtSecret),
RaikoRequestTimeout: c.Duration(flags.RaikoRequestTimeout.Name),
StartingBatchID: startingBatchID,
Dummy: c.Bool(flags.Dummy.Name),
BackOffMaxRetries: c.Uint64(flags.BackOffMaxRetries.Name),
BackOffRetryInterval: c.Duration(flags.BackOffRetryInterval.Name),
ProveUnassignedBlocks: c.Bool(flags.ProveUnassignedBlocks.Name),
RPCTimeout: c.Duration(flags.RPCTimeout.Name),
ProveBatchesGasLimit: c.Uint64(flags.TxGasLimit.Name),
Allowance: allowance,
LocalProposerAddresses: localProposerAddresses,
BlockConfirmations: c.Uint64(flags.BlockConfirmations.Name),
TxmgrConfigs: pkgFlags.InitTxmgrConfigsFromCli(c.String(flags.L1WSEndpoint.Name), l1ProverPrivKey, c),
PrivateTxmgrConfigs: pkgFlags.InitTxmgrConfigsFromCli(
c.String(flags.L1PrivateEndpoint.Name),
l1ProverPrivKey,
Expand Down
56 changes: 35 additions & 21 deletions packages/taiko-client/prover/event_handler/batch_proposed.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"math/big"
"slices"
"time"

"github.com/cenkalti/backoff"
Expand All @@ -27,28 +28,30 @@ var (

// BatchProposedEventHandler is responsible for handling the BatchProposed event as a prover.
type BatchProposedEventHandler struct {
sharedState *state.SharedState
proverAddress common.Address
proverSetAddress common.Address
rpc *rpc.Client
assignmentExpiredCh chan<- metadata.TaikoProposalMetaData
proofSubmissionCh chan<- *proofProducer.ProofRequestBody
backOffRetryInterval time.Duration
backOffMaxRetrys uint64
proveUnassignedBlocks bool
sharedState *state.SharedState
proverAddress common.Address
proverSetAddress common.Address
rpc *rpc.Client
localProposerAddresses []common.Address
assignmentExpiredCh chan<- metadata.TaikoProposalMetaData
proofSubmissionCh chan<- *proofProducer.ProofRequestBody
backOffRetryInterval time.Duration
backOffMaxRetrys uint64
proveUnassignedBlocks bool
}

// NewBatchProposedEventHandlerOps is the options for creating a new BatchProposedEventHandler.
type NewBatchProposedEventHandlerOps struct {
SharedState *state.SharedState
ProverAddress common.Address
ProverSetAddress common.Address
RPC *rpc.Client
AssignmentExpiredCh chan metadata.TaikoProposalMetaData
ProofSubmissionCh chan *proofProducer.ProofRequestBody
BackOffRetryInterval time.Duration
BackOffMaxRetrys uint64
ProveUnassignedBlocks bool
SharedState *state.SharedState
ProverAddress common.Address
ProverSetAddress common.Address
RPC *rpc.Client
LocalProposerAddresses []common.Address
AssignmentExpiredCh chan metadata.TaikoProposalMetaData
ProofSubmissionCh chan *proofProducer.ProofRequestBody
BackOffRetryInterval time.Duration
BackOffMaxRetrys uint64
ProveUnassignedBlocks bool
}

// NewBatchProposedEventHandler creates a new BatchProposedEventHandler instance.
Expand All @@ -58,6 +61,7 @@ func NewBatchProposedEventHandler(opts *NewBatchProposedEventHandlerOps) *BatchP
opts.ProverAddress,
opts.ProverSetAddress,
opts.RPC,
opts.LocalProposerAddresses,
opts.AssignmentExpiredCh,
opts.ProofSubmissionCh,
opts.BackOffRetryInterval,
Expand Down Expand Up @@ -196,12 +200,14 @@ func (h *BatchProposedEventHandler) checkExpirationAndSubmitProofPacaya(
// if no and the current prover wants to prove unassigned blocks, then we should wait for its expiration.
if !windowExpired &&
meta.GetProposer() != h.proverAddress &&
meta.GetProposer() != h.proverSetAddress {
meta.GetProposer() != h.proverSetAddress &&
!slices.Contains(h.localProposerAddresses, meta.GetProposer()) {
log.Info(
"Proposed batch is not provable by current prover at the moment",
"batchID", meta.Pacaya().GetBatchID(),
"prover", meta.GetProposer(),
"timeToExpire", timeToExpire,
"localProposerAddresses", h.localProposerAddresses,
)

if h.proveUnassignedBlocks {
Expand All @@ -210,6 +216,7 @@ func (h *BatchProposedEventHandler) checkExpirationAndSubmitProofPacaya(
"batchID", meta.Pacaya().GetBatchID(),
"assignProver", meta.GetProposer(),
"timeToExpire", timeToExpire,
"localProposerAddresses", h.localProposerAddresses,
)
time.AfterFunc(
// Add another 72 seconds, to ensure one more L1 block will be mined before the proof submission
Expand All @@ -225,18 +232,25 @@ func (h *BatchProposedEventHandler) checkExpirationAndSubmitProofPacaya(
// we should skip proving this batch.
if !h.proveUnassignedBlocks &&
meta.GetProposer() != h.proverAddress &&
meta.GetProposer() != h.proverSetAddress {
meta.GetProposer() != h.proverSetAddress &&
!slices.Contains(h.localProposerAddresses, meta.GetProposer()) {
log.Info(
"Expired batch is not provable by current prover",
"batchID", meta.Pacaya().GetBatchID(),
"currentProver", h.proverAddress,
"currentProverSet", h.proverSetAddress,
"assignProver", meta.GetProposer(),
"localProposerAddresses", h.localProposerAddresses,
)
return nil
}

log.Info("Proposed batch is provable", "batchID", meta.Pacaya().GetBatchID(), "assignProver", meta.GetProposer())
log.Info(
"Proposed batch is provable",
"batchID", meta.Pacaya().GetBatchID(),
"assignProver", meta.GetProposer(),
"localProposerAddresses", h.localProposerAddresses,
)

metrics.ProverProofsAssigned.Add(1)

Expand Down
19 changes: 10 additions & 9 deletions packages/taiko-client/prover/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,15 +308,16 @@ func (p *Prover) initEventHandlers() error {
p.eventHandlers = &eventHandlers{}
// ------- BatchProposed -------
opts := &handler.NewBatchProposedEventHandlerOps{
SharedState: p.sharedState,
ProverAddress: p.ProverAddress(),
ProverSetAddress: p.cfg.ProverSetAddress,
RPC: p.rpc,
AssignmentExpiredCh: p.assignmentExpiredCh,
ProofSubmissionCh: p.proofSubmissionCh,
BackOffRetryInterval: p.cfg.BackOffRetryInterval,
BackOffMaxRetrys: p.cfg.BackOffMaxRetries,
ProveUnassignedBlocks: p.cfg.ProveUnassignedBlocks,
SharedState: p.sharedState,
ProverAddress: p.ProverAddress(),
ProverSetAddress: p.cfg.ProverSetAddress,
RPC: p.rpc,
LocalProposerAddresses: p.cfg.LocalProposerAddresses,
AssignmentExpiredCh: p.assignmentExpiredCh,
ProofSubmissionCh: p.proofSubmissionCh,
BackOffRetryInterval: p.cfg.BackOffRetryInterval,
BackOffMaxRetrys: p.cfg.BackOffMaxRetries,
ProveUnassignedBlocks: p.cfg.ProveUnassignedBlocks,
}
p.eventHandlers.batchProposedHandler = handler.NewBatchProposedEventHandler(opts)
// ------- BatchesProved -------
Expand Down