Skip to content
This repository was archived by the owner on May 11, 2024. It is now read-only.

Commit b7af09c

Browse files
mask-ppdavidtaikochacyberhorseyYoGhurt111yuguo
authored
feat(prover): improve prover implementation (#616)
Co-authored-by: David <david@taiko.xyz> Co-authored-by: jeff <113397187+cyberhorsey@users.noreply.github.com> Co-authored-by: Gavin Yu <623770278@qq.com> Co-authored-by: yuguo <yuguo@loopring.io>
1 parent 077ccf2 commit b7af09c

10 files changed

+100
-147
lines changed

prover/guardian.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ var (
1515
// gurdianProverHeartbeatLoop keeps sending heartbeats to the guardian prover health check server
1616
// on an interval.
1717
func (p *Prover) gurdianProverHeartbeatLoop(ctx context.Context) {
18-
// Only guardian provers need to send heartbeat.
18+
p.wg.Add(1)
19+
defer p.wg.Done()
20+
1921
if !p.IsGuardianProver() {
2022
return
2123
}

prover/init.go

-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ func (p *Prover) initProofSubmitters(
137137
producer,
138138
p.proofGenerationCh,
139139
p.cfg.TaikoL2Address,
140-
p.cfg.L1ProverPrivKey,
141140
p.cfg.Graffiti,
142141
sender,
143142
txBuilder,

prover/init_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
func (s *ProverTestSuite) TestSetApprovalAmount() {
13-
opts, err := bind.NewKeyedTransactorWithChainID(s.p.proverPrivateKey, s.p.rpc.L1.ChainID)
13+
opts, err := bind.NewKeyedTransactorWithChainID(s.p.cfg.L1ProverPrivKey, s.p.rpc.L1.ChainID)
1414
s.Nil(err)
1515

1616
tx, err := s.p.rpc.TaikoToken.Approve(opts, s.p.cfg.AssignmentHookAddress, common.Big0)

prover/proof_submitter/proof_contester.go

-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package submitter
22

33
import (
44
"context"
5-
"crypto/ecdsa"
65
"math/big"
76
"strings"
87

@@ -32,15 +31,13 @@ type ProofContester struct {
3231
func NewProofContester(
3332
ctx context.Context,
3433
rpcClient *rpc.Client,
35-
proverPrivKey *ecdsa.PrivateKey,
3634
txSender *sender.Sender,
3735
graffiti string,
3836
builder *transaction.ProveBlockTxBuilder,
3937
) (*ProofContester, error) {
4038
sender, err := transaction.NewSender(
4139
ctx,
4240
rpcClient,
43-
proverPrivKey,
4441
txSender,
4542
)
4643
if err != nil {

prover/proof_submitter/proof_submitter.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ package submitter
22

33
import (
44
"context"
5-
"crypto/ecdsa"
65
"errors"
76
"fmt"
87

98
"github.com/ethereum/go-ethereum/accounts/abi/bind"
109
"github.com/ethereum/go-ethereum/common"
11-
"github.com/ethereum/go-ethereum/crypto"
1210
"github.com/ethereum/go-ethereum/log"
1311

1412
"github.com/taikoxyz/taiko-client/bindings"
@@ -44,7 +42,6 @@ func New(
4442
proofProducer proofProducer.ProofProducer,
4543
resultCh chan *proofProducer.ProofWithHeader,
4644
taikoL2Address common.Address,
47-
proverPrivKey *ecdsa.PrivateKey,
4845
graffiti string,
4946
txSender *sender.Sender,
5047
builder *transaction.ProveBlockTxBuilder,
@@ -57,7 +54,6 @@ func New(
5754
proofSender, err := transaction.NewSender(
5855
ctx,
5956
rpcClient,
60-
proverPrivKey,
6157
txSender,
6258
)
6359
if err != nil {
@@ -71,7 +67,7 @@ func New(
7167
anchorValidator: anchorValidator,
7268
txBuilder: builder,
7369
sender: proofSender,
74-
proverAddress: crypto.PubkeyToAddress(proverPrivKey.PublicKey),
70+
proverAddress: txSender.GetOpts().From,
7571
taikoL2Address: taikoL2Address,
7672
graffiti: rpc.StringToBytes32(graffiti),
7773
}, nil

prover/proof_submitter/proof_submitter_test.go

-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ func (s *ProofSubmitterTestSuite) SetupTest() {
5656
&producer.OptimisticProofProducer{},
5757
s.proofCh,
5858
common.HexToAddress(os.Getenv("TAIKO_L2_ADDRESS")),
59-
l1ProverPrivKey,
6059
"test",
6160
sender,
6261
builder,
@@ -65,7 +64,6 @@ func (s *ProofSubmitterTestSuite) SetupTest() {
6564
s.contester, err = NewProofContester(
6665
context.Background(),
6766
s.RPCClient,
68-
l1ProverPrivKey,
6967
sender,
7068
"test",
7169
builder,

prover/proof_submitter/transaction/sender.go

-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package transaction
22

33
import (
44
"context"
5-
"crypto/ecdsa"
65
"math/big"
76
"strings"
87

@@ -25,7 +24,6 @@ type Sender struct {
2524
func NewSender(
2625
ctx context.Context,
2726
cli *rpc.Client,
28-
proverPrivateKey *ecdsa.PrivateKey,
2927
txSender *sender.Sender,
3028
) (*Sender, error) {
3129
return &Sender{

prover/proof_submitter/transaction/sender_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (s *TransactionTestSuite) SetupTest() {
3838
txSender, err := sender.NewSender(context.Background(), &sender.Config{}, s.RPCClient.L1, l1ProverPrivKey)
3939
s.Nil(err)
4040

41-
s.sender, err = NewSender(context.Background(), s.RPCClient, l1ProverPrivKey, txSender)
41+
s.sender, err = NewSender(context.Background(), s.RPCClient, txSender)
4242
s.Nil(err)
4343

4444
s.builder = NewProveBlockTxBuilder(s.RPCClient, l1ProverPrivKey)

prover/prover.go

+67-108
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package prover
22

33
import (
44
"context"
5-
"crypto/ecdsa"
65
"errors"
76
"fmt"
87
"math/big"
@@ -35,8 +34,7 @@ import (
3534
// Prover keeps trying to prove newly proposed blocks.
3635
type Prover struct {
3736
// Configurations
38-
cfg *Config
39-
proverPrivateKey *ecdsa.PrivateKey
37+
cfg *Config
4038

4139
// Clients
4240
rpc *rpc.Client
@@ -89,7 +87,9 @@ func (p *Prover) InitFromCli(ctx context.Context, c *cli.Context) error {
8987
func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) {
9088
p.cfg = cfg
9189
p.ctx = ctx
92-
p.proverPrivateKey = cfg.L1ProverPrivKey
90+
91+
// Initialize state which will be shared by event handlers.
92+
p.sharedState = state.New()
9393

9494
// Initialize state which will be shared by event handlers.
9595
p.sharedState = state.New()
@@ -152,11 +152,11 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) {
152152
senderCfg.MaxRetrys = 0
153153
}
154154

155-
txSender, err := sender.NewSender(p.ctx, senderCfg, p.rpc.L1, p.proverPrivateKey)
155+
txSender, err := sender.NewSender(p.ctx, senderCfg, p.rpc.L1, p.cfg.L1ProverPrivKey)
156156
if err != nil {
157157
return err
158158
}
159-
txBuilder := transaction.NewProveBlockTxBuilder(p.rpc, p.proverPrivateKey)
159+
txBuilder := transaction.NewProveBlockTxBuilder(p.rpc, p.cfg.L1ProverPrivKey)
160160

161161
// Proof submitters
162162
if err := p.initProofSubmitters(p.ctx, txSender, txBuilder); err != nil {
@@ -167,7 +167,6 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) {
167167
p.proofContester, err = proofSubmitter.NewProofContester(
168168
p.ctx,
169169
p.rpc,
170-
p.cfg.L1ProverPrivKey,
171170
txSender,
172171
p.cfg.Graffiti,
173172
txBuilder,
@@ -253,9 +252,7 @@ func (p *Prover) Start() error {
253252
// eventLoop starts the main loop of Taiko prover.
254253
func (p *Prover) eventLoop() {
255254
p.wg.Add(1)
256-
defer func() {
257-
p.wg.Done()
258-
}()
255+
defer p.wg.Done()
259256

260257
// reqProving requests performing a proving operation, won't block
261258
// if we are already proving.
@@ -297,35 +294,23 @@ func (p *Prover) eventLoop() {
297294
case <-p.ctx.Done():
298295
return
299296
case proofWithHeader := <-p.proofGenerationCh:
300-
p.submitProofOp(p.ctx, proofWithHeader)
297+
p.withRetry(func() error { return p.submitProofOp(proofWithHeader) })
301298
case req := <-p.proofSubmissionCh:
302-
p.requestProofOp(p.ctx, req.Event, req.Tier)
299+
p.withRetry(func() error { return p.requestProofOp(req.Event, req.Tier) })
303300
case req := <-p.proofContestCh:
304-
p.contestProofOp(p.ctx, req)
301+
p.withRetry(func() error { return p.contestProofOp(req) })
305302
case <-p.proveNotify:
306303
if err := p.proveOp(); err != nil {
307304
log.Error("Prove new blocks error", "error", err)
308305
}
309306
case e := <-blockVerifiedCh:
310307
p.blockVerifiedHandler.Handle(e)
311308
case e := <-transitionProvedCh:
312-
go func() {
313-
if err := p.withRetry(func() error { return p.transitionProvedHandler.Handle(p.ctx, e) }); err != nil {
314-
log.Error("Handle TaikoL1.TransitionProved event error", "error", err)
315-
}
316-
}()
309+
p.withRetry(func() error { return p.transitionProvedHandler.Handle(p.ctx, e) })
317310
case e := <-transitionContestedCh:
318-
go func() {
319-
if err := p.withRetry(func() error { return p.transitionContestedHandler.Handle(p.ctx, e) }); err != nil {
320-
log.Error("Handle TaikoL1.TransitionContested event error", "error", err)
321-
}
322-
}()
311+
p.withRetry(func() error { return p.transitionContestedHandler.Handle(p.ctx, e) })
323312
case e := <-p.assignmentExpiredCh:
324-
go func() {
325-
if err := p.withRetry(func() error { return p.assignmentExpiredHandler.Handle(p.ctx, e) }); err != nil {
326-
log.Error("Handle proof window expired event error", "error", err)
327-
}
328-
}()
313+
p.withRetry(func() error { return p.assignmentExpiredHandler.Handle(p.ctx, e) })
329314
case <-blockProposedCh:
330315
reqProving()
331316
case <-forceProvingTicker.C:
@@ -376,86 +361,53 @@ func (p *Prover) proveOp() error {
376361
}
377362

378363
// contestProofOp performs a proof contest operation.
379-
func (p *Prover) contestProofOp(ctx context.Context, req *proofSubmitter.ContestRequestBody) {
380-
go func() {
381-
if err := backoff.Retry(func() error {
382-
if err := p.proofContester.SubmitContest(
383-
p.ctx,
384-
req.BlockID,
385-
req.ProposedIn,
386-
req.ParentHash,
387-
req.Meta,
388-
req.Tier,
389-
); err != nil {
390-
log.Error("Request new proof contest error", "blockID", req.BlockID, "error", err)
391-
return err
392-
}
364+
func (p *Prover) contestProofOp(req *proofSubmitter.ContestRequestBody) error {
365+
if err := p.proofContester.SubmitContest(
366+
p.ctx,
367+
req.BlockID,
368+
req.ProposedIn,
369+
req.ParentHash,
370+
req.Meta,
371+
req.Tier,
372+
); err != nil {
373+
log.Error("Request new proof contest error", "blockID", req.BlockID, "error", err)
374+
return err
375+
}
393376

394-
return nil
395-
}, backoff.WithMaxRetries(
396-
backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval),
397-
p.cfg.BackOffMaxRetrys,
398-
)); err != nil {
399-
log.Error("Request new proof contest error", "blockID", req.BlockID, "error", err)
400-
}
401-
}()
377+
return nil
402378
}
403379

404380
// requestProofOp requests a new proof generation operation.
405-
func (p *Prover) requestProofOp(ctx context.Context, e *bindings.TaikoL1ClientBlockProposed, minTier uint16) {
406-
go func() {
407-
if p.IsGuardianProver() {
408-
minTier = encoding.TierGuardianID
381+
func (p *Prover) requestProofOp(e *bindings.TaikoL1ClientBlockProposed, minTier uint16) error {
382+
if p.IsGuardianProver() {
383+
minTier = encoding.TierGuardianID
384+
}
385+
if submitter := p.selectSubmitter(minTier); submitter != nil {
386+
if err := submitter.RequestProof(p.ctx, e); err != nil {
387+
log.Error("Request new proof error", "blockID", e.BlockId, "error", err)
388+
return err
409389
}
410390

411-
if err := backoff.Retry(func() error {
412-
if ctx.Err() != nil {
413-
log.Error("Context is done, aborting requestProofOp", "blockID", e.BlockId, "error", ctx.Err())
414-
return nil
415-
}
416-
417-
if proofSubmitter := p.selectSubmitter(minTier); proofSubmitter != nil {
418-
if err := proofSubmitter.RequestProof(ctx, e); err != nil {
419-
log.Error("Request new proof error", "blockID", e.BlockId, "error", err)
420-
return err
421-
}
422-
423-
return nil
424-
}
391+
return nil
392+
}
425393

426-
log.Error("Failed to find proof submitter", "blockID", e.BlockId, "minTier", minTier)
427-
return nil
428-
}, backoff.WithMaxRetries(
429-
backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval),
430-
p.cfg.BackOffMaxRetrys,
431-
)); err != nil {
432-
log.Error("Request new proof error", "blockID", e.BlockId, "error", err)
433-
}
434-
}()
394+
log.Error("Failed to find proof submitter", "blockID", e.BlockId, "minTier", minTier)
395+
return nil
435396
}
436397

437398
// submitProofOp performs a proof submission operation.
438-
func (p *Prover) submitProofOp(ctx context.Context, proofWithHeader *proofProducer.ProofWithHeader) {
439-
go func() {
440-
if err := backoff.Retry(
441-
func() error {
442-
proofSubmitter := p.getSubmitterByTier(proofWithHeader.Tier)
443-
if proofSubmitter == nil {
444-
return nil
445-
}
399+
func (p *Prover) submitProofOp(proofWithHeader *proofProducer.ProofWithHeader) error {
400+
submitter := p.getSubmitterByTier(proofWithHeader.Tier)
401+
if submitter == nil {
402+
return nil
403+
}
446404

447-
if err := proofSubmitter.SubmitProof(p.ctx, proofWithHeader); err != nil {
448-
log.Error("Submit proof error", "error", err)
449-
return err
450-
}
405+
if err := submitter.SubmitProof(p.ctx, proofWithHeader); err != nil {
406+
log.Error("Submit proof error", "error", err)
407+
return err
408+
}
451409

452-
return nil
453-
},
454-
backoff.WithMaxRetries(backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval), p.cfg.BackOffMaxRetrys),
455-
); err != nil {
456-
log.Error("Submit proof error", "error", err)
457-
}
458-
}()
410+
return nil
459411
}
460412

461413
// Name returns the application name.
@@ -497,19 +449,26 @@ func (p *Prover) IsGuardianProver() bool {
497449

498450
// ProverAddress returns the current prover account address.
499451
func (p *Prover) ProverAddress() common.Address {
500-
return crypto.PubkeyToAddress(p.proverPrivateKey.PublicKey)
452+
return crypto.PubkeyToAddress(p.cfg.L1ProverPrivKey.PublicKey)
501453
}
502454

503455
// withRetry retries the given function with prover backoff policy.
504-
func (p *Prover) withRetry(f func() error) error {
505-
return backoff.Retry(
506-
func() error {
507-
if p.ctx.Err() != nil {
508-
log.Error("Context is done, aborting", "error", p.ctx.Err())
509-
return nil
510-
}
511-
return f()
512-
},
513-
backoff.WithMaxRetries(backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval), p.cfg.BackOffMaxRetrys),
514-
)
456+
func (p *Prover) withRetry(f func() error) {
457+
p.wg.Add(1)
458+
go func() {
459+
defer p.wg.Done()
460+
err := backoff.Retry(
461+
func() error {
462+
if p.ctx.Err() != nil {
463+
log.Error("Context is done, aborting", "error", p.ctx.Err())
464+
return nil
465+
}
466+
return f()
467+
},
468+
backoff.WithMaxRetries(backoff.NewConstantBackOff(p.cfg.BackOffRetryInterval), p.cfg.BackOffMaxRetrys),
469+
)
470+
if err != nil {
471+
log.Error("Operation failed", "error", err)
472+
}
473+
}()
515474
}

0 commit comments

Comments
 (0)