From 2156b49202318447ecafdbf4b53a6209b711f1e0 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 8 Jan 2024 15:02:41 +0800 Subject: [PATCH] feat(prover): add more comments to prover package (#491) --- prover/db/db.go | 2 ++ .../guardian_prover_sender/guardian_prover.go | 18 ++++++++-- prover/prover.go | 36 +++++++++---------- prover/prover_test.go | 2 +- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/prover/db/db.go b/prover/db/db.go index 7ebc56f13..811707e94 100644 --- a/prover/db/db.go +++ b/prover/db/db.go @@ -13,6 +13,7 @@ var ( separator = "++" ) +// SignedBlockData is the data stored in the db for a signed block type SignedBlockData struct { BlockID *big.Int BlockHash common.Hash @@ -38,6 +39,7 @@ func BuildBlockValue(hash []byte, signature []byte, blockID *big.Int) []byte { }, []byte(separator)) } +// SignedBlockDataFromValue will build a SignedBlockData from a value func SignedBlockDataFromValue(val []byte) SignedBlockData { v := bytes.Split(val, []byte(separator)) diff --git a/prover/guardian_prover_sender/guardian_prover.go b/prover/guardian_prover_sender/guardian_prover.go index 85c8f1752..9b555393e 100644 --- a/prover/guardian_prover_sender/guardian_prover.go +++ b/prover/guardian_prover_sender/guardian_prover.go @@ -19,11 +19,13 @@ import ( "github.com/taikoxyz/taiko-client/prover/db" ) +// healthCheckReq is the request body sent to the health check server when a heartbeat is sent. type healthCheckReq struct { ProverAddress string `json:"prover"` HeartBeatSignature []byte `json:"heartBeatSignature"` } +// signedBlockReq is the request body sent to the health check server when a block is signed. type signedBlockReq struct { BlockID uint64 `json:"blockID"` BlockHash string `json:"blockHash"` @@ -31,6 +33,7 @@ type signedBlockReq struct { Prover common.Address `json:"proverAddress"` } +// GuardianProverBlockSender is responsible for signing and sending known blocks to the health check server. type GuardianProverBlockSender struct { privateKey *ecdsa.PrivateKey healthCheckServerEndpoint *url.URL @@ -39,7 +42,8 @@ type GuardianProverBlockSender struct { proverAddress common.Address } -func NewGuardianProverBlockSender( +// New creates a new GuardianProverBlockSender instance. +func New( privateKey *ecdsa.PrivateKey, healthCheckServerEndpoint *url.URL, db ethdb.KeyValueStore, @@ -55,6 +59,7 @@ func NewGuardianProverBlockSender( } } +// post sends the given POST request to the health check server. func (s *GuardianProverBlockSender) post(ctx context.Context, route string, req interface{}) error { body, err := json.Marshal(req) if err != nil { @@ -64,19 +69,22 @@ func (s *GuardianProverBlockSender) post(ctx context.Context, route string, req resp, err := http.Post( fmt.Sprintf("%v/%v", s.healthCheckServerEndpoint.String(), route), "application/json", - bytes.NewBuffer(body)) + bytes.NewBuffer(body), + ) if err != nil { return err } if resp.StatusCode != http.StatusOK { return fmt.Errorf( - "unable to contact health check server endpoint, status code: %v", resp.StatusCode) + "unable to contact health check server endpoint, status code: %v", resp.StatusCode, + ) } return nil } +// SignAndSendBlock signs the given block and sends it to the health check server. func (s *GuardianProverBlockSender) SignAndSendBlock(ctx context.Context, blockID *big.Int) error { signed, header, err := s.sign(ctx, blockID) if err != nil { @@ -104,6 +112,7 @@ func (s *GuardianProverBlockSender) SignAndSendBlock(ctx context.Context, blockI return nil } +// sendSignedBlockReq is the actual method that sends the signed block to the health check server. func (s *GuardianProverBlockSender) sendSignedBlockReq( ctx context.Context, signed []byte, @@ -131,6 +140,7 @@ func (s *GuardianProverBlockSender) sendSignedBlockReq( return nil } +// sign signs the given block and returns the signature and header. func (s *GuardianProverBlockSender) sign(ctx context.Context, blockID *big.Int) ([]byte, *types.Header, error) { log.Info("Guardian prover signing block", "blockID", blockID.Uint64()) @@ -185,10 +195,12 @@ func (s *GuardianProverBlockSender) sign(ctx context.Context, blockID *big.Int) return signed, header, nil } +// Close closes the underlying database. func (s *GuardianProverBlockSender) Close() error { return s.db.Close() } +// SendHeartbeat sends a heartbeat to the health check server. func (s *GuardianProverBlockSender) SendHeartbeat(ctx context.Context) error { sig, err := crypto.Sign(crypto.Keccak256Hash([]byte("HEART_BEAT")).Bytes(), s.privateKey) if err != nil { diff --git a/prover/prover.go b/prover/prover.go index e1a95de93..dec75dcab 100644 --- a/prover/prover.go +++ b/prover/prover.go @@ -33,7 +33,8 @@ import ( ) var ( - errTierNotFound = errors.New("tier not found") + errTierNotFound = errors.New("tier not found") + heartbeatInterval = 12 * time.Second ) // Prover keep trying to prove new proposed blocks valid/invalid. @@ -290,11 +291,13 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { IsGuardian: p.IsGuardianProver(), DB: db, } + if p.srv, err = server.New(proverServerOpts); err != nil { + return err + } + // Guardian prover heartbeat sender if p.IsGuardianProver() { - proverServerOpts.ProverPrivateKey = p.cfg.L1ProverPrivKey - - p.guardianProverSender = guardianproversender.NewGuardianProverBlockSender( + p.guardianProverSender = guardianproversender.New( p.cfg.L1ProverPrivKey, p.cfg.GuardianProverHealthCheckServerEndpoint, db, @@ -303,16 +306,12 @@ func InitFromConfig(ctx context.Context, p *Prover, cfg *Config) (err error) { ) } - if p.srv, err = server.New(proverServerOpts); err != nil { - return err - } - return nil } // setApprovalAmount will set the allowance on the TaikoToken contract for the -// configured proverAddress as owner and the TaikoL1 contract as spender, -// if flag is provided for allowance. +// configured proverAddress as owner and the contract as spender, +// if `--prover.allowance` flag is provided for allowance. func (p *Prover) setApprovalAmount(ctx context.Context, contract common.Address) error { if p.cfg.Allowance == nil || p.cfg.Allowance.Cmp(common.Big0) != 1 { log.Info("Skipping setting approval, `--prover.allowance` flag not set") @@ -386,16 +385,15 @@ func (p *Prover) setApprovalAmount(ctx context.Context, contract common.Address) // Start starts the main loop of the L2 block prover. func (p *Prover) Start() error { + for _, contract := range []common.Address{p.cfg.TaikoL1Address, p.cfg.AssignmentHookAddress} { + if err := p.setApprovalAmount(p.ctx, contract); err != nil { + log.Crit("Failed to set approval amount", "contract", contract, "error", err) + } + } + p.wg.Add(1) p.initSubscription() - if err := p.setApprovalAmount(p.ctx, p.cfg.TaikoL1Address); err != nil { - log.Crit("Failed to set approval amount", "contract", p.cfg.TaikoL1Address, "error", err) - } - if err := p.setApprovalAmount(p.ctx, p.cfg.AssignmentHookAddress); err != nil { - log.Crit("Failed to set approval amount", "contract", p.cfg.AssignmentHookAddress, "error", err) - } - go func() { if err := p.srv.Start(fmt.Sprintf(":%v", p.cfg.HTTPServerPort)); !errors.Is(err, http.ErrServerClosed) { log.Crit("Failed to start http server", "error", err) @@ -1300,7 +1298,7 @@ func (p *Prover) IsGuardianProver() bool { // heartbeatInterval sends a heartbeat to the guardian prover health check server // on an interval func (p *Prover) heartbeatInterval(ctx context.Context) { - t := time.NewTicker(12 * time.Second) + t := time.NewTicker(heartbeatInterval) defer func() { t.Stop() @@ -1318,7 +1316,7 @@ func (p *Prover) heartbeatInterval(ctx context.Context) { return case <-t.C: if err := p.guardianProverSender.SendHeartbeat(ctx); err != nil { - log.Error("error sending heartbeat", "error", err) + log.Error("Failed to send guardian prover heartbeat", "error", err) } } } diff --git a/prover/prover_test.go b/prover/prover_test.go index 58b10407d..71bef0cd9 100644 --- a/prover/prover_test.go +++ b/prover/prover_test.go @@ -81,7 +81,7 @@ func (s *ProverTestSuite) SetupTest() { proverServerUrl, ) - p.guardianProverSender = guardianproversender.NewGuardianProverBlockSender( + p.guardianProverSender = guardianproversender.New( p.cfg.L1ProverPrivKey, p.cfg.GuardianProverHealthCheckServerEndpoint, memorydb.New(),