Skip to content

Commit

Permalink
Merge upstream v0.6.3 (#104)
Browse files Browse the repository at this point in the history
* check unsupported precompiles  (0xPolygonHermez#3264)

* check unsupported precompiles

* downgrade prover

* restore solc version

* update SC

* new errors

* fix as workaround to close batch on tx oog (0xPolygonHermez#3271)

Co-authored-by: agnusmor <[email protected]>

* handle executor close batch

* added sanity check closing an empty batch

* change log

---------

Co-authored-by: agnusmor <[email protected]>

* fix RPC closebatch executor error (0xPolygonHermez#3272)

* fix RPC closebatch executor error

* fix close batch

* fix close batch

* fix close batch

* fix close batch

* fix close batch

---------

Co-authored-by: agnusmor <[email protected]>

* fix executor error closebatch (0xPolygonHermez#3276)

* fix executor error closebatch

* fix linter

---------

Co-authored-by: agnusmor <[email protected]>

* add oog2 checks for all the oog cheks (0xPolygonHermez#3277)

* fix oog2 in internal gas estimation (0xPolygonHermez#3280)

* fix oog2

* fix oog2 for estimateGas

---------

Co-authored-by: tclemos <[email protected]>

* execution mode (0xPolygonHermez#3285)

* execution mode

* execution mode

* execution mode

* update prover image (0xPolygonHermez#3286)

* fix log when error on batch sanity check (0xPolygonHermez#3287)

* update prover image to v4.0.13 (0xPolygonHermez#3289)

* update prover image (0xPolygonHermez#3290)

* fix deltaTimestamp when debug tx (0xPolygonHermez#3291)

* fix deltaTimestamp when debug tx

* fix deltaTimeStamp for unsigned txs execution for specific block

* fix deltaTimeStamp for unsigned txs execution for specific block

* Revert "fix deltaTimeStamp for unsigned txs execution for specific block"

This reverts commit eb77e04.

* Revert "fix deltaTimeStamp for unsigned txs execution for specific block"

This reverts commit d2cfa78.

* fix debug trace l1 info tree index and add l1 info tree data

* move MockL1InfoRoot from sequencer to state to allow multiple components to use the same value

---------

Co-authored-by: agnusmor <[email protected]>

* fix checkStateInconsistency when starting sequencer (0xPolygonHermez#3294)

* disable delete addrQueue if empty as a workaround (0xPolygonHermez#3295)

* add aggregator.BatchProofL1BlockConfirmations config parameter (0xPolygonHermez#3302) (0xPolygonHermez#3313)

* Feature remove executor errors (0xPolygonHermez#3317)

* remove executor errors

* readd check

* support to elderberry fork (0xPolygonHermez#3301)

* add new sequenceBatches parameters
* update SMC Elderberry, contract dockers and genesis
* elderberry seq-sender (0xPolygonHermez#3312)
* elderberry seq-sender
* updated prover  image to v5.0.0-RC4
* increase timeout  to e2e-group7

---------

Co-authored-by: Toni Ramírez <[email protected]>
Co-authored-by: dPunisher <[email protected]>

* update prover image (0xPolygonHermez#3322)

* update prover image

* udpate prover docker memory limits

* downgrade prover

* upgrade prover

* Get last l2 block in a batch by batch number (0xPolygonHermez#3335)

* last l2 block by batch number

* optimization

* change returned err in query

* add selector for trusted sync to prevent from executing from an old trusted node  (0xPolygonHermez#3336)

* add selector for trusted sync to check that batches  correspond to the supported forkids

* synchronizer adopt GetLastL2BlockByBatchNumber to check elderberry tstamp baches (0xPolygonHermez#3340)

* synchronizer adopt GetLastL2BlockByBatchNumber to check elderberry bacthes tstamp

* reserved zk counters (0xPolygonHermez#3343)

* reserved zk counters

* new prover image

* udpate counters names

* udpate counters names

* add gas used to reserved zkCounters

* add ReservedZKCounters to pool trasactions

* Add reserved zk counters to pool transactions (0xPolygonHermez#3346)

* add reserved zk counters to pool transaction

* add reserved zk counters to pool transaction

* correct migration test

* Merge v0.5.13 into v0.6.0 (0xPolygonHermez#3350)

* Update reserved counters with used in pool db during migration (0xPolygonHermez#3352)

* return used if reserved counters are 0

* refactor

* refactor

* fix initial sequenced batch event (0xPolygonHermez#3347)

* fix initial sequenced batch event

* Add executor reserved ZK counters (0xPolygonHermez#3348)

* add executor reserved ZK counters

* update prover image to v5.0.0-RC6

* fix typos

* add check reserved counters when executing L2 block

* remove closeBatch

* update prover image v5.0.0-RC7

* fixes and logs improvements

* update prover image v5.0.0-RC8

* fix return on node OOC. Fix logs (0xPolygonHermez#3359)

* to decode ETROG processBatches use ETROG contract (0xPolygonHermez#3360)

* decode old ETROG processBatches use ETROG contract
* fix sanity genesis

* Synchronized inform field state.batch.closing_reason from DB

* Add reasons to the field `state.batch.closing_reason` (issue 0xPolygonHermez#3243)

* remove unnecessary eventlog call when processing unsigned txs (0xPolygonHermez#3365)

* Fix batch 0 timestamp (0xPolygonHermez#3364)

* ignore forkid events from another rollup (0xPolygonHermez#3383)

* Add l2block/interval metrics. Use timeoutCond when waiting for worker readyTxs (0xPolygonHermez#3380)

* Feature/cherry pick 3370 3374 synchronizer, fix bugs, ReprocessFullBatchOnClose and AcceptEmptyClosedBatches (0xPolygonHermez#3384)

* synchronizer accepts empty closed batches from trusted depending on config (0xPolygonHermez#3370)

* accept empty closed batches depending on config
* if trusted synchronization dont create L2 sync classes

* sync reprocess full batch on close, check GER, and fix minor bugs (0xPolygonHermez#3374)

* sync reprocess full batch on close
* reduce the of live of batch cache from 1hour to 5min
* fix reprocess, check virtualBatch before reseting state
* 0xPolygonHermez#3376 - check GlobalExitRoot before working on a batch
* update same data as updateWIPBatch do in the cache of batches

* set Synchronizer.L2Synchronization.ReprocessFullBatchOnClose to false

* update documentation

* fix metrics cleanUp (0xPolygonHermez#3385)

* fix check poseidonHashes exhausted (0xPolygonHermez#3393)

* remove execution mode (0xPolygonHermez#3395)

* fix metrics estimatedTxsPerSec (0xPolygonHermez#3396)

* Fix metrics estimatedTxsPerSec division (0xPolygonHermez#3398)

* fix metrics estimatedTxsPerSec div

* remove unneeded cast

* Get IM State root from receipt for data stream. (0xPolygonHermez#3400)

* get im state root from receipt

* get im state root from receipt

* get im state root from receipt

* Add gas per second estimation in metrics (0xPolygonHermez#3401)

* add gas estimation in metrics

* fix linter

* Feature/cherry pick 3375 sync add check l2block hash (0xPolygonHermez#3406)

* check L2Block hash on closed batch during sync from TrustedNode (0xPolygonHermez#3390)

* update prover image to v5.0.3 (0xPolygonHermez#3407)

* keep empty RPC.SequencerNodeURI config parameter to get node URI from the SC (0xPolygonHermez#3430)

* add log0 debug trace e2e tests (0xPolygonHermez#3422)

* add log0 debug trace e2e tests

* add log0 debug trace e2e tests

* Elderberry blockhash adjustments (0xPolygonHermez#3424)

* remove intermediate state root from receipts after Etrog

* use receipt state returned by executor instead of checking the RomError

* use receipt status from executor only after Etrog

* fix gasLimit and cumulativeGasUsed for Elderberry txs (0xPolygonHermez#3428)

* keep im state root in db (0xPolygonHermez#3427)

* generate receipt refactor (0xPolygonHermez#3436)

* generate receipt refactor

* update prover image

* downgrade prover image

---------

Co-authored-by: agnusmor <[email protected]>
Co-authored-by: Toni Ramírez <[email protected]>

* update prover to v5.0.6 (0xPolygonHermez#3437)

* remove intermediate state root from receipts after Etrog

* use receipt state returned by executor instead of checking the RomError

* use receipt status from executor only after Etrog

* fix gasLimit and cumulativeGasUsed for Elderberry txs (0xPolygonHermez#3428)

* keep im state root in db (0xPolygonHermez#3427)

* generate receipt refactor (0xPolygonHermez#3436)

* generate receipt refactor

* update prover image

* downgrade prover image

* update prover

* adapt test

* undo adapt test

* upgrade prover

---------

Co-authored-by: tclemos <[email protected]>
Co-authored-by: agnusmor <[email protected]>

* use empty byte array instead of all zeros for receipt poststate (0xPolygonHermez#3449)

* L1 Synchronization process check some L2Blocks from TrustedNode (0xPolygonHermez#3445)

* L1 Synchronization process check some L2Blocks from TrustedNode

* l1sync: if local batch is WIP need to be reprocess (0xPolygonHermez#3443)

* Synchronizer accept forkids that are the same as in database (0xPolygonHermez#3452)

* 0xPolygonHermez#3451 accept same forkid from L1
* if same forkid recived and is the last one and same FromBatchNumber update blockNumber

* remove unnecessary eventlog call when estimating tx gas (0xPolygonHermez#3457)

* Update diff

---------

Co-authored-by: Toni Ramírez <[email protected]>
Co-authored-by: agnusmor <[email protected]>
Co-authored-by: Joan Esteban <[email protected]>
Co-authored-by: Thiago Coimbra Lemos <[email protected]>
Co-authored-by: tclemos <[email protected]>
Co-authored-by: agnusmor <[email protected]>
Co-authored-by: dPunisher <[email protected]>
  • Loading branch information
8 people authored Mar 25, 2024
1 parent 5fbb272 commit 54f6b28
Show file tree
Hide file tree
Showing 28 changed files with 39,903 additions and 15,071 deletions.
1 change: 0 additions & 1 deletion cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ func runSynchronizer(cfg config.Config, etherman *etherman.Client, ethTxManagerS
log.Info("trustedSequencerURL ", trustedSequencerURL)
}
zkEVMClient := client.NewClient(trustedSequencerURL)

etherManForL1 := []syncinterfaces.EthermanFullInterface{}
// If synchronizer are using sequential mode, we only need one etherman client
if cfg.Synchronizer.L1SynchronizationMode == synchronizer.ParallelMode {
Expand Down
2 changes: 2 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ SyncInterval = "1s"
SyncChunkSize = 100
TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc
L1SynchronizationMode = "sequential"
L1SyncCheckL2BlockHash = true
L1SyncCheckL2BlockNumberhModulus = 30
[Synchronizer.L1ParallelSynchronization]
MaxClients = 10
MaxPendingNoProcessedBlocks = 25
Expand Down
2 changes: 1 addition & 1 deletion docs/config-file/node-config-doc.html

Large diffs are not rendered by default.

83 changes: 57 additions & 26 deletions docs/config-file/node-config-doc.md

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,16 @@
"description": "TrustedSequencerURL is the rpc url to connect and sync the trusted state",
"default": ""
},
"L1SyncCheckL2BlockHash": {
"type": "boolean",
"description": "L1SyncCheckL2BlockHash if is true when a batch is closed is force to check L2Block hash against trustedNode (only apply for permissionless)",
"default": true
},
"L1SyncCheckL2BlockNumberhModulus": {
"type": "integer",
"description": "L1SyncCheckL2BlockNumberhModulus is the modulus used to choose the l2block to check\na modules 5, for instance, means check all l2block multiples of 5 (10,15,20,...)",
"default": 30
},
"L1SynchronizationMode": {
"type": "string",
"enum": [
Expand Down
53,345 changes: 38,370 additions & 14,975 deletions docs/diff/diff.html

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ type storage interface {
GetBatchByForcedBatchNum(ctx context.Context, forcedBatchNumber uint64, dbTx pgx.Tx) (*Batch, error)
AddForkID(ctx context.Context, forkID ForkIDInterval, dbTx pgx.Tx) error
GetForkIDs(ctx context.Context, dbTx pgx.Tx) ([]ForkIDInterval, error)
UpdateForkID(ctx context.Context, forkID ForkIDInterval, dbTx pgx.Tx) error
UpdateForkIDToBatchNumber(ctx context.Context, forkID ForkIDInterval, dbTx pgx.Tx) error
UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error
GetNativeBlockHashesInRange(ctx context.Context, fromBlock, toBlock uint64, dbTx pgx.Tx) ([]common.Hash, error)
GetDSGenesisBlock(ctx context.Context, dbTx pgx.Tx) (*DSL2Block, error)
GetDSBatches(ctx context.Context, firstBatchNumber, lastBatchNumber uint64, readWIPBatch bool, dbTx pgx.Tx) ([]*DSBatch, error)
Expand Down
82 changes: 66 additions & 16 deletions state/mocks/mock_storage.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 21 additions & 2 deletions state/pgstatestorage/forkid.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (p *PostgresStorage) GetForkIDs(ctx context.Context, dbTx pgx.Tx) ([]state.
}

// UpdateForkID updates the forkID stored in db
func (p *PostgresStorage) UpdateForkID(ctx context.Context, forkID state.ForkIDInterval, dbTx pgx.Tx) error {
func (p *PostgresStorage) UpdateForkIDToBatchNumber(ctx context.Context, forkID state.ForkIDInterval, dbTx pgx.Tx) error {
const updateForkIDSQL = "UPDATE state.fork_id SET to_batch_num = $1 WHERE fork_id = $2"
e := p.getExecQuerier(dbTx)
if _, err := e.Exec(ctx, updateForkIDSQL, forkID.ToBatchNumber, forkID.ForkId); err != nil {
Expand All @@ -60,6 +60,25 @@ func (p *PostgresStorage) UpdateForkID(ctx context.Context, forkID state.ForkIDI
return nil
}

// UpdateForkID updates the forkID stored in db
func (p *PostgresStorage) UpdateForkIDBlockNumber(ctx context.Context, forkdID uint64, newBlockNumber uint64, updateMemCache bool, dbTx pgx.Tx) error {
const sql = "UPDATE state.fork_id SET block_num = $1 WHERE fork_id = $2"
e := p.getExecQuerier(dbTx)
if _, err := e.Exec(ctx, sql, forkdID, newBlockNumber); err != nil {
return err
}
if updateMemCache {
log.Debugf("Updating forkID %d in memory", forkdID)
forkIDs, err := p.GetForkIDs(ctx, dbTx)
if err != nil {
log.Error("error getting oldForkIDs. Error: ", err)
return err
}
p.UpdateForkIDIntervalsInMemory(forkIDs)
}
return nil
}

// UpdateForkIDIntervalsInMemory updates the forkID intervals in memory
func (p *PostgresStorage) UpdateForkIDIntervalsInMemory(intervals []state.ForkIDInterval) {
log.Infof("Updating forkIDs. Setting %d forkIDs", len(intervals))
Expand Down Expand Up @@ -88,7 +107,7 @@ func (p *PostgresStorage) AddForkIDInterval(ctx context.Context, newForkID state
return err
}
forkIDs[len(forkIDs)-1].ToBatchNumber = newForkID.FromBatchNumber - 1
err := p.UpdateForkID(ctx, forkIDs[len(forkIDs)-1], dbTx)
err := p.UpdateForkIDToBatchNumber(ctx, forkIDs[len(forkIDs)-1], dbTx)
if err != nil {
log.Errorf("error updating forkID: %d. Error: %v", forkIDs[len(forkIDs)-1].ForkId, err)
return err
Expand Down
2 changes: 1 addition & 1 deletion state/pgstatestorage/pgstatestorage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ func TestForkIDs(t *testing.T) {
require.Equal(t, forks[i].Version, forkId.Version)
}
forkID3.ToBatchNumber = 18446744073709551615
err = testState.UpdateForkID(ctx, forkID3, dbTx)
err = testState.UpdateForkIDToBatchNumber(ctx, forkID3, dbTx)
require.NoError(t, err)

forkIDs, err = testState.GetForkIDs(ctx, dbTx)
Expand Down
19 changes: 19 additions & 0 deletions state/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,25 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has
}
}

// gets the L1InfoTreeData for the transactions
l1InfoTreeData, _, _, err = s.GetL1InfoTreeDataFromBatchL2Data(ctx, transactions, dbTx)
if err != nil {
return nil, err
}

// In case we have any l1InfoTreeData, add them to the request
if len(l1InfoTreeData) > 0 {
processBatchRequestV2.L1InfoTreeData = map[uint32]*executor.L1DataV2{}
processBatchRequestV2.SkipVerifyL1InfoRoot = cTrue
for k, v := range l1InfoTreeData {
processBatchRequestV2.L1InfoTreeData[k] = &executor.L1DataV2{
GlobalExitRoot: v.GlobalExitRoot.Bytes(),
BlockHashL1: v.BlockHashL1.Bytes(),
MinTimestamp: v.MinTimestamp,
}
}
}

// Send Batch to the Executor
startTime = time.Now()
processBatchResponseV2, err := s.executorClient.ProcessBatchV2(ctx, processBatchRequestV2)
Expand Down
1 change: 0 additions & 1 deletion state/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,6 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc
}
if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR {
err = executor.RomErr(processBatchResponseV2.ErrorRom)
s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2)
return false, false, gasUsed, nil, err
}

Expand Down
139 changes: 139 additions & 0 deletions synchronizer/actions/check_l2block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package actions

import (
"context"
"errors"
"fmt"
"math/big"

"github.com/0xPolygonHermez/zkevm-node/jsonrpc/types"
"github.com/0xPolygonHermez/zkevm-node/log"
"github.com/0xPolygonHermez/zkevm-node/state"
"github.com/jackc/pgx/v4"
)

// Implements PostClosedBatchChecker

type stateGetL2Block interface {
GetL2BlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, error)
GetLastL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error)
}

type trustedRPCGetL2Block interface {
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
}

// CheckL2BlockHash is a struct that implements a checker of L2Block hash
type CheckL2BlockHash struct {
state stateGetL2Block
trustedClient trustedRPCGetL2Block
lastL2BlockChecked uint64
// Is a modulus used to choose the l2block to check
modulusL2BlockToCheck uint64
}

// NewCheckL2BlockHash creates a new CheckL2BlockHash
func NewCheckL2BlockHash(state stateGetL2Block,
trustedClient trustedRPCGetL2Block,
initialL2BlockNumber uint64,
modulusBlockNumber uint64) *CheckL2BlockHash {
return &CheckL2BlockHash{
state: state,
trustedClient: trustedClient,
lastL2BlockChecked: initialL2BlockNumber,
modulusL2BlockToCheck: modulusBlockNumber,
}
}

// CheckL2Block checks the L2Block hash between the local and the trusted
func (p *CheckL2BlockHash) CheckL2Block(ctx context.Context, dbTx pgx.Tx) error {
lastLocalL2BlockNumber, err := p.state.GetLastL2BlockNumber(ctx, dbTx)
if errors.Is(err, state.ErrNotFound) || errors.Is(err, state.ErrStateNotSynchronized) {
log.Debugf("checkL2block:No L2Block in database. err: %s", err.Error())
return nil
}
if err != nil {
log.Errorf("checkL2block: Error getting last L2Block from the database. err: %s", err.Error())
return err
}
shouldCheck, l2BlockNumber := p.GetNextL2BlockToCheck(lastLocalL2BlockNumber, p.GetMinimumL2BlockToCheck())
if !shouldCheck {
return nil
}
err = p.iterationCheckL2Block(ctx, l2BlockNumber, dbTx)
if err != nil {
return err
}
return nil
}

// GetNextL2BlockToCheck returns true is need to check and the blocknumber
func (p *CheckL2BlockHash) GetNextL2BlockToCheck(lastLocalL2BlockNumber, minL2BlockNumberToCheck uint64) (bool, uint64) {
l2BlockNumber := max(minL2BlockNumberToCheck, lastLocalL2BlockNumber)
if l2BlockNumber > lastLocalL2BlockNumber {
log.Infof("checkL2block: skip check L2block (next to check: %d) currently LastL2BlockNumber: %d", minL2BlockNumberToCheck, lastLocalL2BlockNumber)
return false, 0
}
return true, l2BlockNumber
}

// GetMinimumL2BlockToCheck returns the minimum L2Block to check
func (p *CheckL2BlockHash) GetMinimumL2BlockToCheck() uint64 {
if p.modulusL2BlockToCheck == 0 {
return p.lastL2BlockChecked + 1
}
return ((p.lastL2BlockChecked / p.modulusL2BlockToCheck) + 1) * p.modulusL2BlockToCheck
}

// GetL2Blocks returns localL2Block and trustedL2Block
func (p *CheckL2BlockHash) GetL2Blocks(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.L2Block, *types.Block, error) {
localL2Block, err := p.state.GetL2BlockByNumber(ctx, blockNumber, dbTx)
if err != nil {
log.Debugf("checkL2block: Error getting L2Block %d from the database. err: %s", blockNumber, err.Error())
return nil, nil, err
}
trustedL2Block, err := p.trustedClient.BlockByNumber(ctx, big.NewInt(int64(blockNumber)))
if err != nil {
log.Errorf("checkL2block: Error getting L2Block %d from the Trusted RPC. err:%s", blockNumber, err.Error())
return nil, nil, err
}
return localL2Block, trustedL2Block, nil
}

// CheckPostClosedBatch checks the last L2Block hash on close batch
func (p *CheckL2BlockHash) iterationCheckL2Block(ctx context.Context, l2BlockNumber uint64, dbTx pgx.Tx) error {
prefixLogs := fmt.Sprintf("checkL2block: L2BlockNumber: %d ", l2BlockNumber)
localL2Block, trustedL2Block, err := p.GetL2Blocks(ctx, l2BlockNumber, dbTx)
if errors.Is(err, state.ErrNotFound) || errors.Is(err, state.ErrStateNotSynchronized) {
log.Debugf("%s not found in the database", prefixLogs, l2BlockNumber)
return nil
}
if err != nil {
log.Errorf("%s Error getting from the database and trusted. err: %s", prefixLogs, err.Error())
return err
}
if localL2Block == nil || trustedL2Block == nil {
log.Errorf("%s localL2Block or trustedL2Block is nil", prefixLogs, l2BlockNumber)
return nil
}

if err := compareL2Blocks(prefixLogs, localL2Block, trustedL2Block); err != nil {
log.Errorf("%s Error comparing L2Blocks from the database and trusted. err: %s", prefixLogs, err.Error())
return err
}

log.Infof("%s checked L2Block in the database and the trusted batch are the same %s", prefixLogs, localL2Block.Hash().String())
// Compare the two blocks
p.lastL2BlockChecked = l2BlockNumber
return nil
}

func compareL2Blocks(prefixLogs string, localL2Block *state.L2Block, trustedL2Block *types.Block) error {
if localL2Block == nil || trustedL2Block == nil || trustedL2Block.Hash == nil {
return fmt.Errorf("%s localL2Block or trustedL2Block or trustedHash are nil", prefixLogs)
}
if localL2Block.Hash() != *trustedL2Block.Hash {
return fmt.Errorf("%s localL2Block.Hash %s and trustedL2Block.Hash %s are different", prefixLogs, localL2Block.Hash().String(), (*trustedL2Block.Hash).String())
}
return nil
}
Loading

0 comments on commit 54f6b28

Please sign in to comment.