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

Commit

Permalink
feat(prover): more listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
davidtaikocha committed Oct 12, 2023
1 parent c7cd1e9 commit fd1a146
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 34 deletions.
2 changes: 1 addition & 1 deletion driver/chain_syncer/calldata/syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (s *CalldataSyncerTestSuite) SetupTest() {
L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")),
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: s.ProverEndpoints,
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down
2 changes: 1 addition & 1 deletion driver/chain_syncer/chain_syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (s *ChainSyncerTestSuite) SetupTest() {
L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")),
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: s.ProverEndpoints,
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down
2 changes: 1 addition & 1 deletion driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (s *DriverTestSuite) SetupTest() {
L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")),
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: s.ProverEndpoints,
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down
18 changes: 16 additions & 2 deletions driver/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,23 @@ func (s *State) startSubscriptions(ctx context.Context) {
case e := <-s.blockProposedCh:
s.setHeadBlockID(e.BlockId)
case e := <-s.transitionProvedCh:
log.Info("✅ Block proven", "blockID", e.BlockId, "hash", common.Hash(e.BlockHash), "prover", e.Prover)
log.Info(
"✅ Transition proven",
"blockID", e.BlockId,
"parentHash", common.Hash(e.ParentHash),
"hash", common.Hash(e.BlockHash),
"signalRoot", common.Hash(e.SignalRoot),
"prover", e.Prover,
)
case e := <-s.blockVerifiedCh:
log.Info("📈 Block verified", "blockID", e.BlockId, "hash", common.Hash(e.BlockHash), "prover", e.Prover)
log.Info(
"📈 Block verified",
"blockID", e.BlockId,
"hash", common.Hash(e.BlockHash),
"signalRoot", common.Hash(e.SignalRoot),
"assignedProver", e.AssignedProver,
"prover", e.Prover,
)
case e := <-s.crossChainSynced:
// Verify the protocol synced block, check if it exists in
// L2 execution engine.
Expand Down
2 changes: 1 addition & 1 deletion proposer/proposer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (s *ProposerTestSuite) SetupTest() {
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
ProposeBlockTxReplacementMultiplier: 2,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: s.ProverEndpoints,
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down
7 changes: 5 additions & 2 deletions prover/proof_submitter/proof_contester.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,11 @@ func (c *ProofContester) SubmitContest(
Meta: &blockProposedEvent.Meta,
Header: header,
Proof: []byte{},
Opts: &proofProducer.ProofRequestOptions{EventL1Hash: blockProposedEvent.Raw.BlockHash},
Tier: transitionProvedEvent.Tier,
Opts: &proofProducer.ProofRequestOptions{
EventL1Hash: blockProposedEvent.Raw.BlockHash,
SignalRoot: evidence.SignalRoot,
},
Tier: transitionProvedEvent.Tier,
},
c.txBuilder.Build(ctx, transitionProvedEvent.BlockId, input),
); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion prover/proof_submitter/proof_submitter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (s *ProofSubmitterTestSuite) SetupTest() {
L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")),
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: s.ProverEndpoints,
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down
4 changes: 4 additions & 0 deletions prover/proof_submitter/transaction/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,12 @@ func (s *Sender) Send(
log.Info(
"💰 Your block proof was accepted",
"blockID", proofWithHeader.BlockID,
"parentHash", proofWithHeader.Header.ParentHash,
"hash", proofWithHeader.Header.Hash(),
"signalRoot", proofWithHeader.Opts.SignalRoot,
"txHash", tx.Hash(),
"tier", proofWithHeader.Tier,
"isContest", len(proofWithHeader.Proof) == 0,
)

return nil
Expand Down
2 changes: 2 additions & 0 deletions prover/proof_submitter/transaction/sender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (s *TransactionTestSuite) TestSendTxWithBackoff() {
&proofProducer.ProofWithHeader{
Meta: meta,
BlockID: common.Big1,
Header: &types.Header{},
Opts: &proofProducer.ProofRequestOptions{EventL1Hash: l1Head.Hash()},
},
func(nonce *big.Int) (*types.Transaction, error) { return nil, errors.New("L1_TEST") },
Expand All @@ -59,6 +60,7 @@ func (s *TransactionTestSuite) TestSendTxWithBackoff() {
&proofProducer.ProofWithHeader{
Meta: meta,
BlockID: common.Big1,
Header: &types.Header{},
Opts: &proofProducer.ProofRequestOptions{EventL1Hash: l1Head.Hash()},
},
func(nonce *big.Int) (*types.Transaction, error) {
Expand Down
106 changes: 84 additions & 22 deletions prover/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,9 @@ func (p *Prover) eventLoop() {
log.Error("Handle TransitionProved event error", "error", err)
}
case e := <-p.transitionContestedCh:
// TODO: add a listener.
log.Info("Transaction contested", "event", e)
if err := p.onTransitionContested(p.ctx, e); err != nil {
log.Error("Handle TransitionContested event error", "error", err)
}
case e := <-p.proofWindowExpiredCh:
if err := p.onProvingWindowExpired(p.ctx, e); err != nil {
log.Error("Handle provingWindow expired event error", "error", err)
Expand Down Expand Up @@ -625,18 +626,69 @@ func (p *Prover) submitProofOp(ctx context.Context, proofWithHeader *proofProduc
}()
}

// onTransitionContested tries to submit a higher tier proof for the contested transition.
func (p *Prover) onTransitionContested(ctx context.Context, e *bindings.TaikoL1ClientTransitionContested) error {
log.Info(
"🗡 Transition contested",
"blockID", e.BlockId,
"parentHash", common.Bytes2Hex(e.ParentHash[:]),
"hash", common.Bytes2Hex(e.BlockHash[:]),
"signalRoot", common.BytesToHash(e.SignalRoot[:]),
"contester", e.Contester,
"bond", e.ContestBond,
)

// If this prover is not in contest mode, we simply output a log and return.
if !p.cfg.ContestControversialProofs {
return nil
}

// Compare the contested transition to the block in local L2 canonical chain.
isValidProof, err := p.isValidProof(
ctx,
e.BlockId,
e.ParentHash,
e.BlockHash,
e.SignalRoot,
)
if err != nil {
return err
}
if isValidProof {
log.Info(
"Contested transition is valid to local canonical chain, ignore the contest",
"blockID", e.BlockId,
"parentHash", common.Bytes2Hex(e.ParentHash[:]),
"hash", common.Bytes2Hex(e.BlockHash[:]),
"signalRoot", common.BytesToHash(e.SignalRoot[:]),
"contester", e.Contester,
"bond", e.ContestBond,
)
return nil
}

l1Height, err := p.rpc.TaikoL2.LatestSyncedL1Height(&bind.CallOpts{Context: ctx, BlockNumber: e.BlockId})
if err != nil {
return err
}

return p.requestProofByBlockID(e.BlockId, new(big.Int).SetUint64(l1Height+1), e.Tier+1, nil)
}

// onBlockVerified update the latestVerified block in current state, and cancels
// the block being proven if it's verified.
func (p *Prover) onBlockVerified(ctx context.Context, event *bindings.TaikoL1ClientBlockVerified) error {
metrics.ProverLatestVerifiedIDGauge.Update(event.BlockId.Int64())
func (p *Prover) onBlockVerified(ctx context.Context, e *bindings.TaikoL1ClientBlockVerified) error {
metrics.ProverLatestVerifiedIDGauge.Update(e.BlockId.Int64())

p.latestVerifiedL1Height = event.Raw.BlockNumber
p.latestVerifiedL1Height = e.Raw.BlockNumber

log.Info(
"New verified block",
"blockID", event.BlockId,
"hash", common.BytesToHash(event.BlockHash[:]),
"prover", event.Prover,
"blockID", e.BlockId,
"hash", common.BytesToHash(e.BlockHash[:]),
"signalRoot", common.BytesToHash(e.SignalRoot[:]),
"assignedProver", e.AssignedProver,
"prover", e.Prover,
)

return nil
Expand Down Expand Up @@ -665,7 +717,10 @@ func (p *Prover) onTransitionProved(ctx context.Context, event *bindings.TaikoL1

isValidProof, err := p.isValidProof(
ctx,
event,
event.BlockId,
event.ParentHash,
event.BlockHash,
event.SignalRoot,
)
if err != nil {
return err
Expand All @@ -680,7 +735,7 @@ func (p *Prover) onTransitionProved(ctx context.Context, event *bindings.TaikoL1
}

log.Info(
"Contest a proven block",
"Contest a proven transition",
"blockID", event.BlockId,
"l1Height", l1Height,
"tier", event.Tier,
Expand All @@ -689,7 +744,7 @@ func (p *Prover) onTransitionProved(ctx context.Context, event *bindings.TaikoL1
"signalRoot", common.Bytes2Hex(event.SignalRoot[:]),
)

return p.requestProofByBlockID(event.BlockId, new(big.Int).SetUint64(l1Height+1), event)
return p.requestProofByBlockID(event.BlockId, new(big.Int).SetUint64(l1Height+1), event.Tier, event)
}

// Name returns the application name.
Expand Down Expand Up @@ -774,44 +829,51 @@ func (p *Prover) closeSubscription() {
}

// isValidProof checks if the given proof is a valid one, comparing to current L2 node canonical chain.
func (p *Prover) isValidProof(ctx context.Context, event *bindings.TaikoL1ClientTransitionProved) (bool, error) {
parent, err := p.rpc.L2ParentByBlockId(ctx, event.BlockId)
func (p *Prover) isValidProof(
ctx context.Context,
blockID *big.Int,
parentHash common.Hash,
blockHash common.Hash,
signalRoot common.Hash,
) (bool, error) {
parent, err := p.rpc.L2ParentByBlockId(ctx, blockID)
if err != nil {
return false, err
}

block, err := p.rpc.L2.BlockByNumber(ctx, event.BlockId)
block, err := p.rpc.L2.BlockByNumber(ctx, blockID)
if err != nil {
return false, err
}

l2SignalService, err := p.rpc.TaikoL2.Resolve0(
&bind.CallOpts{Context: ctx, BlockNumber: event.BlockId},
&bind.CallOpts{Context: ctx, BlockNumber: blockID},
rpc.StringToBytes32("signal_service"),
false,
)
if err != nil {
return false, err
}
signalRoot, err := p.rpc.GetStorageRoot(
root, err := p.rpc.GetStorageRoot(
ctx,
p.rpc.L2GethClient,
l2SignalService,
event.BlockId,
blockID,
)
if err != nil {
return false, err
}

return parent.Hash() == event.ParentHash &&
block.Hash() == event.BlockHash &&
signalRoot == event.SignalRoot, nil
return parent.Hash() == parentHash &&
block.Hash() == blockHash &&
root == signalRoot, nil
}

// requestProofByBlockID performs a proving operation for the given block.
func (p *Prover) requestProofByBlockID(
blockID *big.Int,
l1Height *big.Int,
minTier uint16,
// If this event is not nil, then the prover will try contesting the transition.
transitionProvedEvent *bindings.TaikoL1ClientTransitionProved,
) error {
Expand Down Expand Up @@ -847,7 +909,7 @@ func (p *Prover) requestProofByBlockID(
}

// If there is no proof submitter selected, skip proving it.
if proofSubmitter := p.selectSubmitter(event.MinTier); proofSubmitter != nil {
if proofSubmitter := p.selectSubmitter(minTier); proofSubmitter != nil {
return proofSubmitter.RequestProof(ctx, event)
}

Expand Down Expand Up @@ -927,7 +989,7 @@ func (p *Prover) onProvingWindowExpired(ctx context.Context, e *bindings.TaikoL1
return nil
}

return p.requestProofByBlockID(e.BlockId, new(big.Int).SetUint64(e.Raw.BlockNumber), nil)
return p.requestProofByBlockID(e.BlockId, new(big.Int).SetUint64(e.Raw.BlockNumber), e.MinTier, nil)
}

// getProvingWindow returns the provingWindow of the given proposed block.
Expand Down
13 changes: 11 additions & 2 deletions prover/prover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func (s *ProverTestSuite) SetupTest() {
MinSgxTierFee: common.Big1,
MinPseZkevmTierFee: common.Big1,
HTTPServerPort: uint64(port),
WaitReceiptTimeout: 12 * time.Second,
})))
p.srv = testutils.NewTestProverServer(
&s.ClientTestSuite,
Expand Down Expand Up @@ -104,7 +105,7 @@ func (s *ProverTestSuite) SetupTest() {
L2SuggestedFeeRecipient: common.HexToAddress(os.Getenv("L2_SUGGESTED_FEE_RECIPIENT")),
ProposeInterval: &proposeInterval,
MaxProposedTxListsPerEpoch: 1,
WaitReceiptTimeout: 10 * time.Second,
WaitReceiptTimeout: 12 * time.Second,
ProverEndpoints: []*url.URL{proverServerUrl},
OptimisticTierFee: common.Big256,
SgxTierFee: common.Big256,
Expand Down Expand Up @@ -244,7 +245,6 @@ func (s *ProverTestSuite) TestContestWrongBlocks() {

// Contest the transition.
contestedSink := make(chan *bindings.TaikoL1ClientTransitionContested)

contestedSub, err := s.p.rpc.TaikoL1.WatchTransitionContested(nil, contestedSink, nil)
s.Nil(err)
defer func() {
Expand All @@ -259,6 +259,15 @@ func (s *ProverTestSuite) TestContestWrongBlocks() {
s.Equal(header.Number.Uint64(), contestedEvent.BlockId.Uint64())
s.Equal(common.BytesToHash(proofWithHeader.Opts.BlockHash[:]), common.BytesToHash(contestedEvent.BlockHash[:]))
s.Equal(header.ParentHash, common.BytesToHash(contestedEvent.ParentHash[:]))

s.Nil(s.p.onTransitionContested(context.Background(), contestedEvent))
s.Nil(s.p.selectSubmitter(contestedEvent.Tier+1).SubmitProof(context.Background(), <-s.p.proofGenerationCh))
provenEvent := <-sink

s.Equal(header.Number.Uint64(), provenEvent.BlockId.Uint64())
s.Equal(header.Hash(), common.BytesToHash(provenEvent.BlockHash[:]))
s.Equal(header.ParentHash, common.BytesToHash(provenEvent.ParentHash[:]))
s.Greater(provenEvent.Tier, contestedEvent.Tier)
}

func (s *ProverTestSuite) TestProveExpiredUnassignedBlock() {
Expand Down
7 changes: 6 additions & 1 deletion testutils/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (s *ClientTestSuite) SetupTest() {
s.Nil(err)

if tokenBalance.Cmp(common.Big0) == 0 {
// Do not verify zk proofs in tests.
// Do not verify zk && sgx proofs in tests.
addressManager, err := bindings.NewAddressManager(
common.HexToAddress(os.Getenv("ADDRESS_MANAGER_CONTRACT_ADDRESS")),
rpcCli.L1,
Expand All @@ -103,6 +103,11 @@ func (s *ClientTestSuite) SetupTest() {
_, err = rpc.WaitReceipt(context.Background(), rpcCli.L1, tx)
s.Nil(err)

tx, err = addressManager.SetAddress(opts, chainID, rpc.StringToBytes32("tier_sgx"), common.Address{})
s.Nil(err)
_, err = rpc.WaitReceipt(context.Background(), rpcCli.L1, tx)
s.Nil(err)

// Deposit taiko tokens for provers.
opts, err = bind.NewKeyedTransactorWithChainID(l1ProverPrivKey, rpcCli.L1ChainID)
s.Nil(err)
Expand Down

0 comments on commit fd1a146

Please sign in to comment.