Skip to content
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

Merge upstream v0.6.6 changes #134

Merged
merged 21 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bb0395b
check GER and index of synced L1InfoRoot matches with sc values (#3551)
agnusmor Apr 11, 2024
52e9667
apply txIndex fix to StoreTransactions; add migration to fix wrong tx…
tclemos Apr 12, 2024
d9ec8f0
Feature/#3549 reorgs improvement (#3553)
ARR552 Apr 15, 2024
cfeb68d
Fix adding tx that matches with tx that is being processed (#3559)
agnusmor Apr 15, 2024
b9f7fbf
synchronizer: check l1blocks (#3546)
joanestebanr Apr 16, 2024
a144388
Fix + remove empty blocks (#3564)
ARR552 Apr 17, 2024
6395e24
Fix/#3565 reorg (#3566)
ARR552 Apr 17, 2024
2d75bc0
fix L1InfoRoot when an error happens during the process of the L1 inf…
ARR552 Apr 22, 2024
bc951bc
added logs to analyze blocking issue when storing L2 block
agnusmor Apr 22, 2024
7b6a0ac
add debug logs for datastreamer
agnusmor Apr 22, 2024
94dc305
fix #3581 synchronizer panic synchronizing from trusted node (#3582)
joanestebanr Apr 23, 2024
b45d78e
synchronized: #3583 stop sync from l2 after no closed batch (#3584)
joanestebanr Apr 23, 2024
4dc6f3b
Update datastream lib to the latest version with additional debug info
dpunish3r Apr 24, 2024
578052e
update dslib client interface
dpunish3r Apr 24, 2024
59f7ebb
Update the diff
Stefan-Ethernal Apr 26, 2024
45d64ed
Fix non-e2e tests
Stefan-Ethernal Apr 26, 2024
d5757c0
Update the docker image for the mock L1 network
Stefan-Ethernal May 10, 2024
3e88600
Update the diff
Stefan-Ethernal May 13, 2024
385bd72
Fix typo in the comment
Stefan-Ethernal May 21, 2024
67b5ee1
Use the Geth v1.13.11 Docker image and update the genesis spec
Stefan-Ethernal May 21, 2024
d59718e
Update the diff
Stefan-Ethernal May 21, 2024
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
Prev Previous commit
Next Next commit
synchronizer: check l1blocks (0xPolygonHermez#3546)
* wip

* run on background L1block checker

* fix lint and documentation

* fix conflict

* add unittest

* more unittest

* fix lint

* increase timeout for async unittest

* fix unittest

* rename GetResponse for GetResult and fix uniitest

* add a second gorutines for check the newest blocks

* more unittest

* add unittest and run also preCheck on launch

* by default Precheck from FINALIZED and SAFE

* fix unittest, apply PR comments

* changes suggested by ARR552 in integration method

* fix documentation

* import new network-l1-mock from PR#3553

* import new network-l1-mock from PR#3553

* import new network-l1-mock from PR#3553

* import new network-l1-mock from PR#3553

* fix unittest

* fix PR comments

* fix error

* checkReorgAndExecuteReset can't be call with lastEthBlockSynced=nil

* add parentHash to error

* fix error

* merge 3553 fix unittest

* fix unittest

* fix wrong merge

* adapt parallel reorg detection to flow

* fix unit tests

* fix log

* allow use sync parallel mode

---------

Co-authored-by: Alonso <[email protected]>
  • Loading branch information
2 people authored and Stefan-Ethernal committed May 21, 2024
commit b9f7fbf18875ab45104fd276f6cfe07896963ba7
8 changes: 8 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ SyncBlockProtection = "safe" # latest, finalized, safe
L1SynchronizationMode = "sequential"
L1SyncCheckL2BlockHash = true
L1SyncCheckL2BlockNumberhModulus = 30
[Synchronizer.L1BlockCheck]
Enable = true
L1SafeBlockPoint = "finalized"
L1SafeBlockOffset = 0
ForceCheckBeforeStart = true
PreCheckEnable = true
L1PreSafeBlockPoint = "safe"
L1PreSafeBlockOffset = 0
[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.

165 changes: 147 additions & 18 deletions docs/config-file/node-config-doc.md

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,57 @@
"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
},
"L1BlockCheck": {
"properties": {
"Enable": {
"type": "boolean",
"description": "Enable if is true then the check l1 Block Hash is active",
"default": true
},
"L1SafeBlockPoint": {
"type": "string",
"enum": [
"finalized",
"safe",
"latest"
],
"description": "L1SafeBlockPoint is the point that a block is considered safe enough to be checked\nit can be: finalized, safe,pending or latest",
"default": "finalized"
},
"L1SafeBlockOffset": {
"type": "integer",
"description": "L1SafeBlockOffset is the offset to add to L1SafeBlockPoint as a safe point\nit can be positive or negative\nExample: L1SafeBlockPoint= finalized, L1SafeBlockOffset= -10, then the safe block ten blocks before the finalized block",
"default": 0
},
"ForceCheckBeforeStart": {
"type": "boolean",
"description": "ForceCheckBeforeStart if is true then the first time the system is started it will force to check all pending blocks",
"default": true
},
"PreCheckEnable": {
"type": "boolean",
"description": "PreCheckEnable if is true then the pre-check is active, will check blocks between L1SafeBlock and L1PreSafeBlock",
"default": true
},
"L1PreSafeBlockPoint": {
"type": "string",
"enum": [
"finalized",
"safe",
"latest"
],
"description": "L1PreSafeBlockPoint is the point that a block is considered safe enough to be checked\nit can be: finalized, safe,pending or latest",
"default": "safe"
},
"L1PreSafeBlockOffset": {
"type": "integer",
"description": "L1PreSafeBlockOffset is the offset to add to L1PreSafeBlockPoint as a safe point\nit can be positive or negative\nExample: L1PreSafeBlockPoint= finalized, L1PreSafeBlockOffset= -10, then the safe block ten blocks before the finalized block",
"default": 0
}
},
"additionalProperties": false,
"type": "object"
},
"L1SynchronizationMode": {
"type": "string",
"enum": [
Expand Down
2 changes: 2 additions & 0 deletions state/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type storage interface {
GetLastBlock(ctx context.Context, dbTx pgx.Tx) (*Block, error)
GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*Block, error)
GetFirstUncheckedBlock(ctx context.Context, fromBlockNumber uint64, dbTx pgx.Tx) (*Block, error)
GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*Block, error)
UpdateCheckedBlockByNumber(ctx context.Context, blockNumber uint64, newCheckedStatus bool, dbTx pgx.Tx) error
AddGlobalExitRoot(ctx context.Context, exitRoot *GlobalExitRoot, dbTx pgx.Tx) error
GetLatestGlobalExitRoot(ctx context.Context, maxBlockNumber uint64, dbTx pgx.Tx) (GlobalExitRoot, time.Time, error)
Expand Down Expand Up @@ -164,4 +165,5 @@ type storage interface {
UpdateBatchAsChecked(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error
GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error)
GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error)
GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*Block, error)
}
121 changes: 121 additions & 0 deletions state/mocks/mock_storage.go

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

49 changes: 49 additions & 0 deletions state/pgstatestorage/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,35 @@ func (p *PostgresStorage) GetFirstUncheckedBlock(ctx context.Context, fromBlockN
return &block, err
}

func (p *PostgresStorage) GetUncheckedBlocks(ctx context.Context, fromBlockNumber uint64, toBlockNumber uint64, dbTx pgx.Tx) ([]*state.Block, error) {
const getUncheckedBlocksSQL = "SELECT block_num, block_hash, parent_hash, received_at, checked FROM state.block WHERE block_num>=$1 AND block_num<=$2 AND checked=false ORDER BY block_num"

q := p.getExecQuerier(dbTx)

rows, err := q.Query(ctx, getUncheckedBlocksSQL, fromBlockNumber, toBlockNumber)
if err != nil {
return nil, err
}
defer rows.Close()

var blocks []*state.Block
for rows.Next() {
var (
blockHash string
parentHash string
block state.Block
)
err := rows.Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
if err != nil {
return nil, err
}
block.BlockHash = common.HexToHash(blockHash)
block.ParentHash = common.HexToHash(parentHash)
blocks = append(blocks, &block)
}
return blocks, nil
}

// GetPreviousBlock gets the offset previous L1 block respect to latest.
func (p *PostgresStorage) GetPreviousBlock(ctx context.Context, offset uint64, dbTx pgx.Tx) (*state.Block, error) {
var (
Expand All @@ -83,6 +112,26 @@ func (p *PostgresStorage) GetPreviousBlock(ctx context.Context, offset uint64, d
return &block, err
}

// GetPreviousBlockToBlockNumber gets the previous L1 block respect blockNumber.
func (p *PostgresStorage) GetPreviousBlockToBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error) {
var (
blockHash string
parentHash string
block state.Block
)
const getPreviousBlockSQL = "SELECT block_num, block_hash, parent_hash, received_at,checked FROM state.block WHERE block_num < $1 ORDER BY block_num DESC LIMIT 1 "

q := p.getExecQuerier(dbTx)

err := q.QueryRow(ctx, getPreviousBlockSQL, blockNumber).Scan(&block.BlockNumber, &blockHash, &parentHash, &block.ReceivedAt, &block.Checked)
if errors.Is(err, pgx.ErrNoRows) {
return nil, state.ErrNotFound
}
block.BlockHash = common.HexToHash(blockHash)
block.ParentHash = common.HexToHash(parentHash)
return &block, err
}

// GetBlockByNumber returns the L1 block with the given number.
func (p *PostgresStorage) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error) {
var (
Expand Down
21 changes: 21 additions & 0 deletions state/pgstatestorage/pgstatestorage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1795,3 +1795,24 @@ func TestUpdateCheckedBlockByNumber(t *testing.T) {
require.NoError(t, err)
require.False(t, b1.Checked)
}

func TestGetUncheckedBlocks(t *testing.T) {
var err error
blockNumber := uint64(61001)
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber, Checked: true}, nil)
require.NoError(t, err)
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 1, Checked: false}, nil)
require.NoError(t, err)
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 2, Checked: true}, nil)
require.NoError(t, err)
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 3, Checked: false}, nil)
require.NoError(t, err)
err = testState.AddBlock(context.Background(), &state.Block{BlockNumber: blockNumber + 4, Checked: false}, nil)
require.NoError(t, err)

blocks, err := testState.GetUncheckedBlocks(context.Background(), blockNumber, blockNumber+3, nil)
require.NoError(t, err)
require.Equal(t, 2, len(blocks))
require.Equal(t, uint64(blockNumber+1), blocks[0].BlockNumber)
require.Equal(t, uint64(blockNumber+3), blocks[1].BlockNumber)
}
44 changes: 44 additions & 0 deletions synchronizer/common/reorg_error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package common

import "fmt"

// ReorgError is an error that is raised when a reorg is detected
type ReorgError struct {
// BlockNumber is the block number that caused the reorg
BlockNumber uint64
Err error
}

// NewReorgError creates a new ReorgError
func NewReorgError(blockNumber uint64, err error) *ReorgError {
return &ReorgError{
BlockNumber: blockNumber,
Err: err,
}
}

func (e *ReorgError) Error() string {
return fmt.Sprintf("%s blockNumber: %d", e.Err.Error(), e.BlockNumber)
}

// IsReorgError checks if an error is a ReorgError
func IsReorgError(err error) bool {
_, ok := err.(*ReorgError)
return ok
}

// GetReorgErrorBlockNumber returns the block number that caused the reorg
func GetReorgErrorBlockNumber(err error) uint64 {
if reorgErr, ok := err.(*ReorgError); ok {
return reorgErr.BlockNumber
}
return 0
}

// GetReorgError returns the error that caused the reorg
func GetReorgError(err error) error {
if reorgErr, ok := err.(*ReorgError); ok {
return reorgErr.Err
}
return nil
}
40 changes: 40 additions & 0 deletions synchronizer/common/syncinterfaces/async_l1_block_checker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package syncinterfaces

import (
"context"
"fmt"

"github.com/0xPolygonHermez/zkevm-node/state"
)

type IterationResult struct {
Err error
ReorgDetected bool
BlockNumber uint64
ReorgMessage string
}

func (ir *IterationResult) String() string {
if ir.Err == nil {
if ir.ReorgDetected {
return fmt.Sprintf("IterationResult{ReorgDetected: %v, BlockNumber: %d ReorgMessage:%s}", ir.ReorgDetected, ir.BlockNumber, ir.ReorgMessage)
} else {
return "IterationResult{None}"
}
} else {
return fmt.Sprintf("IterationResult{Err: %s, ReorgDetected: %v, BlockNumber: %d ReorgMessage:%s}", ir.Err.Error(), ir.ReorgDetected, ir.BlockNumber, ir.ReorgMessage)
}
}

type AsyncL1BlockChecker interface {
Run(ctx context.Context, onFinish func())
RunSynchronous(ctx context.Context) IterationResult
Stop()
GetResult() *IterationResult
}

type L1BlockCheckerIntegrator interface {
OnStart(ctx context.Context) error
OnResetState(ctx context.Context)
CheckReorgWrapper(ctx context.Context, reorgFirstBlockOk *state.Block, errReportedByReorgFunc error) (*state.Block, error)
}
Loading