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

fix: 154 sanity check for genesis block #155

Merged
merged 6 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
5 changes: 5 additions & 0 deletions state/block.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package state

import (
"fmt"
"time"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -14,6 +15,10 @@ type Block struct {
ReceivedAt time.Time
}

func (b *Block) String() string {
return fmt.Sprintf("BlockNumber: %d, BlockHash: %s, ParentHash: %s, ReceivedAt: %s", b.BlockNumber, b.BlockHash, b.ParentHash, b.ReceivedAt)
}

// NewBlock creates a block with the given data.
func NewBlock(blockNumber uint64) *Block {
return &Block{BlockNumber: blockNumber}
Expand Down
130 changes: 74 additions & 56 deletions synchronizer/synchronizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ func (s *ClientSynchronizer) processGenesis() (*state.Block, error) {
log.Errorf("error creating db transaction to get latest block. Error: %v", err)
return nil, err
}
// This add the genesis block and set values on tree
genesisRoot, err := s.state.SetGenesis(s.ctx, *lastEthBlockSynced, s.genesis, stateMetrics.SynchronizerCallerLabel, dbTx)
if err != nil {
log.Error("error setting genesis: ", err)
Expand Down Expand Up @@ -562,12 +563,18 @@ func (s *ClientSynchronizer) RequestAndProcessRollupGenesisBlock(dbTx pgx.Tx, la
log.Error("error getting rollupInfoByBlockRange after set the genesis: ", err)
return err
}
// Check that the response is the expected. It should be 1 block with 2 orders
// Check that the response is the expected. It should be 1 block with ForkID event
log.Debugf("genesis block (%d) events: %+v", lastEthBlockSynced.BlockNumber, order)
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
err = sanityCheckForGenesisBlockRollupInfo(blocks, order)
if err != nil {
return err
}
forkId := s.state.GetForkIDByBlockNumber(blocks[0].BlockNumber)
log.Infof("Processing genesis block %d orders: %+v", lastEthBlockSynced.BlockNumber, order)
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
err = s.internalProcessBlock(blocks[0], order[blocks[0].BlockHash], false, dbTx)
if err != nil {
log.Error("error processinge events on genesis block %d: err:%w", lastEthBlockSynced.BlockNumber, err)
joanestebanr marked this conversation as resolved.
Show resolved Hide resolved
}
/*forkId := s.state.GetForkIDByBlockNumber(blocks[0].BlockNumber)
err = s.l1EventProcessors.Process(s.ctx, actions.ForkIdType(forkId), etherman.Order{Name: etherman.ForkIDsOrder, Pos: 0}, &blocks[0], dbTx)
if err != nil {
log.Error("error storing genesis forkID: ", err)
Expand All @@ -582,20 +589,25 @@ func (s *ClientSynchronizer) RequestAndProcessRollupGenesisBlock(dbTx pgx.Tx, la
return err
}
}
*/
return nil
}

func sanityCheckForGenesisBlockRollupInfo(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
if len(blocks) != 1 || len(order) < 1 || len(order[blocks[0].BlockHash]) < 1 {
log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders")
return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders")
log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with minimum 2 orders")
return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with minimum 2 orders")
}
if order[blocks[0].BlockHash][0].Name != etherman.ForkIDsOrder {
log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder, got %s", order[blocks[0].BlockHash][0].Name)
return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder")
// The genesis block implies 1 ForkID event
for _, value := range order[blocks[0].BlockHash] {
if value.Name == etherman.ForkIDsOrder {
return nil
}
}

return nil
err := fmt.Errorf("events on genesis block (%d) need a ForkIDsOrder event but this block got %+v",
blocks[0].BlockNumber, order[blocks[0].BlockHash])
log.Error(err.Error())
return err
}

// This function syncs the node from a specific block to the latest
Expand Down Expand Up @@ -723,78 +735,84 @@ func (s *ClientSynchronizer) syncBlocksSequential(lastEthBlockSynced *state.Bloc

// ProcessBlockRange process the L1 events and stores the information in the db
func (s *ClientSynchronizer) ProcessBlockRange(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
// New info has to be included into the db using the state
for i := range blocks {
// Begin db transaction
dbTx, err := s.state.BeginStateTransaction(s.ctx)
if err != nil {
log.Errorf("error creating db transaction to store block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
return err
}
b := state.Block{
BlockNumber: blocks[i].BlockNumber,
BlockHash: blocks[i].BlockHash,
ParentHash: blocks[i].ParentHash,
ReceivedAt: blocks[i].ReceivedAt,
err = s.internalProcessBlock(blocks[i], order[blocks[i].BlockHash], true, dbTx)
if err != nil {
log.Error("rollingback BlockNumber: %d, because error internalProcessBlock: ", blocks[i].BlockNumber, err)
// If any goes wrong we ensure that the state is rollbacked
rollbackErr := dbTx.Rollback(s.ctx)
if rollbackErr != nil && !errors.Is(rollbackErr, pgx.ErrTxClosed) {
log.Warnf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
return fmt.Errorf("error rollback BlockNumber: %d: err:%w original error:%w", blocks[i].BlockNumber, rollbackErr, err)
}
return err
}
// Add block information
err = s.state.AddBlock(s.ctx, &b, dbTx)

err = dbTx.Commit(s.ctx)
if err != nil {
log.Errorf("error storing block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
log.Errorf("error committing state to store block. BlockNumber: %d, err: %v", blocks[i].BlockNumber, err)
rollbackErr := dbTx.Rollback(s.ctx)
if rollbackErr != nil {
log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
return rollbackErr
}
return err
}
}
return nil
}

for _, element := range order[blocks[i].BlockHash] {
batchSequence := l1event_orders.GetSequenceFromL1EventOrder(element.Name, &blocks[i], element.Pos)
var forkId uint64
if batchSequence != nil {
forkId = s.state.GetForkIDByBatchNumber(batchSequence.FromBatchNumber)
log.Debug("EventOrder: ", element.Name, ". Batch Sequence: ", batchSequence, "forkId: ", forkId)
} else {
forkId = s.state.GetForkIDByBlockNumber(blocks[i].BlockNumber)
log.Debug("EventOrder: ", element.Name, ". BlockNumber: ", blocks[i].BlockNumber, "forkId: ", forkId)
}
forkIdTyped := actions.ForkIdType(forkId)
// Process event received from l1
err := s.l1EventProcessors.Process(s.ctx, forkIdTyped, element, &blocks[i], dbTx)
if err != nil {
log.Error("error: ", err)
// If any goes wrong we ensure that the state is rollbacked
rollbackErr := dbTx.Rollback(s.ctx)
if rollbackErr != nil && !errors.Is(rollbackErr, pgx.ErrTxClosed) {
log.Warnf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
return rollbackErr
}
return err
}
// ProcessBlockRange process the L1 events and stores the information in the db
func (s *ClientSynchronizer) internalProcessBlock(blocks etherman.Block, order []etherman.Order, addBlock bool, dbTx pgx.Tx) error {
var err error
// New info has to be included into the db using the state
if addBlock {
b := state.Block{
BlockNumber: blocks.BlockNumber,
BlockHash: blocks.BlockHash,
ParentHash: blocks.ParentHash,
ReceivedAt: blocks.ReceivedAt,
}
log.Debug("Checking FlushID to commit L1 data to db")
err = s.checkFlushID(dbTx)
// Add block information
log.Debugf("Storing block. Block: %s", b.String())
err = s.state.AddBlock(s.ctx, &b, dbTx)
if err != nil {
log.Errorf("error checking flushID. Error: %v", err)
rollbackErr := dbTx.Rollback(s.ctx)
if rollbackErr != nil {
log.Errorf("error rolling back state. RollbackErr: %s, Error : %v", rollbackErr.Error(), err)
return rollbackErr
}
log.Errorf("error storing block. BlockNumber: %d, error: %v", blocks.BlockNumber, err)
return err
}
err = dbTx.Commit(s.ctx)
}

for _, element := range order {
batchSequence := l1event_orders.GetSequenceFromL1EventOrder(element.Name, &blocks, element.Pos)
var forkId uint64
if batchSequence != nil {
forkId = s.state.GetForkIDByBatchNumber(batchSequence.FromBatchNumber)
log.Debug("EventOrder: ", element.Name, ". Batch Sequence: ", batchSequence, "forkId: ", forkId)
} else {
forkId = s.state.GetForkIDByBlockNumber(blocks.BlockNumber)
log.Debug("EventOrder: ", element.Name, ". BlockNumber: ", blocks.BlockNumber, "forkId: ", forkId)
}
forkIdTyped := actions.ForkIdType(forkId)
// Process event received from l1
err := s.l1EventProcessors.Process(s.ctx, forkIdTyped, element, &blocks, dbTx)
if err != nil {
log.Errorf("error committing state to store block. BlockNumber: %d, err: %v", blocks[i].BlockNumber, err)
rollbackErr := dbTx.Rollback(s.ctx)
if rollbackErr != nil {
log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
return rollbackErr
}
log.Error("1EventProcessors.Process error: ", err)
return err
}
}
log.Debug("Checking FlushID to commit L1 data to db")
err = s.checkFlushID(dbTx)
if err != nil {
log.Errorf("error checking flushID. Error: %v", err)
return err
}

return nil
}

Expand Down
24 changes: 24 additions & 0 deletions synchronizer/synchronizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,30 @@ type mocks struct {
//EventLog *eventLogMock
}

func TestExploratory(t *testing.T) {
t.Skip("This test is for exploratory purposes, it is not a real test")
cfg := etherman.Config{
URL: "https://eth-sepolia.g.alchemy.com/v2/",
ForkIDChunkSize: 100,
MultiGasProvider: false,
}
l1Config := etherman.L1Config{
L1ChainID: 1,
ZkEVMAddr: common.HexToAddress("0xf3eca1d175cd7811519e251a9e0c7f13c9217734"),
RollupManagerAddr: common.HexToAddress("0x32d33d5137a7cffb54c5bf8371172bcec5f310ff"),
PolAddr: common.HexToAddress("0x6a7c3f4b0651d6da389ad1d11d962ea458cdca70"),
GlobalExitRootManagerAddr: common.HexToAddress("0xad1490c248c5d3cbae399fd529b79b42984277df"),
}

eth, err := etherman.NewClient(cfg, l1Config, nil)
require.NoError(t, err)
blockNumber := uint64(6510565)
blocks, order, err := eth.GetRollupInfoByBlockRange(context.TODO(), blockNumber, &blockNumber)
require.NoError(t, err)
require.Equal(t, 1, len(blocks))
require.Equal(t, 1, len(order))
}

// Feature #2220 and #2239: Optimize Trusted state synchronization
//
// this Check partially point 2: Use previous batch stored in memory to avoid getting from database
Expand Down
Loading