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 }