github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/synchronizer/synchronizer.go (about)

     1  package synchronizer
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"math/big"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/0xPolygon/supernets2-data-availability/client"
    12  	"github.com/0xPolygon/supernets2-node/etherman"
    13  	"github.com/0xPolygon/supernets2-node/hex"
    14  	"github.com/0xPolygon/supernets2-node/jsonrpc/types"
    15  	"github.com/0xPolygon/supernets2-node/log"
    16  	"github.com/0xPolygon/supernets2-node/state"
    17  	"github.com/0xPolygon/supernets2-node/state/metrics"
    18  	"github.com/ethereum/go-ethereum/common"
    19  	"github.com/jackc/pgx/v4"
    20  )
    21  
    22  // Synchronizer connects L1 and L2
    23  type Synchronizer interface {
    24  	Sync() error
    25  	Stop()
    26  }
    27  
    28  // ClientSynchronizer connects L1 and L2
    29  type ClientSynchronizer struct {
    30  	isTrustedSequencer         bool
    31  	etherMan                   ethermanInterface
    32  	state                      stateInterface
    33  	pool                       poolInterface
    34  	ethTxManager               ethTxManager
    35  	zkEVMClient                zkEVMClientInterface
    36  	ctx                        context.Context
    37  	cancelCtx                  context.CancelFunc
    38  	genesis                    state.Genesis
    39  	cfg                        Config
    40  	committeeMembers           []etherman.DataCommitteeMember
    41  	selectedCommitteeMember    int
    42  	dataCommitteeClientFactory client.ClientFactoryInterface
    43  }
    44  
    45  // NewSynchronizer creates and initializes an instance of Synchronizer
    46  func NewSynchronizer(
    47  	isTrustedSequencer bool,
    48  	ethMan ethermanInterface,
    49  	st stateInterface,
    50  	pool poolInterface,
    51  	ethTxManager ethTxManager,
    52  	zkEVMClient zkEVMClientInterface,
    53  	genesis state.Genesis,
    54  	cfg Config,
    55  	clientFactory client.ClientFactoryInterface,
    56  ) (Synchronizer, error) {
    57  	ctx, cancel := context.WithCancel(context.Background())
    58  
    59  	c := &ClientSynchronizer{
    60  		isTrustedSequencer:         isTrustedSequencer,
    61  		state:                      st,
    62  		etherMan:                   ethMan,
    63  		pool:                       pool,
    64  		ctx:                        ctx,
    65  		cancelCtx:                  cancel,
    66  		ethTxManager:               ethTxManager,
    67  		zkEVMClient:                zkEVMClient,
    68  		genesis:                    genesis,
    69  		cfg:                        cfg,
    70  		dataCommitteeClientFactory: clientFactory,
    71  	}
    72  	err := c.loadCommittee()
    73  	return c, err
    74  }
    75  
    76  var waitDuration = time.Duration(0)
    77  
    78  // Sync function will read the last state synced and will continue from that point.
    79  // Sync() will read blockchain events to detect rollup updates
    80  func (s *ClientSynchronizer) Sync() error {
    81  	// If there is no lastEthereumBlock means that sync from the beginning is necessary. If not, it continues from the retrieved ethereum block
    82  	// Get the latest synced block. If there is no block on db, use genesis block
    83  	log.Info("Sync started")
    84  	dbTx, err := s.state.BeginStateTransaction(s.ctx)
    85  	if err != nil {
    86  		log.Errorf("error creating db transaction to get latest block. Error: %v", err)
    87  		return err
    88  	}
    89  	lastEthBlockSynced, err := s.state.GetLastBlock(s.ctx, dbTx)
    90  	if err != nil {
    91  		if errors.Is(err, state.ErrStateNotSynchronized) {
    92  			log.Info("State is empty, verifying genesis block")
    93  			valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.GenesisBlockNum)
    94  			if err != nil {
    95  				log.Error("error checking genesis block number. Error: ", err)
    96  				rollbackErr := dbTx.Rollback(s.ctx)
    97  				if rollbackErr != nil {
    98  					log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
    99  					return rollbackErr
   100  				}
   101  				return err
   102  			} else if !valid {
   103  				log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
   104  				rollbackErr := dbTx.Rollback(s.ctx)
   105  				if rollbackErr != nil {
   106  					log.Errorf("error rolling back state. RollbackErr: %v", rollbackErr)
   107  					return rollbackErr
   108  				}
   109  				return fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")
   110  			}
   111  			log.Info("Setting genesis block")
   112  			header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(0).SetUint64(s.genesis.GenesisBlockNum))
   113  			if err != nil {
   114  				log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.GenesisBlockNum, err)
   115  				rollbackErr := dbTx.Rollback(s.ctx)
   116  				if rollbackErr != nil {
   117  					log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   118  					return rollbackErr
   119  				}
   120  				return err
   121  			}
   122  			lastEthBlockSynced = &state.Block{
   123  				BlockNumber: header.Number.Uint64(),
   124  				BlockHash:   header.Hash(),
   125  				ParentHash:  header.ParentHash,
   126  				ReceivedAt:  time.Unix(int64(header.Time), 0),
   127  			}
   128  			newRoot, err := s.state.SetGenesis(s.ctx, *lastEthBlockSynced, s.genesis, dbTx)
   129  			if err != nil {
   130  				log.Error("error setting genesis: ", err)
   131  				rollbackErr := dbTx.Rollback(s.ctx)
   132  				if rollbackErr != nil {
   133  					log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   134  					return rollbackErr
   135  				}
   136  				return err
   137  			}
   138  			var root common.Hash
   139  			root.SetBytes(newRoot)
   140  			if root != s.genesis.Root {
   141  				log.Errorf("Calculated newRoot should be %s instead of %s", s.genesis.Root.String(), root.String())
   142  				rollbackErr := dbTx.Rollback(s.ctx)
   143  				if rollbackErr != nil {
   144  					log.Errorf("error rolling back state. RollbackErr: %v", rollbackErr)
   145  					return rollbackErr
   146  				}
   147  				return fmt.Errorf("Calculated newRoot should be %s instead of %s", s.genesis.Root.String(), root.String())
   148  			}
   149  			log.Debug("Genesis root matches!")
   150  		} else {
   151  			log.Error("unexpected error getting the latest ethereum block. Error: ", err)
   152  			rollbackErr := dbTx.Rollback(s.ctx)
   153  			if rollbackErr != nil {
   154  				log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   155  				return rollbackErr
   156  			}
   157  			return err
   158  		}
   159  	}
   160  	initBatchNumber, err := s.state.GetLastBatchNumber(s.ctx, dbTx)
   161  	if err != nil {
   162  		log.Error("error getting latest batchNumber synced. Error: ", err)
   163  		rollbackErr := dbTx.Rollback(s.ctx)
   164  		if rollbackErr != nil {
   165  			log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   166  			return rollbackErr
   167  		}
   168  		return err
   169  	}
   170  	err = s.state.SetInitSyncBatch(s.ctx, initBatchNumber, dbTx)
   171  	if err != nil {
   172  		log.Error("error setting initial batch number. Error: ", err)
   173  		rollbackErr := dbTx.Rollback(s.ctx)
   174  		if rollbackErr != nil {
   175  			log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   176  			return rollbackErr
   177  		}
   178  		return err
   179  	}
   180  	if err := dbTx.Commit(s.ctx); err != nil {
   181  		log.Errorf("error committing dbTx, err: %v", err)
   182  		rollbackErr := dbTx.Rollback(s.ctx)
   183  		if rollbackErr != nil {
   184  			log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error())
   185  			return rollbackErr
   186  		}
   187  		return err
   188  	}
   189  
   190  	for {
   191  		select {
   192  		case <-s.ctx.Done():
   193  			return nil
   194  		case <-time.After(waitDuration):
   195  			latestSequencedBatchNumber, err := s.etherMan.GetLatestBatchNumber()
   196  			if err != nil {
   197  				log.Warn("error getting latest sequenced batch in the rollup. Error: ", err)
   198  				continue
   199  			}
   200  			latestSyncedBatch, err := s.state.GetLastBatchNumber(s.ctx, nil)
   201  			if err != nil {
   202  				log.Warn("error getting latest batch synced in the db. Error: ", err)
   203  				continue
   204  			}
   205  			// Check the latest verified Batch number in the smc
   206  			lastVerifiedBatchNumber, err := s.etherMan.GetLatestVerifiedBatchNum()
   207  			if err != nil {
   208  				log.Warn("error getting last verified batch in the rollup. Error: ", err)
   209  				continue
   210  			}
   211  			err = s.state.SetLastBatchInfoSeenOnEthereum(s.ctx, latestSequencedBatchNumber, lastVerifiedBatchNumber, nil)
   212  			if err != nil {
   213  				log.Warn("error setting latest batch info into db. Error: ", err)
   214  				continue
   215  			}
   216  
   217  			// Sync trusted state
   218  			if latestSyncedBatch >= latestSequencedBatchNumber {
   219  				log.Info("L1 state fully synchronized")
   220  				err = s.syncTrustedState(latestSyncedBatch)
   221  				if err != nil {
   222  					log.Warn("error syncing trusted state. Error: ", err)
   223  					continue
   224  				}
   225  				waitDuration = s.cfg.SyncInterval.Duration
   226  			}
   227  			//Sync L1Blocks
   228  			if lastEthBlockSynced, err = s.syncBlocks(lastEthBlockSynced); err != nil {
   229  				log.Warn("error syncing blocks: ", err)
   230  				lastEthBlockSynced, err = s.state.GetLastBlock(s.ctx, nil)
   231  				if err != nil {
   232  					log.Fatal("error getting lastEthBlockSynced to resume the synchronization... Error: ", err)
   233  				}
   234  				if s.ctx.Err() != nil {
   235  					continue
   236  				}
   237  			}
   238  		}
   239  	}
   240  }
   241  
   242  // This function syncs the node from a specific block to the latest
   243  func (s *ClientSynchronizer) syncBlocks(lastEthBlockSynced *state.Block) (*state.Block, error) {
   244  	// This function will read events fromBlockNum to latestEthBlock. Check reorg to be sure that everything is ok.
   245  	block, err := s.checkReorg(lastEthBlockSynced)
   246  	if err != nil {
   247  		log.Errorf("error checking reorgs. Retrying... Err: %v", err)
   248  		return lastEthBlockSynced, fmt.Errorf("error checking reorgs")
   249  	}
   250  	if block != nil {
   251  		err = s.resetState(block.BlockNumber)
   252  		if err != nil {
   253  			log.Errorf("error resetting the state to a previous block. Retrying... Err: %v", err)
   254  			return lastEthBlockSynced, fmt.Errorf("error resetting the state to a previous block")
   255  		}
   256  		return block, nil
   257  	}
   258  
   259  	// Call the blockchain to retrieve data
   260  	header, err := s.etherMan.HeaderByNumber(s.ctx, nil)
   261  	if err != nil {
   262  		return lastEthBlockSynced, err
   263  	}
   264  	lastKnownBlock := header.Number
   265  
   266  	var fromBlock uint64
   267  	if lastEthBlockSynced.BlockNumber > 0 {
   268  		fromBlock = lastEthBlockSynced.BlockNumber + 1
   269  	}
   270  
   271  	for {
   272  		toBlock := fromBlock + s.cfg.SyncChunkSize
   273  		log.Infof("Syncing block %d of %d", fromBlock, lastKnownBlock.Uint64())
   274  		log.Infof("Getting rollup info from block %d to block %d", fromBlock, toBlock)
   275  		// This function returns the rollup information contained in the ethereum blocks and an extra param called order.
   276  		// Order param is a map that contains the event order to allow the synchronizer store the info in the same order that is readed.
   277  		// Name can be defferent in the order struct. For instance: Batches or Name:NewSequencers. This name is an identifier to check
   278  		// if the next info that must be stored in the db is a new sequencer or a batch. The value pos (position) tells what is the
   279  		// array index where this value is.
   280  		blocks, order, err := s.etherMan.GetRollupInfoByBlockRange(s.ctx, fromBlock, &toBlock)
   281  		if err != nil {
   282  			return lastEthBlockSynced, err
   283  		}
   284  		err = s.processBlockRange(blocks, order)
   285  		if err != nil {
   286  			return lastEthBlockSynced, err
   287  		}
   288  		if len(blocks) > 0 {
   289  			lastEthBlockSynced = &state.Block{
   290  				BlockNumber: blocks[len(blocks)-1].BlockNumber,
   291  				BlockHash:   blocks[len(blocks)-1].BlockHash,
   292  				ParentHash:  blocks[len(blocks)-1].ParentHash,
   293  				ReceivedAt:  blocks[len(blocks)-1].ReceivedAt,
   294  			}
   295  			for i := range blocks {
   296  				log.Debug("Position: ", i, ". BlockNumber: ", blocks[i].BlockNumber, ". BlockHash: ", blocks[i].BlockHash)
   297  			}
   298  		}
   299  		fromBlock = toBlock + 1
   300  
   301  		if lastKnownBlock.Cmp(new(big.Int).SetUint64(toBlock)) < 1 {
   302  			waitDuration = s.cfg.SyncInterval.Duration
   303  			break
   304  		}
   305  		if len(blocks) == 0 { // If there is no events in the checked blocks range and lastKnownBlock > fromBlock.
   306  			// Store the latest block of the block range. Get block info and process the block
   307  			fb, err := s.etherMan.EthBlockByNumber(s.ctx, toBlock)
   308  			if err != nil {
   309  				return lastEthBlockSynced, err
   310  			}
   311  			b := etherman.Block{
   312  				BlockNumber: fb.NumberU64(),
   313  				BlockHash:   fb.Hash(),
   314  				ParentHash:  fb.ParentHash(),
   315  				ReceivedAt:  time.Unix(int64(fb.Time()), 0),
   316  			}
   317  			err = s.processBlockRange([]etherman.Block{b}, order)
   318  			if err != nil {
   319  				return lastEthBlockSynced, err
   320  			}
   321  			block := state.Block{
   322  				BlockNumber: fb.NumberU64(),
   323  				BlockHash:   fb.Hash(),
   324  				ParentHash:  fb.ParentHash(),
   325  				ReceivedAt:  time.Unix(int64(fb.Time()), 0),
   326  			}
   327  			lastEthBlockSynced = &block
   328  			log.Debug("Storing empty block. BlockNumber: ", b.BlockNumber, ". BlockHash: ", b.BlockHash)
   329  		}
   330  	}
   331  
   332  	return lastEthBlockSynced, nil
   333  }
   334  
   335  // syncTrustedState synchronizes information from the trusted sequencer
   336  // related to the trusted state when the node has all the information from
   337  // l1 synchronized
   338  func (s *ClientSynchronizer) syncTrustedState(latestSyncedBatch uint64) error {
   339  	if s.isTrustedSequencer {
   340  		return nil
   341  	}
   342  
   343  	log.Info("Getting trusted state info")
   344  	lastTrustedStateBatchNumber, err := s.zkEVMClient.BatchNumber(s.ctx)
   345  	if err != nil {
   346  		log.Warn("error syncing trusted state. Error: ", err)
   347  		return err
   348  	}
   349  
   350  	log.Debug("lastTrustedStateBatchNumber ", lastTrustedStateBatchNumber)
   351  	log.Debug("latestSyncedBatch ", latestSyncedBatch)
   352  	if lastTrustedStateBatchNumber < latestSyncedBatch {
   353  		return nil
   354  	}
   355  
   356  	batchNumberToSync := latestSyncedBatch
   357  	for batchNumberToSync <= lastTrustedStateBatchNumber {
   358  		batchToSync, err := s.zkEVMClient.BatchByNumber(s.ctx, big.NewInt(0).SetUint64(batchNumberToSync))
   359  		if err != nil {
   360  			log.Warnf("failed to get batch %v from trusted state. Error: %v", batchNumberToSync, err)
   361  			return err
   362  		}
   363  
   364  		dbTx, err := s.state.BeginStateTransaction(s.ctx)
   365  		if err != nil {
   366  			log.Errorf("error creating db transaction to sync trusted batch %v: %v", batchNumberToSync, err)
   367  			return err
   368  		}
   369  
   370  		if err := s.processTrustedBatch(batchToSync, dbTx); err != nil {
   371  			log.Errorf("error processing trusted batch %v: %v", batchNumberToSync, err)
   372  			err := dbTx.Rollback(s.ctx)
   373  			if err != nil {
   374  				log.Errorf("error rolling back db transaction to sync trusted batch %v: %v", batchNumberToSync, err)
   375  				return err
   376  			}
   377  			break
   378  		}
   379  
   380  		if err := dbTx.Commit(s.ctx); err != nil {
   381  			log.Errorf("error committing db transaction to sync trusted batch %v: %v", batchNumberToSync, err)
   382  			return err
   383  		}
   384  
   385  		batchNumberToSync++
   386  	}
   387  
   388  	log.Info("Trusted state fully synchronized")
   389  	return nil
   390  }
   391  
   392  func (s *ClientSynchronizer) processBlockRange(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error {
   393  	// New info has to be included into the db using the state
   394  	for i := range blocks {
   395  		// Begin db transaction
   396  		dbTx, err := s.state.BeginStateTransaction(s.ctx)
   397  		if err != nil {
   398  			log.Errorf("error creating db transaction to store block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
   399  			return err
   400  		}
   401  		b := state.Block{
   402  			BlockNumber: blocks[i].BlockNumber,
   403  			BlockHash:   blocks[i].BlockHash,
   404  			ParentHash:  blocks[i].ParentHash,
   405  			ReceivedAt:  blocks[i].ReceivedAt,
   406  		}
   407  		// Add block information
   408  		err = s.state.AddBlock(s.ctx, &b, dbTx)
   409  		if err != nil {
   410  			log.Errorf("error storing block. BlockNumber: %d, error: %v", blocks[i].BlockNumber, err)
   411  			rollbackErr := dbTx.Rollback(s.ctx)
   412  			if rollbackErr != nil {
   413  				log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
   414  				return rollbackErr
   415  			}
   416  			return err
   417  		}
   418  		for _, element := range order[blocks[i].BlockHash] {
   419  			switch element.Name {
   420  			case etherman.SequenceBatchesOrder:
   421  				err = s.processSequenceBatches(blocks[i].SequencedBatches[element.Pos], blocks[i].BlockNumber, dbTx)
   422  				if err != nil {
   423  					return err
   424  				}
   425  			case etherman.ForcedBatchesOrder:
   426  				err = s.processForcedBatch(blocks[i].ForcedBatches[element.Pos], dbTx)
   427  				if err != nil {
   428  					return err
   429  				}
   430  			case etherman.GlobalExitRootsOrder:
   431  				err = s.processGlobalExitRoot(blocks[i].GlobalExitRoots[element.Pos], dbTx)
   432  				if err != nil {
   433  					return err
   434  				}
   435  			case etherman.SequenceForceBatchesOrder:
   436  				err = s.processSequenceForceBatch(blocks[i].SequencedForceBatches[element.Pos], blocks[i], dbTx)
   437  				if err != nil {
   438  					return err
   439  				}
   440  			case etherman.TrustedVerifyBatchOrder:
   441  				err = s.processTrustedVerifyBatches(blocks[i].VerifiedBatches[element.Pos], dbTx)
   442  				if err != nil {
   443  					return err
   444  				}
   445  			case etherman.ForkIDsOrder:
   446  				err = s.processForkID(blocks[i].ForkIDs[element.Pos], blocks[i].BlockNumber, dbTx)
   447  				if err != nil {
   448  					return err
   449  				}
   450  			}
   451  		}
   452  		err = dbTx.Commit(s.ctx)
   453  		if err != nil {
   454  			log.Errorf("error committing state to store block. BlockNumber: %d, err: %v", blocks[i].BlockNumber, err)
   455  			rollbackErr := dbTx.Rollback(s.ctx)
   456  			if rollbackErr != nil {
   457  				log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blocks[i].BlockNumber, rollbackErr.Error(), err)
   458  				return rollbackErr
   459  			}
   460  			return err
   461  		}
   462  	}
   463  	return nil
   464  }
   465  
   466  // This function allows reset the state until an specific ethereum block
   467  func (s *ClientSynchronizer) resetState(blockNumber uint64) error {
   468  	log.Debug("Reverting synchronization to block: ", blockNumber)
   469  	dbTx, err := s.state.BeginStateTransaction(s.ctx)
   470  	if err != nil {
   471  		log.Error("error starting a db transaction to reset the state. Error: ", err)
   472  		return err
   473  	}
   474  	err = s.state.Reset(s.ctx, blockNumber, dbTx)
   475  	if err != nil {
   476  		rollbackErr := dbTx.Rollback(s.ctx)
   477  		if rollbackErr != nil {
   478  			log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   479  			return rollbackErr
   480  		}
   481  		log.Error("error resetting the state. Error: ", err)
   482  		return err
   483  	}
   484  	err = s.ethTxManager.Reorg(s.ctx, blockNumber+1, dbTx)
   485  	if err != nil {
   486  		rollbackErr := dbTx.Rollback(s.ctx)
   487  		if rollbackErr != nil {
   488  			log.Errorf("error rolling back eth tx manager when reorg detected. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   489  			return rollbackErr
   490  		}
   491  		log.Error("error processing reorg on eth tx manager. Error: ", err)
   492  		return err
   493  	}
   494  	err = dbTx.Commit(s.ctx)
   495  	if err != nil {
   496  		rollbackErr := dbTx.Rollback(s.ctx)
   497  		if rollbackErr != nil {
   498  			log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   499  			return rollbackErr
   500  		}
   501  		log.Error("error committing the resetted state. Error: ", err)
   502  		return err
   503  	}
   504  
   505  	return nil
   506  }
   507  
   508  /*
   509  This function will check if there is a reorg.
   510  As input param needs the last ethereum block synced. Retrieve the block info from the blockchain
   511  to compare it with the stored info. If hash and hash parent matches, then no reorg is detected and return a nil.
   512  If hash or hash parent don't match, reorg detected and the function will return the block until the sync process
   513  must be reverted. Then, check the previous ethereum block synced, get block info from the blockchain and check
   514  hash and has parent. This operation has to be done until a match is found.
   515  */
   516  func (s *ClientSynchronizer) checkReorg(latestBlock *state.Block) (*state.Block, error) {
   517  	// This function only needs to worry about reorgs if some of the reorganized blocks contained rollup info.
   518  	latestEthBlockSynced := *latestBlock
   519  	var depth uint64
   520  	for {
   521  		block, err := s.etherMan.EthBlockByNumber(s.ctx, latestBlock.BlockNumber)
   522  		if err != nil {
   523  			log.Errorf("error getting latest block synced from blockchain. Block: %d, error: %v", latestBlock.BlockNumber, err)
   524  			return nil, err
   525  		}
   526  		if block.NumberU64() != latestBlock.BlockNumber {
   527  			err = fmt.Errorf("wrong ethereum block retrieved from blockchain. Block numbers don't match. BlockNumber stored: %d. BlockNumber retrieved: %d",
   528  				latestBlock.BlockNumber, block.NumberU64())
   529  			log.Error("error: ", err)
   530  			return nil, err
   531  		}
   532  		// Compare hashes
   533  		if (block.Hash() != latestBlock.BlockHash || block.ParentHash() != latestBlock.ParentHash) && latestBlock.BlockNumber > s.genesis.GenesisBlockNum {
   534  			log.Debug("[checkReorg function] => latestBlockNumber: ", latestBlock.BlockNumber)
   535  			log.Debug("[checkReorg function] => latestBlockHash: ", latestBlock.BlockHash)
   536  			log.Debug("[checkReorg function] => latestBlockHashParent: ", latestBlock.ParentHash)
   537  			log.Debug("[checkReorg function] => BlockNumber: ", latestBlock.BlockNumber, block.NumberU64())
   538  			log.Debug("[checkReorg function] => BlockHash: ", block.Hash())
   539  			log.Debug("[checkReorg function] => BlockHashParent: ", block.ParentHash())
   540  			depth++
   541  			log.Debug("REORG: Looking for the latest correct ethereum block. Depth: ", depth)
   542  			// Reorg detected. Getting previous block
   543  			dbTx, err := s.state.BeginStateTransaction(s.ctx)
   544  			if err != nil {
   545  				log.Errorf("error creating db transaction to get prevoius blocks")
   546  				return nil, err
   547  			}
   548  			latestBlock, err = s.state.GetPreviousBlock(s.ctx, depth, dbTx)
   549  			errC := dbTx.Commit(s.ctx)
   550  			if errC != nil {
   551  				log.Errorf("error committing dbTx, err: %v", errC)
   552  				rollbackErr := dbTx.Rollback(s.ctx)
   553  				if rollbackErr != nil {
   554  					log.Errorf("error rolling back state. RollbackErr: %v", rollbackErr)
   555  					return nil, rollbackErr
   556  				}
   557  				log.Errorf("error committing dbTx, err: %v", errC)
   558  				return nil, errC
   559  			}
   560  			if errors.Is(err, state.ErrNotFound) {
   561  				log.Warn("error checking reorg: previous block not found in db: ", err)
   562  				return &state.Block{}, nil
   563  			} else if err != nil {
   564  				return nil, err
   565  			}
   566  		} else {
   567  			break
   568  		}
   569  	}
   570  	if latestEthBlockSynced.BlockHash != latestBlock.BlockHash {
   571  		log.Debug("Reorg detected in block: ", latestEthBlockSynced.BlockNumber)
   572  		return latestBlock, nil
   573  	}
   574  	return nil, nil
   575  }
   576  
   577  // Stop function stops the synchronizer
   578  func (s *ClientSynchronizer) Stop() {
   579  	s.cancelCtx()
   580  }
   581  
   582  func (s *ClientSynchronizer) checkTrustedState(batch state.Batch, tBatch *state.Batch, newRoot common.Hash, dbTx pgx.Tx) bool {
   583  	//Compare virtual state with trusted state
   584  	var reorgReasons strings.Builder
   585  	if newRoot != tBatch.StateRoot {
   586  		log.Warnf("Different field StateRoot. Virtual: %s, Trusted: %s\n", newRoot.String(), tBatch.StateRoot.String())
   587  		reorgReasons.WriteString(fmt.Sprintf("Different field StateRoot. Virtual: %s, Trusted: %s\n", newRoot.String(), tBatch.StateRoot.String()))
   588  	}
   589  	if hex.EncodeToString(batch.BatchL2Data) != hex.EncodeToString(tBatch.BatchL2Data) {
   590  		log.Warnf("Different field BatchL2Data. Virtual: %s, Trusted: %s\n", hex.EncodeToString(batch.BatchL2Data), hex.EncodeToString(tBatch.BatchL2Data))
   591  		reorgReasons.WriteString(fmt.Sprintf("Different field BatchL2Data. Virtual: %s, Trusted: %s\n", hex.EncodeToString(batch.BatchL2Data), hex.EncodeToString(tBatch.BatchL2Data)))
   592  	}
   593  	if batch.GlobalExitRoot.String() != tBatch.GlobalExitRoot.String() {
   594  		log.Warnf("Different field GlobalExitRoot. Virtual: %s, Trusted: %s\n", batch.GlobalExitRoot.String(), tBatch.GlobalExitRoot.String())
   595  		reorgReasons.WriteString(fmt.Sprintf("Different field GlobalExitRoot. Virtual: %s, Trusted: %s\n", batch.GlobalExitRoot.String(), tBatch.GlobalExitRoot.String()))
   596  	}
   597  	if batch.Timestamp.Unix() != tBatch.Timestamp.Unix() {
   598  		log.Warnf("Different field Timestamp. Virtual: %d, Trusted: %d\n", batch.Timestamp.Unix(), tBatch.Timestamp.Unix())
   599  		reorgReasons.WriteString(fmt.Sprintf("Different field Timestamp. Virtual: %d, Trusted: %d\n", batch.Timestamp.Unix(), tBatch.Timestamp.Unix()))
   600  	}
   601  	if batch.Coinbase.String() != tBatch.Coinbase.String() {
   602  		log.Warnf("Different field Coinbase. Virtual: %s, Trusted: %s\n", batch.Coinbase.String(), tBatch.Coinbase.String())
   603  		reorgReasons.WriteString(fmt.Sprintf("Different field Coinbase. Virtual: %s, Trusted: %s\n", batch.Coinbase.String(), tBatch.Coinbase.String()))
   604  	}
   605  
   606  	if reorgReasons.Len() > 0 {
   607  		reason := reorgReasons.String()
   608  		log.Warnf("Trusted Reorg detected for Batch Number: %d. Reasons: %s", tBatch.BatchNumber, reason)
   609  		if s.isTrustedSequencer {
   610  			for {
   611  				log.Error("TRUSTED REORG DETECTED! Batch: ", batch.BatchNumber)
   612  				time.Sleep(5 * time.Second) //nolint:gomnd
   613  			}
   614  		}
   615  		// Store trusted reorg register
   616  		tr := state.TrustedReorg{
   617  			BatchNumber: tBatch.BatchNumber,
   618  			Reason:      reason,
   619  		}
   620  		err := s.state.AddTrustedReorg(s.ctx, &tr, dbTx)
   621  		if err != nil {
   622  			log.Error("error storing tursted reorg register into the db. Error: ", err)
   623  		}
   624  		return true
   625  	}
   626  	return false
   627  }
   628  
   629  func (s *ClientSynchronizer) processForkID(forkID etherman.ForkID, blockNumber uint64, dbTx pgx.Tx) error {
   630  	//If the forkID.batchnumber is a future batch
   631  	latestBatchNumber, err := s.state.GetLastBatchNumber(s.ctx, dbTx)
   632  	if err != nil {
   633  		log.Error("error getting last batch number. Error: ", err)
   634  		rollbackErr := dbTx.Rollback(s.ctx)
   635  		if rollbackErr != nil {
   636  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   637  			return rollbackErr
   638  		}
   639  		return err
   640  	}
   641  	if latestBatchNumber < forkID.BatchNumber { //If the forkID will start in a future batch
   642  		// Read Fork ID FROM POE SC
   643  		forkIDIntervals, err := s.etherMan.GetForks(s.ctx, s.genesis.GenesisBlockNum)
   644  		if err != nil || len(forkIDIntervals) == 0 {
   645  			log.Error("error getting all forkIDs: ", err)
   646  			rollbackErr := dbTx.Rollback(s.ctx)
   647  			if rollbackErr != nil {
   648  				log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   649  				return rollbackErr
   650  			}
   651  			return err
   652  		}
   653  		// Update forkID intervals in the state
   654  		s.state.UpdateForkIDIntervals(forkIDIntervals)
   655  		return nil
   656  	}
   657  
   658  	// If forkID affects to a batch from the past. State must be reseted.
   659  	log.Debugf("ForkID: %d, Reverting synchronization to batch: %d", forkID.ForkID, forkID.BatchNumber+1)
   660  	count, err := s.state.GetForkIDTrustedReorgCount(s.ctx, forkID.ForkID, forkID.Version, dbTx)
   661  	if err != nil {
   662  		log.Error("error getting ForkIDTrustedReorg. Error: ", err)
   663  		rollbackErr := dbTx.Rollback(s.ctx)
   664  		if rollbackErr != nil {
   665  			log.Errorf("error rolling back state get forkID trusted state. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   666  			return rollbackErr
   667  		}
   668  		return err
   669  	}
   670  	if count > 0 { // If the forkID reset was already done
   671  		return nil
   672  	}
   673  
   674  	// Read Fork ID FROM POE SC
   675  	forkIDIntervals, err := s.etherMan.GetForks(s.ctx, s.genesis.GenesisBlockNum)
   676  	if err != nil || len(forkIDIntervals) == 0 {
   677  		log.Error("error getting all forkIDs: ", err)
   678  		rollbackErr := dbTx.Rollback(s.ctx)
   679  		if rollbackErr != nil {
   680  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   681  			return rollbackErr
   682  		}
   683  		return err
   684  	}
   685  
   686  	//Reset DB
   687  	err = s.state.ResetForkID(s.ctx, forkID.BatchNumber+1, forkID.ForkID, forkID.Version, dbTx)
   688  	if err != nil {
   689  		log.Error("error resetting the state. Error: ", err)
   690  		rollbackErr := dbTx.Rollback(s.ctx)
   691  		if rollbackErr != nil {
   692  			log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   693  			return rollbackErr
   694  		}
   695  		return err
   696  	}
   697  	err = dbTx.Commit(s.ctx)
   698  	if err != nil {
   699  		log.Error("error committing the resetted state. Error: ", err)
   700  		rollbackErr := dbTx.Rollback(s.ctx)
   701  		if rollbackErr != nil {
   702  			log.Errorf("error rolling back state to store block. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   703  			return rollbackErr
   704  		}
   705  		return err
   706  	}
   707  
   708  	// Update forkID intervals in the state
   709  	s.state.UpdateForkIDIntervals(forkIDIntervals)
   710  
   711  	return fmt.Errorf("new ForkID detected, reseting synchronizarion")
   712  }
   713  
   714  func (s *ClientSynchronizer) processSequenceBatches(sequencedBatches []etherman.SequencedBatch, blockNumber uint64, dbTx pgx.Tx) error {
   715  	if len(sequencedBatches) == 0 {
   716  		log.Warn("Empty sequencedBatches array detected, ignoring...")
   717  		return nil
   718  	}
   719  	for _, sbatch := range sequencedBatches {
   720  		batchL2Data, err := s.getBatchL2Data(sbatch.BatchNumber, sbatch.TransactionsHash)
   721  		if err != nil {
   722  			return err
   723  		}
   724  		virtualBatch := state.VirtualBatch{
   725  			BatchNumber:   sbatch.BatchNumber,
   726  			TxHash:        sbatch.TxHash,
   727  			Coinbase:      sbatch.Coinbase,
   728  			BlockNumber:   blockNumber,
   729  			SequencerAddr: sbatch.SequencerAddr,
   730  		}
   731  		batch := state.Batch{
   732  			BatchNumber:    sbatch.BatchNumber,
   733  			GlobalExitRoot: sbatch.GlobalExitRoot,
   734  			Timestamp:      time.Unix(int64(sbatch.Timestamp), 0),
   735  			Coinbase:       sbatch.Coinbase,
   736  			BatchL2Data:    batchL2Data,
   737  		}
   738  		// ForcedBatch must be processed
   739  		if sbatch.MinForcedTimestamp > 0 { // If this is true means that the batch is forced
   740  			log.Debug("FORCED BATCH SEQUENCED!")
   741  			// Read forcedBatches from db
   742  			forcedBatches, err := s.state.GetNextForcedBatches(s.ctx, 1, dbTx)
   743  			if err != nil {
   744  				log.Errorf("error getting forcedBatches. BatchNumber: %d", virtualBatch.BatchNumber)
   745  				rollbackErr := dbTx.Rollback(s.ctx)
   746  				if rollbackErr != nil {
   747  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", virtualBatch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   748  					return rollbackErr
   749  				}
   750  				return err
   751  			}
   752  			if len(forcedBatches) == 0 {
   753  				log.Errorf("error: empty forcedBatches array read from db. BatchNumber: %d", sbatch.BatchNumber)
   754  				rollbackErr := dbTx.Rollback(s.ctx)
   755  				if rollbackErr != nil {
   756  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %v", sbatch.BatchNumber, blockNumber, rollbackErr)
   757  					return rollbackErr
   758  				}
   759  				return fmt.Errorf("error: empty forcedBatches array read from db. BatchNumber: %d", sbatch.BatchNumber)
   760  			}
   761  			if uint64(forcedBatches[0].ForcedAt.Unix()) != sbatch.MinForcedTimestamp ||
   762  				forcedBatches[0].GlobalExitRoot != sbatch.GlobalExitRoot ||
   763  				common.Bytes2Hex(forcedBatches[0].RawTxsData) != common.Bytes2Hex(batchL2Data) {
   764  				log.Warnf("ForcedBatch stored: %+v", forcedBatches)
   765  				log.Warnf("ForcedBatch sequenced received: %+v", sbatch)
   766  				log.Errorf("error: forcedBatch received doesn't match with the next expected forcedBatch stored in db. Expected: %+v, Synced: %+v", forcedBatches, sbatch)
   767  				rollbackErr := dbTx.Rollback(s.ctx)
   768  				if rollbackErr != nil {
   769  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %v", virtualBatch.BatchNumber, blockNumber, rollbackErr)
   770  					return rollbackErr
   771  				}
   772  				return fmt.Errorf("error: forcedBatch received doesn't match with the next expected forcedBatch stored in db. Expected: %+v, Synced: %+v", forcedBatches, sbatch)
   773  			}
   774  			batch.ForcedBatchNum = &forcedBatches[0].ForcedBatchNumber
   775  		}
   776  
   777  		// Now we need to check the batch. ForcedBatches should be already stored in the batch table because this is done by the sequencer
   778  		processCtx := state.ProcessingContext{
   779  			BatchNumber:    batch.BatchNumber,
   780  			Coinbase:       batch.Coinbase,
   781  			Timestamp:      batch.Timestamp,
   782  			GlobalExitRoot: batch.GlobalExitRoot,
   783  			ForcedBatchNum: batch.ForcedBatchNum,
   784  		}
   785  
   786  		var newRoot common.Hash
   787  
   788  		// First get trusted batch from db
   789  		tBatch, err := s.state.GetBatchByNumber(s.ctx, batch.BatchNumber, dbTx)
   790  		if err != nil {
   791  			if errors.Is(err, state.ErrNotFound) || errors.Is(err, state.ErrStateNotSynchronized) {
   792  				log.Debugf("BatchNumber: %d, not found in trusted state. Storing it...", batch.BatchNumber)
   793  				// If it is not found, store batch
   794  				newStateRoot, err := s.state.ProcessAndStoreClosedBatch(s.ctx, processCtx, batch.BatchL2Data, dbTx, metrics.SynchronizerCallerLabel)
   795  				if err != nil {
   796  					log.Errorf("error storing trustedBatch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   797  					rollbackErr := dbTx.Rollback(s.ctx)
   798  					if rollbackErr != nil {
   799  						log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", batch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   800  						return rollbackErr
   801  					}
   802  					log.Errorf("error storing batch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   803  					return err
   804  				}
   805  				newRoot = newStateRoot
   806  				tBatch = &batch
   807  				tBatch.StateRoot = newRoot
   808  			} else {
   809  				log.Error("error checking trusted state: ", err)
   810  				rollbackErr := dbTx.Rollback(s.ctx)
   811  				if rollbackErr != nil {
   812  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %v", batch.BatchNumber, blockNumber, rollbackErr)
   813  					return rollbackErr
   814  				}
   815  				return err
   816  			}
   817  		} else {
   818  			// Reprocess batch to compare the stateRoot with tBatch.StateRoot and get accInputHash
   819  			p, err := s.state.ExecuteBatch(s.ctx, batch, false, dbTx)
   820  			if err != nil {
   821  				log.Errorf("error executing L1 batch: %+v, error: %v", batch, err)
   822  				rollbackErr := dbTx.Rollback(s.ctx)
   823  				if rollbackErr != nil {
   824  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", batch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   825  					return rollbackErr
   826  				}
   827  				return err
   828  			}
   829  			newRoot = common.BytesToHash(p.NewStateRoot)
   830  			accumulatedInputHash := common.BytesToHash(p.NewAccInputHash)
   831  
   832  			//AddAccumulatedInputHash
   833  			err = s.state.AddAccumulatedInputHash(s.ctx, batch.BatchNumber, accumulatedInputHash, dbTx)
   834  			if err != nil {
   835  				log.Errorf("error adding accumulatedInputHash for batch: %d. Error; %v", batch.BatchNumber, err)
   836  				rollbackErr := dbTx.Rollback(s.ctx)
   837  				if rollbackErr != nil {
   838  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %v", batch.BatchNumber, blockNumber, rollbackErr)
   839  					return rollbackErr
   840  				}
   841  				return err
   842  			}
   843  		}
   844  
   845  		// Call the check trusted state method to compare trusted and virtual state
   846  		status := s.checkTrustedState(batch, tBatch, newRoot, dbTx)
   847  		if status {
   848  			// Reorg Pool
   849  			err := s.reorgPool(dbTx)
   850  			if err != nil {
   851  				rollbackErr := dbTx.Rollback(s.ctx)
   852  				if rollbackErr != nil {
   853  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", tBatch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   854  					return rollbackErr
   855  				}
   856  				log.Errorf("error: %v. BatchNumber: %d, BlockNumber: %d", err, tBatch.BatchNumber, blockNumber)
   857  				return err
   858  			}
   859  
   860  			// Reset trusted state
   861  			previousBatchNumber := batch.BatchNumber - 1
   862  			log.Warnf("Trusted reorg detected, discarding batches until batchNum %d", previousBatchNumber)
   863  			err = s.state.ResetTrustedState(s.ctx, previousBatchNumber, dbTx) // This method has to reset the forced batches deleting the batchNumber for higher batchNumbers
   864  			if err != nil {
   865  				log.Errorf("error resetting trusted state. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   866  				rollbackErr := dbTx.Rollback(s.ctx)
   867  				if rollbackErr != nil {
   868  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", batch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   869  					return rollbackErr
   870  				}
   871  				log.Errorf("error resetting trusted state. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   872  				return err
   873  			}
   874  			_, err = s.state.ProcessAndStoreClosedBatch(s.ctx, processCtx, batch.BatchL2Data, dbTx, metrics.SynchronizerCallerLabel)
   875  			if err != nil {
   876  				log.Errorf("error storing trustedBatch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   877  				rollbackErr := dbTx.Rollback(s.ctx)
   878  				if rollbackErr != nil {
   879  					log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", batch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   880  					return rollbackErr
   881  				}
   882  				log.Errorf("error storing batch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, blockNumber, err)
   883  				return err
   884  			}
   885  		}
   886  
   887  		// Store virtualBatch
   888  		err = s.state.AddVirtualBatch(s.ctx, &virtualBatch, dbTx)
   889  		if err != nil {
   890  			log.Errorf("error storing virtualBatch. BatchNumber: %d, BlockNumber: %d, error: %v", virtualBatch.BatchNumber, blockNumber, err)
   891  			rollbackErr := dbTx.Rollback(s.ctx)
   892  			if rollbackErr != nil {
   893  				log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", virtualBatch.BatchNumber, blockNumber, rollbackErr.Error(), err)
   894  				return rollbackErr
   895  			}
   896  			log.Errorf("error storing virtualBatch. BatchNumber: %d, BlockNumber: %d, error: %v", virtualBatch.BatchNumber, blockNumber, err)
   897  			return err
   898  		}
   899  	}
   900  	// Insert the sequence to allow the aggregator verify the sequence batches
   901  	seq := state.Sequence{
   902  		FromBatchNumber: sequencedBatches[0].BatchNumber,
   903  		ToBatchNumber:   sequencedBatches[len(sequencedBatches)-1].BatchNumber,
   904  	}
   905  	err := s.state.AddSequence(s.ctx, seq, dbTx)
   906  	if err != nil {
   907  		log.Errorf("error adding sequence. Sequence: %+v", seq)
   908  		rollbackErr := dbTx.Rollback(s.ctx)
   909  		if rollbackErr != nil {
   910  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", blockNumber, rollbackErr.Error(), err)
   911  			return rollbackErr
   912  		}
   913  		log.Errorf("error getting adding sequence. BlockNumber: %d, error: %v", blockNumber, err)
   914  		return err
   915  	}
   916  	return nil
   917  }
   918  
   919  func (s *ClientSynchronizer) processSequenceForceBatch(sequenceForceBatch []etherman.SequencedForceBatch, block etherman.Block, dbTx pgx.Tx) error {
   920  	if len(sequenceForceBatch) == 0 {
   921  		log.Warn("Empty sequenceForceBatch array detected, ignoring...")
   922  		return nil
   923  	}
   924  	// First, get last virtual batch number
   925  	lastVirtualizedBatchNumber, err := s.state.GetLastVirtualBatchNum(s.ctx, dbTx)
   926  	if err != nil {
   927  		log.Errorf("error getting lastVirtualBatchNumber. BlockNumber: %d, error: %v", block.BlockNumber, err)
   928  		rollbackErr := dbTx.Rollback(s.ctx)
   929  		if rollbackErr != nil {
   930  			log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", lastVirtualizedBatchNumber, block.BlockNumber, rollbackErr.Error(), err)
   931  			return rollbackErr
   932  		}
   933  		log.Errorf("error getting lastVirtualBatchNumber. BlockNumber: %d, error: %v", block.BlockNumber, err)
   934  		return err
   935  	}
   936  	// Second, reset trusted state
   937  	err = s.state.ResetTrustedState(s.ctx, lastVirtualizedBatchNumber, dbTx) // This method has to reset the forced batches deleting the batchNumber for higher batchNumbers
   938  	if err != nil {
   939  		log.Errorf("error resetting trusted state. BatchNumber: %d, BlockNumber: %d, error: %v", lastVirtualizedBatchNumber, block.BlockNumber, err)
   940  		rollbackErr := dbTx.Rollback(s.ctx)
   941  		if rollbackErr != nil {
   942  			log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", lastVirtualizedBatchNumber, block.BlockNumber, rollbackErr.Error(), err)
   943  			return rollbackErr
   944  		}
   945  		log.Errorf("error resetting trusted state. BatchNumber: %d, BlockNumber: %d, error: %v", lastVirtualizedBatchNumber, block.BlockNumber, err)
   946  		return err
   947  	}
   948  	// Read forcedBatches from db
   949  	forcedBatches, err := s.state.GetNextForcedBatches(s.ctx, len(sequenceForceBatch), dbTx)
   950  	if err != nil {
   951  		log.Errorf("error getting forcedBatches in processSequenceForceBatch. BlockNumber: %d", block.BlockNumber)
   952  		rollbackErr := dbTx.Rollback(s.ctx)
   953  		if rollbackErr != nil {
   954  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", block.BlockNumber, rollbackErr.Error(), err)
   955  			return rollbackErr
   956  		}
   957  		log.Errorf("error getting forcedBatches in processSequenceForceBatch. BlockNumber: %d, error: %v", block.BlockNumber, err)
   958  		return err
   959  	}
   960  	if len(sequenceForceBatch) != len(forcedBatches) {
   961  		rollbackErr := dbTx.Rollback(s.ctx)
   962  		if rollbackErr != nil {
   963  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %v", block.BlockNumber, rollbackErr)
   964  			return rollbackErr
   965  		}
   966  		log.Error("error number of forced batches doesn't match")
   967  		return fmt.Errorf("error number of forced batches doesn't match")
   968  	}
   969  	for i, fbatch := range sequenceForceBatch {
   970  		if uint64(forcedBatches[i].ForcedAt.Unix()) != fbatch.MinForcedTimestamp ||
   971  			forcedBatches[i].GlobalExitRoot != fbatch.GlobalExitRoot ||
   972  			common.Bytes2Hex(forcedBatches[i].RawTxsData) != common.Bytes2Hex(fbatch.Transactions) {
   973  			log.Warnf("ForcedBatch stored: %+v", forcedBatches)
   974  			log.Warnf("ForcedBatch sequenced received: %+v", fbatch)
   975  			log.Errorf("error: forcedBatch received doesn't match with the next expected forcedBatch stored in db. Expected: %+v, Synced: %+v", forcedBatches[i], fbatch)
   976  			rollbackErr := dbTx.Rollback(s.ctx)
   977  			if rollbackErr != nil {
   978  				log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %v", fbatch.BatchNumber, block.BlockNumber, rollbackErr)
   979  				return rollbackErr
   980  			}
   981  			return fmt.Errorf("error: forcedBatch received doesn't match with the next expected forcedBatch stored in db. Expected: %+v, Synced: %+v", forcedBatches[i], fbatch)
   982  		}
   983  		virtualBatch := state.VirtualBatch{
   984  			BatchNumber:   fbatch.BatchNumber,
   985  			TxHash:        fbatch.TxHash,
   986  			Coinbase:      fbatch.Coinbase,
   987  			SequencerAddr: fbatch.Coinbase,
   988  			BlockNumber:   block.BlockNumber,
   989  		}
   990  		batch := state.ProcessingContext{
   991  			BatchNumber:    fbatch.BatchNumber,
   992  			GlobalExitRoot: fbatch.GlobalExitRoot,
   993  			Timestamp:      block.ReceivedAt,
   994  			Coinbase:       fbatch.Coinbase,
   995  			ForcedBatchNum: &forcedBatches[i].ForcedBatchNumber,
   996  		}
   997  		// Process batch
   998  		_, err := s.state.ProcessAndStoreClosedBatch(s.ctx, batch, forcedBatches[i].RawTxsData, dbTx, metrics.SynchronizerCallerLabel)
   999  		if err != nil {
  1000  			log.Errorf("error processing batch in processSequenceForceBatch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, block.BlockNumber, err)
  1001  			rollbackErr := dbTx.Rollback(s.ctx)
  1002  			if rollbackErr != nil {
  1003  				log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", batch.BatchNumber, block.BlockNumber, rollbackErr.Error(), err)
  1004  				return rollbackErr
  1005  			}
  1006  			log.Errorf("error processing batch in processSequenceForceBatch. BatchNumber: %d, BlockNumber: %d, error: %v", batch.BatchNumber, block.BlockNumber, err)
  1007  			return err
  1008  		}
  1009  		// Store virtualBatch
  1010  		err = s.state.AddVirtualBatch(s.ctx, &virtualBatch, dbTx)
  1011  		if err != nil {
  1012  			log.Errorf("error storing virtualBatch in processSequenceForceBatch. BatchNumber: %d, BlockNumber: %d, error: %v", virtualBatch.BatchNumber, block.BlockNumber, err)
  1013  			rollbackErr := dbTx.Rollback(s.ctx)
  1014  			if rollbackErr != nil {
  1015  				log.Errorf("error rolling back state. BatchNumber: %d, BlockNumber: %d, rollbackErr: %s, error : %v", virtualBatch.BatchNumber, block.BlockNumber, rollbackErr.Error(), err)
  1016  				return rollbackErr
  1017  			}
  1018  			log.Errorf("error storing virtualBatch in processSequenceForceBatch. BatchNumber: %d, BlockNumber: %d, error: %v", virtualBatch.BatchNumber, block.BlockNumber, err)
  1019  			return err
  1020  		}
  1021  	}
  1022  	// Insert the sequence to allow the aggregator verify the sequence batches
  1023  	seq := state.Sequence{
  1024  		FromBatchNumber: sequenceForceBatch[0].BatchNumber,
  1025  		ToBatchNumber:   sequenceForceBatch[len(sequenceForceBatch)-1].BatchNumber,
  1026  	}
  1027  	err = s.state.AddSequence(s.ctx, seq, dbTx)
  1028  	if err != nil {
  1029  		log.Errorf("error adding sequence. Sequence: %+v", seq)
  1030  		rollbackErr := dbTx.Rollback(s.ctx)
  1031  		if rollbackErr != nil {
  1032  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", block.BlockNumber, rollbackErr.Error(), err)
  1033  			return rollbackErr
  1034  		}
  1035  		log.Errorf("error getting adding sequence. BlockNumber: %d, error: %v", block.BlockNumber, err)
  1036  		return err
  1037  	}
  1038  	return nil
  1039  }
  1040  
  1041  func (s *ClientSynchronizer) processForcedBatch(forcedBatch etherman.ForcedBatch, dbTx pgx.Tx) error {
  1042  	// Store forced batch into the db
  1043  	forcedB := state.ForcedBatch{
  1044  		BlockNumber:       forcedBatch.BlockNumber,
  1045  		ForcedBatchNumber: forcedBatch.ForcedBatchNumber,
  1046  		Sequencer:         forcedBatch.Sequencer,
  1047  		GlobalExitRoot:    forcedBatch.GlobalExitRoot,
  1048  		RawTxsData:        forcedBatch.RawTxsData,
  1049  		ForcedAt:          forcedBatch.ForcedAt,
  1050  	}
  1051  	err := s.state.AddForcedBatch(s.ctx, &forcedB, dbTx)
  1052  	if err != nil {
  1053  		log.Errorf("error storing the forcedBatch in processForcedBatch. BlockNumber: %d", forcedBatch.BlockNumber)
  1054  		rollbackErr := dbTx.Rollback(s.ctx)
  1055  		if rollbackErr != nil {
  1056  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", forcedBatch.BlockNumber, rollbackErr.Error(), err)
  1057  			return rollbackErr
  1058  		}
  1059  		log.Errorf("error storing the forcedBatch in processForcedBatch. BlockNumber: %d, error: %v", forcedBatch.BlockNumber, err)
  1060  		return err
  1061  	}
  1062  	return nil
  1063  }
  1064  
  1065  func (s *ClientSynchronizer) processGlobalExitRoot(globalExitRoot etherman.GlobalExitRoot, dbTx pgx.Tx) error {
  1066  	// Store GlobalExitRoot
  1067  	ger := state.GlobalExitRoot{
  1068  		BlockNumber:     globalExitRoot.BlockNumber,
  1069  		MainnetExitRoot: globalExitRoot.MainnetExitRoot,
  1070  		RollupExitRoot:  globalExitRoot.RollupExitRoot,
  1071  		GlobalExitRoot:  globalExitRoot.GlobalExitRoot,
  1072  	}
  1073  	err := s.state.AddGlobalExitRoot(s.ctx, &ger, dbTx)
  1074  	if err != nil {
  1075  		log.Errorf("error storing the globalExitRoot in processGlobalExitRoot. BlockNumber: %d", globalExitRoot.BlockNumber)
  1076  		rollbackErr := dbTx.Rollback(s.ctx)
  1077  		if rollbackErr != nil {
  1078  			log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", globalExitRoot.BlockNumber, rollbackErr.Error(), err)
  1079  			return rollbackErr
  1080  		}
  1081  		log.Errorf("error storing the GlobalExitRoot in processGlobalExitRoot. BlockNumber: %d, error: %v", globalExitRoot.BlockNumber, err)
  1082  		return err
  1083  	}
  1084  	return nil
  1085  }
  1086  
  1087  func (s *ClientSynchronizer) processTrustedVerifyBatches(lastVerifiedBatch etherman.VerifiedBatch, dbTx pgx.Tx) error {
  1088  	lastVBatch, err := s.state.GetLastVerifiedBatch(s.ctx, dbTx)
  1089  	if err != nil {
  1090  		log.Errorf("error getting lastVerifiedBatch stored in db in processTrustedVerifyBatches. Processing synced blockNumber: %d", lastVerifiedBatch.BlockNumber)
  1091  		rollbackErr := dbTx.Rollback(s.ctx)
  1092  		if rollbackErr != nil {
  1093  			log.Errorf("error rolling back state. Processing synced blockNumber: %d, rollbackErr: %s, error : %v", lastVerifiedBatch.BlockNumber, rollbackErr.Error(), err)
  1094  			return rollbackErr
  1095  		}
  1096  		log.Errorf("error getting lastVerifiedBatch stored in db in processTrustedVerifyBatches. Processing synced blockNumber: %d, error: %v", lastVerifiedBatch.BlockNumber, err)
  1097  		return err
  1098  	}
  1099  	nbatches := lastVerifiedBatch.BatchNumber - lastVBatch.BatchNumber
  1100  	batch, err := s.state.GetBatchByNumber(s.ctx, lastVerifiedBatch.BatchNumber, dbTx)
  1101  	if err != nil {
  1102  		log.Errorf("error getting GetBatchByNumber stored in db in processTrustedVerifyBatches. Processing blockNumber: %d", lastVerifiedBatch.BatchNumber)
  1103  		rollbackErr := dbTx.Rollback(s.ctx)
  1104  		if rollbackErr != nil {
  1105  			log.Errorf("error rolling back state. Processing blockNumber: %d, rollbackErr: %s, error : %v", lastVerifiedBatch.BatchNumber, rollbackErr.Error(), err)
  1106  			return rollbackErr
  1107  		}
  1108  		log.Errorf("error getting GetBatchByNumber stored in db in processTrustedVerifyBatches. Processing blockNumber: %d, error: %v", lastVerifiedBatch.BatchNumber, err)
  1109  		return err
  1110  	}
  1111  
  1112  	// Checks that calculated state root matches with the verified state root in the smc
  1113  	if batch.StateRoot != lastVerifiedBatch.StateRoot {
  1114  		log.Warn("nbatches: ", nbatches)
  1115  		log.Warnf("Batch from db: %+v", batch)
  1116  		log.Warnf("Verified Batch: %+v", lastVerifiedBatch)
  1117  		log.Errorf("error: stateRoot calculated and state root verified don't match in processTrustedVerifyBatches. Processing blockNumber: %d", lastVerifiedBatch.BatchNumber)
  1118  		rollbackErr := dbTx.Rollback(s.ctx)
  1119  		if rollbackErr != nil {
  1120  			log.Errorf("error rolling back state. Processing blockNumber: %d, rollbackErr: %v", lastVerifiedBatch.BatchNumber, rollbackErr)
  1121  			return rollbackErr
  1122  		}
  1123  		log.Errorf("error: stateRoot calculated and state root verified don't match in processTrustedVerifyBatches. Processing blockNumber: %d", lastVerifiedBatch.BatchNumber)
  1124  		return fmt.Errorf("error: stateRoot calculated and state root verified don't match in processTrustedVerifyBatches. Processing blockNumber: %d", lastVerifiedBatch.BatchNumber)
  1125  	}
  1126  	var i uint64
  1127  	for i = 1; i <= nbatches; i++ {
  1128  		verifiedB := state.VerifiedBatch{
  1129  			BlockNumber: lastVerifiedBatch.BlockNumber,
  1130  			BatchNumber: lastVBatch.BatchNumber + i,
  1131  			Aggregator:  lastVerifiedBatch.Aggregator,
  1132  			StateRoot:   lastVerifiedBatch.StateRoot,
  1133  			TxHash:      lastVerifiedBatch.TxHash,
  1134  			IsTrusted:   true,
  1135  		}
  1136  		err = s.state.AddVerifiedBatch(s.ctx, &verifiedB, dbTx)
  1137  		if err != nil {
  1138  			log.Errorf("error storing the verifiedB in processTrustedVerifyBatches. verifiedBatch: %+v, lastVerifiedBatch: %+v", verifiedB, lastVerifiedBatch)
  1139  			rollbackErr := dbTx.Rollback(s.ctx)
  1140  			if rollbackErr != nil {
  1141  				log.Errorf("error rolling back state. BlockNumber: %d, rollbackErr: %s, error : %v", lastVerifiedBatch.BlockNumber, rollbackErr.Error(), err)
  1142  				return rollbackErr
  1143  			}
  1144  			log.Errorf("error storing the verifiedB in processTrustedVerifyBatches. BlockNumber: %d, error: %v", lastVerifiedBatch.BlockNumber, err)
  1145  			return err
  1146  		}
  1147  	}
  1148  	return nil
  1149  }
  1150  
  1151  func (s *ClientSynchronizer) processTrustedBatch(trustedBatch *types.Batch, dbTx pgx.Tx) error {
  1152  	log.Debugf("processing trusted batch: %v", trustedBatch.Number)
  1153  	trustedBatchL2Data := trustedBatch.BatchL2Data
  1154  
  1155  	batch, err := s.state.GetBatchByNumber(s.ctx, uint64(trustedBatch.Number), nil)
  1156  	if err != nil && err != state.ErrStateNotSynchronized {
  1157  		log.Warnf("failed to get batch %v from local trusted state. Error: %v", trustedBatch.Number, err)
  1158  		return err
  1159  	}
  1160  
  1161  	// check if batch needs to be synchronized
  1162  	if batch != nil {
  1163  		matchNumber := batch.BatchNumber == uint64(trustedBatch.Number)
  1164  		matchGER := batch.GlobalExitRoot.String() == trustedBatch.GlobalExitRoot.String()
  1165  		matchLER := batch.LocalExitRoot.String() == trustedBatch.LocalExitRoot.String()
  1166  		matchSR := batch.StateRoot.String() == trustedBatch.StateRoot.String()
  1167  		matchCoinbase := batch.Coinbase.String() == trustedBatch.Coinbase.String()
  1168  		matchTimestamp := uint64(batch.Timestamp.Unix()) == uint64(trustedBatch.Timestamp)
  1169  		matchL2Data := hex.EncodeToString(batch.BatchL2Data) == hex.EncodeToString(trustedBatchL2Data)
  1170  
  1171  		if matchNumber && matchGER && matchLER && matchSR &&
  1172  			matchCoinbase && matchTimestamp && matchL2Data {
  1173  			log.Debugf("batch %v already synchronized", trustedBatch.Number)
  1174  			return nil
  1175  		}
  1176  		log.Infof("batch %v needs to be updated", trustedBatch.Number)
  1177  	} else {
  1178  		log.Infof("batch %v needs to be synchronized", trustedBatch.Number)
  1179  	}
  1180  
  1181  	log.Debugf("resetting trusted state from batch %v", trustedBatch.Number)
  1182  	previousBatchNumber := trustedBatch.Number - 1
  1183  	if err := s.state.ResetTrustedState(s.ctx, uint64(previousBatchNumber), dbTx); err != nil {
  1184  		log.Errorf("failed to reset trusted state", trustedBatch.Number)
  1185  		return err
  1186  	}
  1187  
  1188  	log.Debugf("opening batch %v", trustedBatch.Number)
  1189  	processCtx := state.ProcessingContext{
  1190  		BatchNumber:    uint64(trustedBatch.Number),
  1191  		Coinbase:       common.HexToAddress(trustedBatch.Coinbase.String()),
  1192  		Timestamp:      time.Unix(int64(trustedBatch.Timestamp), 0),
  1193  		GlobalExitRoot: trustedBatch.GlobalExitRoot,
  1194  	}
  1195  	if err := s.state.OpenBatch(s.ctx, processCtx, dbTx); err != nil {
  1196  		log.Errorf("error opening batch %d", trustedBatch.Number)
  1197  		return err
  1198  	}
  1199  
  1200  	log.Debugf("processing sequencer for batch %v", trustedBatch.Number)
  1201  
  1202  	processBatchResp, err := s.state.ProcessSequencerBatch(s.ctx, uint64(trustedBatch.Number), trustedBatchL2Data, metrics.SynchronizerCallerLabel, dbTx)
  1203  	if err != nil {
  1204  		log.Errorf("error processing sequencer batch for batch: %d", trustedBatch.Number)
  1205  		return err
  1206  	}
  1207  
  1208  	log.Debugf("storing transactions for batch %v", trustedBatch.Number)
  1209  	if err = s.state.StoreTransactions(s.ctx, uint64(trustedBatch.Number), processBatchResp.Responses, dbTx); err != nil {
  1210  		log.Errorf("failed to store transactions for batch: %d", trustedBatch.Number)
  1211  		return err
  1212  	}
  1213  
  1214  	log.Debug("trustedBatch.StateRoot ", trustedBatch.StateRoot)
  1215  	isBatchClosed := trustedBatch.StateRoot.String() != state.ZeroHash.String()
  1216  	if isBatchClosed {
  1217  		receipt := state.ProcessingReceipt{
  1218  			BatchNumber:   uint64(trustedBatch.Number),
  1219  			StateRoot:     processBatchResp.NewStateRoot,
  1220  			LocalExitRoot: processBatchResp.NewLocalExitRoot,
  1221  			BatchL2Data:   trustedBatchL2Data,
  1222  			AccInputHash:  trustedBatch.AccInputHash,
  1223  		}
  1224  		log.Debugf("closing batch %v", trustedBatch.Number)
  1225  		if err := s.state.CloseBatch(s.ctx, receipt, dbTx); err != nil {
  1226  			log.Errorf("error closing batch %d", trustedBatch.Number)
  1227  			return err
  1228  		}
  1229  	}
  1230  
  1231  	log.Infof("batch %v synchronized", trustedBatch.Number)
  1232  	return nil
  1233  }
  1234  
  1235  func (s *ClientSynchronizer) reorgPool(dbTx pgx.Tx) error {
  1236  	latestBatchNum, err := s.etherMan.GetLatestBatchNumber()
  1237  	if err != nil {
  1238  		log.Error("error getting the latestBatchNumber virtualized in the smc. Error: ", err)
  1239  		return err
  1240  	}
  1241  	batchNumber := latestBatchNum + 1
  1242  	// Get transactions that have to be included in the pool again
  1243  	txs, err := s.state.GetReorgedTransactions(s.ctx, batchNumber, dbTx)
  1244  	if err != nil {
  1245  		log.Errorf("error getting txs from trusted state. BatchNumber: %d, error: %v", batchNumber, err)
  1246  		return err
  1247  	}
  1248  	log.Debug("Reorged transactions: ", txs)
  1249  
  1250  	// Remove txs from the pool
  1251  	err = s.pool.DeleteReorgedTransactions(s.ctx, txs)
  1252  	if err != nil {
  1253  		log.Errorf("error deleting txs from the pool. BatchNumber: %d, error: %v", batchNumber, err)
  1254  		return err
  1255  	}
  1256  	log.Debug("Delete reorged transactions")
  1257  
  1258  	// Add txs to the pool
  1259  	for _, tx := range txs {
  1260  		// Insert tx in WIP status to avoid the sequencer to grab them before it gets restarted
  1261  		// When the sequencer restarts, it will update the status to pending non-wip
  1262  		err = s.pool.StoreTx(s.ctx, *tx, "", true)
  1263  		if err != nil {
  1264  			log.Errorf("error storing tx into the pool again. TxHash: %s. BatchNumber: %d, error: %v", tx.Hash().String(), batchNumber, err)
  1265  			return err
  1266  		}
  1267  		log.Debug("Reorged transactions inserted in the pool: ", tx.Hash())
  1268  	}
  1269  	return nil
  1270  }