github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/rollup/sync_service.go (about) 1 package rollup 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "math/big" 8 "strconv" 9 "sync" 10 "sync/atomic" 11 "time" 12 13 "github.com/ethereum-optimism/optimism/l2geth/common" 14 "github.com/ethereum-optimism/optimism/l2geth/core" 15 "github.com/ethereum-optimism/optimism/l2geth/core/state" 16 "github.com/ethereum-optimism/optimism/l2geth/ethdb" 17 "github.com/ethereum-optimism/optimism/l2geth/event" 18 "github.com/ethereum-optimism/optimism/l2geth/log" 19 20 "github.com/ethereum-optimism/optimism/l2geth/core/rawdb" 21 "github.com/ethereum-optimism/optimism/l2geth/core/types" 22 23 "github.com/ethereum-optimism/optimism/l2geth/eth/gasprice" 24 "github.com/ethereum-optimism/optimism/l2geth/rollup/fees" 25 "github.com/ethereum-optimism/optimism/l2geth/rollup/rcfg" 26 ) 27 28 var ( 29 // errBadConfig is the error when the SyncService is started with invalid 30 // configuration options 31 errBadConfig = errors.New("bad config") 32 // errShortRemoteTip is an error for when the remote tip is shorter than the 33 // local tip 34 errShortRemoteTip = errors.New("unexpected remote less than tip") 35 // errZeroGasPriceTx is the error for when a user submits a transaction 36 // with gas price zero and fees are currently enforced 37 errZeroGasPriceTx = errors.New("cannot accept 0 gas price transaction") 38 float1 = big.NewFloat(1) 39 ) 40 41 // SyncService implements the main functionality around pulling in transactions 42 // and executing them. It can be configured to run in both sequencer mode and in 43 // verifier mode. 44 type SyncService struct { 45 ctx context.Context 46 cancel context.CancelFunc 47 verifier bool 48 db ethdb.Database 49 scope event.SubscriptionScope 50 txFeed event.Feed 51 txLock sync.Mutex 52 loopLock sync.Mutex 53 enable bool 54 bc *core.BlockChain 55 txpool *core.TxPool 56 RollupGpo *gasprice.RollupOracle 57 client RollupClient 58 syncing atomic.Value 59 chainHeadSub event.Subscription 60 OVMContext OVMContext 61 pollInterval time.Duration 62 timestampRefreshThreshold time.Duration 63 chainHeadCh chan core.ChainHeadEvent 64 backend Backend 65 gasPriceOracleOwnerAddress common.Address 66 gasPriceOracleOwnerAddressLock *sync.RWMutex 67 enforceFees bool 68 signer types.Signer 69 feeThresholdUp *big.Float 70 feeThresholdDown *big.Float 71 } 72 73 // NewSyncService returns an initialized sync service 74 func NewSyncService(ctx context.Context, cfg Config, txpool *core.TxPool, bc *core.BlockChain, db ethdb.Database) (*SyncService, error) { 75 if bc == nil { 76 return nil, errors.New("Must pass BlockChain to SyncService") 77 } 78 79 ctx, cancel := context.WithCancel(ctx) 80 _ = cancel // satisfy govet 81 82 if cfg.IsVerifier { 83 log.Info("Running in verifier mode", "sync-backend", cfg.Backend.String()) 84 } else { 85 log.Info("Running in sequencer mode", "sync-backend", cfg.Backend.String()) 86 log.Info("Fees", "threshold-up", cfg.FeeThresholdUp, "threshold-down", cfg.FeeThresholdDown) 87 log.Info("Enforce Fees", "set", cfg.EnforceFees) 88 } 89 90 pollInterval := cfg.PollInterval 91 if pollInterval == 0 { 92 log.Info("Sanitizing poll interval to 15 seconds") 93 pollInterval = time.Second * 15 94 } 95 timestampRefreshThreshold := cfg.TimestampRefreshThreshold 96 if timestampRefreshThreshold == 0 { 97 log.Info("Sanitizing timestamp refresh threshold to 3 minutes") 98 timestampRefreshThreshold = time.Minute * 3 99 } 100 101 // Layer 2 chainid 102 chainID := bc.Config().ChainID 103 if chainID == nil { 104 return nil, errors.New("Must configure with chain id") 105 } 106 // Initialize the rollup client 107 client := NewClient(cfg.RollupClientHttp, chainID) 108 log.Info("Configured rollup client", "url", cfg.RollupClientHttp, "chain-id", chainID.Uint64(), "ctc-deploy-height", cfg.CanonicalTransactionChainDeployHeight) 109 110 // Ensure sane values for the fee thresholds 111 if cfg.FeeThresholdDown != nil { 112 // The fee threshold down should be less than 1 113 if cfg.FeeThresholdDown.Cmp(float1) != -1 { 114 return nil, fmt.Errorf("%w: fee threshold down not lower than 1: %f", errBadConfig, 115 cfg.FeeThresholdDown) 116 } 117 } 118 if cfg.FeeThresholdUp != nil { 119 // The fee threshold up should be greater than 1 120 if cfg.FeeThresholdUp.Cmp(float1) != 1 { 121 return nil, fmt.Errorf("%w: fee threshold up not larger than 1: %f", errBadConfig, 122 cfg.FeeThresholdUp) 123 } 124 } 125 126 service := SyncService{ 127 ctx: ctx, 128 cancel: cancel, 129 verifier: cfg.IsVerifier, 130 enable: cfg.Eth1SyncServiceEnable, 131 syncing: atomic.Value{}, 132 bc: bc, 133 txpool: txpool, 134 chainHeadCh: make(chan core.ChainHeadEvent, 1), 135 client: client, 136 db: db, 137 pollInterval: pollInterval, 138 timestampRefreshThreshold: timestampRefreshThreshold, 139 backend: cfg.Backend, 140 gasPriceOracleOwnerAddress: cfg.GasPriceOracleOwnerAddress, 141 gasPriceOracleOwnerAddressLock: new(sync.RWMutex), 142 enforceFees: cfg.EnforceFees, 143 signer: types.NewEIP155Signer(chainID), 144 feeThresholdDown: cfg.FeeThresholdDown, 145 feeThresholdUp: cfg.FeeThresholdUp, 146 } 147 148 // The chainHeadSub is used to synchronize the SyncService with the chain. 149 // As the SyncService processes transactions, it waits until the transaction 150 // is added to the chain. This synchronization is required for handling 151 // reorgs and also favors safety over liveliness. If a transaction breaks 152 // things downstream, it is expected that this channel will halt ingestion 153 // of additional transactions by the SyncService. 154 service.chainHeadSub = service.bc.SubscribeChainHeadEvent(service.chainHeadCh) 155 156 // Initial sync service setup if it is enabled. This code depends on 157 // a remote server that indexes the layer one contracts. Place this 158 // code behind this if statement so that this can run without the 159 // requirement of the remote server being up. 160 if service.enable { 161 // Ensure that the rollup client can connect to a remote server 162 // before starting. Retry until it can connect. 163 tEnsure := time.NewTicker(10 * time.Second) 164 for ; true; <-tEnsure.C { 165 err := service.ensureClient() 166 if err != nil { 167 log.Info("Cannot connect to upstream service", "msg", err) 168 } else { 169 log.Info("Connected to upstream service") 170 tEnsure.Stop() 171 break 172 } 173 } 174 175 if !cfg.IsVerifier || cfg.Backend == BackendL2 { 176 // Wait until the remote service is done syncing 177 tStatus := time.NewTicker(10 * time.Second) 178 for ; true; <-tStatus.C { 179 status, err := service.client.SyncStatus(service.backend) 180 if err != nil { 181 log.Error("Cannot get sync status") 182 continue 183 } 184 if !status.Syncing { 185 tStatus.Stop() 186 break 187 } 188 log.Info("Still syncing", "index", status.CurrentTransactionIndex, "tip", status.HighestKnownTransactionIndex) 189 } 190 } 191 192 // Initialize the latest L1 data here to make sure that 193 // it happens before the RPC endpoints open up 194 // Only do it if the sync service is enabled so that this 195 // can be ran without needing to have a configured RollupClient. 196 err := service.initializeLatestL1(cfg.CanonicalTransactionChainDeployHeight) 197 if err != nil { 198 return nil, fmt.Errorf("Cannot initialize latest L1 data: %w", err) 199 } 200 201 // Log the OVMContext information on startup 202 bn := service.GetLatestL1BlockNumber() 203 ts := service.GetLatestL1Timestamp() 204 log.Info("Initialized Latest L1 Info", "blocknumber", bn, "timestamp", ts) 205 206 index := service.GetLatestIndex() 207 queueIndex := service.GetLatestEnqueueIndex() 208 verifiedIndex := service.GetLatestVerifiedIndex() 209 block := service.bc.CurrentBlock() 210 if block == nil { 211 block = types.NewBlock(&types.Header{}, nil, nil, nil) 212 } 213 header := block.Header() 214 log.Info("Initial Rollup State", "state", header.Root.Hex(), "index", stringify(index), "queue-index", stringify(queueIndex), "verified-index", verifiedIndex) 215 216 // The sequencer needs to sync to the tip at start up 217 // By setting the sync status to true, it will prevent RPC calls. 218 // Be sure this is set to false later. 219 if !service.verifier { 220 service.setSyncStatus(true) 221 } 222 } 223 return &service, nil 224 } 225 226 // ensureClient checks to make sure that the remote transaction source is 227 // available. It will return an error if it cannot connect via HTTP 228 func (s *SyncService) ensureClient() error { 229 _, err := s.client.GetLatestEthContext() 230 if err != nil { 231 return fmt.Errorf("Cannot connect to data service: %w", err) 232 } 233 return nil 234 } 235 236 // Start initializes the service 237 func (s *SyncService) Start() error { 238 if !s.enable { 239 log.Info("Running without syncing enabled") 240 return nil 241 } 242 log.Info("Initializing Sync Service") 243 if err := s.updateGasPriceOracleCache(nil); err != nil { 244 return err 245 } 246 247 if s.verifier { 248 go s.VerifierLoop() 249 } else { 250 go func() { 251 if err := s.syncTransactionsToTip(); err != nil { 252 log.Crit("Sequencer cannot sync transactions to tip", "err", err) 253 } 254 if err := s.syncQueueToTip(); err != nil { 255 log.Crit("Sequencer cannot sync queue to tip", "err", err) 256 } 257 s.setSyncStatus(false) 258 go s.SequencerLoop() 259 }() 260 } 261 return nil 262 } 263 264 // initializeLatestL1 sets the initial values of the `L1BlockNumber` 265 // and `L1Timestamp` to the deploy height of the Canonical Transaction 266 // chain if the chain is empty, otherwise set it from the last 267 // transaction processed. This must complete before transactions 268 // are accepted via RPC when running as a sequencer. 269 func (s *SyncService) initializeLatestL1(ctcDeployHeight *big.Int) error { 270 index := s.GetLatestIndex() 271 if index == nil { 272 if ctcDeployHeight == nil { 273 return errors.New("Must configure with canonical transaction chain deploy height") 274 } 275 log.Info("Initializing initial OVM Context", "ctc-deploy-height", ctcDeployHeight.Uint64()) 276 context, err := s.client.GetEthContext(ctcDeployHeight.Uint64()) 277 if err != nil { 278 return fmt.Errorf("Cannot fetch ctc deploy block at height %d: %w", ctcDeployHeight.Uint64(), err) 279 } 280 s.SetLatestL1Timestamp(context.Timestamp) 281 s.SetLatestL1BlockNumber(context.BlockNumber) 282 } else { 283 // Recover from accidentally skipped batches if necessary. 284 if s.verifier && s.backend == BackendL1 { 285 tx, err := s.client.GetRawTransaction(*index, s.backend) 286 if err != nil { 287 return fmt.Errorf("Cannot fetch transaction from dtl at index %d: %w", *index, err) 288 } 289 290 oldbatchIndex := s.GetLatestBatchIndex() 291 newBatchIndex := tx.Transaction.BatchIndex 292 if tx.Transaction.BatchIndex > 0 { 293 newBatchIndex -= 1 294 } 295 296 log.Info("Updating batch index", "old", oldbatchIndex, "new", newBatchIndex) 297 s.SetLatestBatchIndex(&newBatchIndex) 298 } 299 300 log.Info("Found latest index", "index", *index) 301 block := s.bc.GetBlockByNumber(*index + 1) 302 if block == nil { 303 block = s.bc.CurrentBlock() 304 blockNum := block.Number().Uint64() 305 if blockNum > *index { 306 // This is recoverable with a reorg but should never happen 307 return fmt.Errorf("Current block height greater than index") 308 } 309 var idx *uint64 310 if blockNum > 0 { 311 num := blockNum - 1 312 idx = &num 313 } 314 s.SetLatestIndex(idx) 315 log.Info("Block not found, resetting index", "new", stringify(idx), "old", *index) 316 } 317 txs := block.Transactions() 318 if len(txs) != 1 { 319 log.Error("Unexpected number of transactions in block", "count", len(txs)) 320 panic("Cannot recover OVM Context") 321 } 322 tx := txs[0] 323 s.SetLatestL1Timestamp(tx.L1Timestamp()) 324 s.SetLatestL1BlockNumber(tx.L1BlockNumber().Uint64()) 325 } 326 queueIndex := s.GetLatestEnqueueIndex() 327 if queueIndex == nil { 328 enqueue, err := s.client.GetLastConfirmedEnqueue() 329 // There are no enqueues yet 330 if errors.Is(err, errElementNotFound) { 331 return nil 332 } 333 // Other unexpected error 334 if err != nil { 335 return fmt.Errorf("Cannot fetch last confirmed queue tx: %w", err) 336 } 337 // No error, the queue element was found 338 queueIndex = enqueue.GetMeta().QueueIndex 339 } else { 340 log.Info("Found latest queue index", "queue-index", *queueIndex) 341 // The queue index is defined. Work backwards from the tip 342 // to make sure that the indexed queue index is the latest 343 // enqueued transaction 344 block := s.bc.CurrentBlock() 345 for { 346 // There are no blocks in the chain 347 // This should never happen 348 if block == nil { 349 log.Warn("Found no genesis block when fixing queue index") 350 break 351 } 352 num := block.Number().Uint64() 353 // Handle the genesis block 354 if num == 0 { 355 log.Info("Hit genesis block when fixing queue index") 356 queueIndex = nil 357 break 358 } 359 txs := block.Transactions() 360 // This should never happen 361 if len(txs) != 1 { 362 log.Warn("Found block with unexpected number of txs", "count", len(txs), "height", num) 363 break 364 } 365 tx := txs[0] 366 qi := tx.GetMeta().QueueIndex 367 // When the queue index is set 368 if qi != nil { 369 if *qi == *queueIndex { 370 log.Info("Found correct staring queue index", "queue-index", *qi) 371 } else { 372 log.Info("Found incorrect staring queue index, fixing", "old", *queueIndex, "new", *qi) 373 queueIndex = qi 374 } 375 break 376 } 377 block = s.bc.GetBlockByNumber(num - 1) 378 } 379 } 380 s.SetLatestEnqueueIndex(queueIndex) 381 return nil 382 } 383 384 // setSyncStatus sets the `syncing` field as well as prevents 385 // any transactions from coming in via RPC. 386 // `syncing` should never be set directly outside of this function. 387 func (s *SyncService) setSyncStatus(status bool) { 388 log.Info("Setting sync status", "status", status) 389 s.syncing.Store(status) 390 } 391 392 // IsSyncing returns the syncing status of the syncservice. 393 // Returns false if not yet set. 394 func (s *SyncService) IsSyncing() bool { 395 value := s.syncing.Load() 396 val, ok := value.(bool) 397 if !ok { 398 return false 399 } 400 return val 401 } 402 403 // Stop will close the open channels and cancel the goroutines 404 // started by this service. 405 func (s *SyncService) Stop() error { 406 log.Info("Stopping sync service") 407 s.scope.Close() 408 s.chainHeadSub.Unsubscribe() 409 close(s.chainHeadCh) 410 411 if s.cancel != nil { 412 defer s.cancel() 413 } 414 return nil 415 } 416 417 // VerifierLoop is the main loop for Verifier mode 418 func (s *SyncService) VerifierLoop() { 419 log.Info("Starting Verifier Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold) 420 t := time.NewTicker(s.pollInterval) 421 defer t.Stop() 422 423 for { 424 select { 425 case <-t.C: 426 if err := s.verify(); err != nil { 427 log.Error("Could not verify", "error", err) 428 } 429 case <-s.ctx.Done(): 430 return 431 } 432 } 433 } 434 435 // verify is the main logic for the Verifier. The verifier logic is different 436 // depending on the Backend 437 func (s *SyncService) verify() error { 438 switch s.backend { 439 case BackendL1: 440 if err := s.syncBatchesToTip(); err != nil { 441 return fmt.Errorf("Verifier cannot sync transaction batches to tip: %w", err) 442 } 443 case BackendL2: 444 if err := s.syncTransactionsToTip(); err != nil { 445 return fmt.Errorf("Verifier cannot sync transactions with BackendL2: %w", err) 446 } 447 } 448 return nil 449 } 450 451 // SequencerLoop is the polling loop that runs in sequencer mode. It sequences 452 // transactions and then updates the EthContext. 453 func (s *SyncService) SequencerLoop() { 454 log.Info("Starting Sequencer Loop", "poll-interval", s.pollInterval, "timestamp-refresh-threshold", s.timestampRefreshThreshold) 455 t := time.NewTicker(s.pollInterval) 456 defer t.Stop() 457 for ; true; <-t.C { 458 s.txLock.Lock() 459 if err := s.sequence(); err != nil { 460 log.Error("Could not sequence", "error", err) 461 } 462 s.txLock.Unlock() 463 464 if err := s.updateL1BlockNumber(); err != nil { 465 log.Error("Could not update execution context", "error", err) 466 } 467 } 468 } 469 470 // sequence is the main logic for the Sequencer. It will sync any `enqueue` 471 // transactions it has yet to sync and then pull in transaction batches to 472 // compare against the transactions it has in its local state. The sequencer 473 // should reorg based on the transaction batches that are posted because 474 // L1 is the source of truth. The sequencer concurrently accepts user 475 // transactions via the RPC. When reorg logic is enabled, this should 476 // also call `syncBatchesToTip` 477 func (s *SyncService) sequence() error { 478 if err := s.syncQueueToTip(); err != nil { 479 return fmt.Errorf("Sequencer cannot sequence queue: %w", err) 480 } 481 return nil 482 } 483 484 func (s *SyncService) syncQueueToTip() error { 485 if err := s.syncToTip(s.syncQueue, s.client.GetLatestEnqueueIndex); err != nil { 486 return fmt.Errorf("Cannot sync queue to tip: %w", err) 487 } 488 return nil 489 } 490 491 func (s *SyncService) syncBatchesToTip() error { 492 if err := s.syncToTip(s.syncBatches, s.client.GetLatestTransactionBatchIndex); err != nil { 493 return fmt.Errorf("Cannot sync transaction batches to tip: %w", err) 494 } 495 return nil 496 } 497 498 func (s *SyncService) syncTransactionsToTip() error { 499 sync := func() (*uint64, error) { 500 return s.syncTransactions(s.backend) 501 } 502 check := func() (*uint64, error) { 503 return s.client.GetLatestTransactionIndex(s.backend) 504 } 505 if err := s.syncToTip(sync, check); err != nil { 506 return fmt.Errorf("Verifier cannot sync transactions with backend %s: %w", s.backend.String(), err) 507 } 508 return nil 509 } 510 511 // updateL1GasPrice queries for the current L1 gas price and then stores it 512 // in the L1 Gas Price Oracle. This must be called over time to properly 513 // estimate the transaction fees that the sequencer should charge. 514 func (s *SyncService) updateL1GasPrice(statedb *state.StateDB) error { 515 value, err := s.readGPOStorageSlot(statedb, rcfg.L1GasPriceSlot) 516 if err != nil { 517 return err 518 } 519 return s.RollupGpo.SetL1GasPrice(value) 520 } 521 522 // updateL2GasPrice accepts a state db and reads the gas price from the gas 523 // price oracle at the state that corresponds to the state db. If no state db 524 // is passed in, then the tip is used. 525 func (s *SyncService) updateL2GasPrice(statedb *state.StateDB) error { 526 value, err := s.readGPOStorageSlot(statedb, rcfg.L2GasPriceSlot) 527 if err != nil { 528 return err 529 } 530 return s.RollupGpo.SetL2GasPrice(value) 531 } 532 533 // updateOverhead will update the overhead value from the OVM_GasPriceOracle 534 // in the local cache 535 func (s *SyncService) updateOverhead(statedb *state.StateDB) error { 536 value, err := s.readGPOStorageSlot(statedb, rcfg.OverheadSlot) 537 if err != nil { 538 return err 539 } 540 return s.RollupGpo.SetOverhead(value) 541 } 542 543 // updateScalar will update the scalar value from the OVM_GasPriceOracle 544 // in the local cache 545 func (s *SyncService) updateScalar(statedb *state.StateDB) error { 546 scalar, err := s.readGPOStorageSlot(statedb, rcfg.ScalarSlot) 547 if err != nil { 548 return err 549 } 550 decimals, err := s.readGPOStorageSlot(statedb, rcfg.DecimalsSlot) 551 if err != nil { 552 return err 553 } 554 return s.RollupGpo.SetScalar(scalar, decimals) 555 } 556 557 // cacheGasPriceOracleOwner accepts a statedb and caches the gas price oracle 558 // owner address locally 559 func (s *SyncService) cacheGasPriceOracleOwner(statedb *state.StateDB) error { 560 s.gasPriceOracleOwnerAddressLock.Lock() 561 defer s.gasPriceOracleOwnerAddressLock.Unlock() 562 563 value, err := s.readGPOStorageSlot(statedb, rcfg.L2GasPriceOracleOwnerSlot) 564 if err != nil { 565 return err 566 } 567 s.gasPriceOracleOwnerAddress = common.BigToAddress(value) 568 return nil 569 } 570 571 // readGPOStorageSlot is a helper function for reading storage 572 // slots from the OVM_GasPriceOracle 573 func (s *SyncService) readGPOStorageSlot(statedb *state.StateDB, hash common.Hash) (*big.Int, error) { 574 var err error 575 if statedb == nil { 576 statedb, err = s.bc.State() 577 if err != nil { 578 return nil, err 579 } 580 } 581 result := statedb.GetState(rcfg.L2GasPriceOracleAddress, hash) 582 return result.Big(), nil 583 } 584 585 // updateGasPriceOracleCache caches the owner as well as updating the 586 // the L2 gas price from the OVM_GasPriceOracle. 587 // This should be sure to read all public variables from the 588 // OVM_GasPriceOracle 589 func (s *SyncService) updateGasPriceOracleCache(hash *common.Hash) error { 590 var statedb *state.StateDB 591 var err error 592 if hash != nil { 593 statedb, err = s.bc.StateAt(*hash) 594 } else { 595 statedb, err = s.bc.State() 596 } 597 if err != nil { 598 return err 599 } 600 if err := s.cacheGasPriceOracleOwner(statedb); err != nil { 601 return err 602 } 603 if err := s.updateL2GasPrice(statedb); err != nil { 604 return err 605 } 606 if err := s.updateL1GasPrice(statedb); err != nil { 607 return err 608 } 609 if err := s.updateOverhead(statedb); err != nil { 610 return err 611 } 612 if err := s.updateScalar(statedb); err != nil { 613 return err 614 } 615 return nil 616 } 617 618 // A thread safe getter for the gas price oracle owner address 619 func (s *SyncService) GasPriceOracleOwnerAddress() *common.Address { 620 s.gasPriceOracleOwnerAddressLock.RLock() 621 defer s.gasPriceOracleOwnerAddressLock.RUnlock() 622 return &s.gasPriceOracleOwnerAddress 623 } 624 625 /// Update the execution context's timestamp and blocknumber 626 /// over time. This is only necessary for the sequencer. 627 func (s *SyncService) updateL1BlockNumber() error { 628 context, err := s.client.GetLatestEthContext() 629 if err != nil { 630 return fmt.Errorf("Cannot get eth context: %w", err) 631 } 632 latest := s.GetLatestL1BlockNumber() 633 if context.BlockNumber > latest { 634 log.Info("Updating L1 block number", "blocknumber", context.BlockNumber) 635 s.SetLatestL1BlockNumber(context.BlockNumber) 636 } 637 return nil 638 } 639 640 // Methods for safely accessing and storing the latest 641 // L1 blocknumber and timestamp. These are held in memory. 642 643 // GetLatestL1Timestamp returns the OVMContext timestamp 644 func (s *SyncService) GetLatestL1Timestamp() uint64 { 645 return atomic.LoadUint64(&s.OVMContext.timestamp) 646 } 647 648 // GetLatestL1BlockNumber returns the OVMContext blocknumber 649 func (s *SyncService) GetLatestL1BlockNumber() uint64 { 650 return atomic.LoadUint64(&s.OVMContext.blockNumber) 651 } 652 653 // SetLatestL1Timestamp will set the OVMContext timestamp 654 func (s *SyncService) SetLatestL1Timestamp(ts uint64) { 655 atomic.StoreUint64(&s.OVMContext.timestamp, ts) 656 } 657 658 // SetLatestL1BlockNumber will set the OVMContext blocknumber 659 func (s *SyncService) SetLatestL1BlockNumber(bn uint64) { 660 atomic.StoreUint64(&s.OVMContext.blockNumber, bn) 661 } 662 663 // GetLatestEnqueueIndex reads the last queue index processed 664 func (s *SyncService) GetLatestEnqueueIndex() *uint64 { 665 return rawdb.ReadHeadQueueIndex(s.db) 666 } 667 668 // GetNextEnqueueIndex returns the next queue index to process 669 func (s *SyncService) GetNextEnqueueIndex() uint64 { 670 latest := s.GetLatestEnqueueIndex() 671 if latest == nil { 672 return 0 673 } 674 return *latest + 1 675 } 676 677 // SetLatestEnqueueIndex writes the last queue index that was processed 678 func (s *SyncService) SetLatestEnqueueIndex(index *uint64) { 679 if index != nil { 680 rawdb.WriteHeadQueueIndex(s.db, *index) 681 } 682 } 683 684 // GetLatestIndex reads the last CTC index that was processed 685 func (s *SyncService) GetLatestIndex() *uint64 { 686 return rawdb.ReadHeadIndex(s.db) 687 } 688 689 // GetNextIndex reads the next CTC index to process 690 func (s *SyncService) GetNextIndex() uint64 { 691 latest := s.GetLatestIndex() 692 if latest == nil { 693 return 0 694 } 695 return *latest + 1 696 } 697 698 // SetLatestIndex writes the last CTC index that was processed 699 func (s *SyncService) SetLatestIndex(index *uint64) { 700 if index != nil { 701 rawdb.WriteHeadIndex(s.db, *index) 702 } 703 } 704 705 // GetLatestVerifiedIndex reads the last verified CTC index that was processed 706 // These are set by processing batches of transactions that were submitted to 707 // the Canonical Transaction Chain. 708 func (s *SyncService) GetLatestVerifiedIndex() *uint64 { 709 return rawdb.ReadHeadVerifiedIndex(s.db) 710 } 711 712 // GetNextVerifiedIndex reads the next verified index 713 func (s *SyncService) GetNextVerifiedIndex() uint64 { 714 index := s.GetLatestVerifiedIndex() 715 if index == nil { 716 return 0 717 } 718 return *index + 1 719 } 720 721 // SetLatestVerifiedIndex writes the last verified index that was processed 722 func (s *SyncService) SetLatestVerifiedIndex(index *uint64) { 723 if index != nil { 724 rawdb.WriteHeadVerifiedIndex(s.db, *index) 725 } 726 } 727 728 // GetLatestBatchIndex reads the last processed transaction batch 729 func (s *SyncService) GetLatestBatchIndex() *uint64 { 730 return rawdb.ReadHeadBatchIndex(s.db) 731 } 732 733 // GetNextBatchIndex reads the index of the next transaction batch to process 734 func (s *SyncService) GetNextBatchIndex() uint64 { 735 index := s.GetLatestBatchIndex() 736 if index == nil { 737 return 0 738 } 739 return *index + 1 740 } 741 742 // SetLatestBatchIndex writes the last index of the transaction batch that was processed 743 func (s *SyncService) SetLatestBatchIndex(index *uint64) { 744 if index != nil { 745 rawdb.WriteHeadBatchIndex(s.db, *index) 746 } 747 } 748 749 // applyTransaction is a higher level API for applying a transaction 750 func (s *SyncService) applyTransaction(tx *types.Transaction) error { 751 if tx.GetMeta().Index != nil { 752 return s.applyIndexedTransaction(tx) 753 } 754 return s.applyTransactionToTip(tx) 755 } 756 757 // applyIndexedTransaction applys a transaction that has an index. This means 758 // that the source of the transaction was either a L1 batch or from the 759 // sequencer. 760 func (s *SyncService) applyIndexedTransaction(tx *types.Transaction) error { 761 if tx == nil { 762 return errors.New("Transaction is nil in applyIndexedTransaction") 763 } 764 index := tx.GetMeta().Index 765 if index == nil { 766 return errors.New("No index found in applyIndexedTransaction") 767 } 768 log.Trace("Applying indexed transaction", "index", *index) 769 next := s.GetNextIndex() 770 if *index == next { 771 return s.applyTransactionToTip(tx) 772 } 773 if *index < next { 774 return s.applyHistoricalTransaction(tx) 775 } 776 return fmt.Errorf("Received tx at index %d when looking for %d", *index, next) 777 } 778 779 // applyHistoricalTransaction will compare a historical transaction against what 780 // is locally indexed. This will trigger a reorg in the future 781 func (s *SyncService) applyHistoricalTransaction(tx *types.Transaction) error { 782 if tx == nil { 783 return errors.New("Transaction is nil in applyHistoricalTransaction") 784 } 785 index := tx.GetMeta().Index 786 if index == nil { 787 return errors.New("No index is found in applyHistoricalTransaction") 788 } 789 // Handle the off by one 790 block := s.bc.GetBlockByNumber(*index + 1) 791 if block == nil { 792 return fmt.Errorf("Block %d is not found", *index+1) 793 } 794 txs := block.Transactions() 795 if len(txs) != 1 { 796 return fmt.Errorf("More than one transaction found in block %d", *index+1) 797 } 798 if !isCtcTxEqual(tx, txs[0]) { 799 log.Error("Mismatched transaction", "index", *index) 800 } else { 801 log.Debug("Historical transaction matches", "index", *index, "hash", tx.Hash().Hex()) 802 } 803 return nil 804 } 805 806 // applyTransactionToTip will do sanity checks on the transaction before 807 // applying it to the tip. It blocks until the transaction has been included in 808 // the chain. It is assumed that validation around the index has already 809 // happened. 810 func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error { 811 if tx == nil { 812 return errors.New("nil transaction passed to applyTransactionToTip") 813 } 814 // Queue Origin L1 to L2 transactions must have a timestamp that is set by 815 // the L1 block that holds the transaction. This should never happen but is 816 // a sanity check to prevent fraudulent execution. 817 // No need to unlock here as the lock is only taken when its a queue origin 818 // sequencer transaction. 819 if tx.QueueOrigin() == types.QueueOriginL1ToL2 { 820 if tx.L1Timestamp() == 0 { 821 return fmt.Errorf("Queue origin L1 to L2 transaction without a timestamp: %s", tx.Hash().Hex()) 822 } 823 } 824 825 // If there is no L1 timestamp assigned to the transaction, then assign a 826 // timestamp to it. The property that L1 to L2 transactions have the same 827 // timestamp as the L1 block that it was included in is removed for better 828 // UX. This functionality can be added back in during a future release. For 829 // now, the sequencer will assign a timestamp to each transaction. 830 ts := s.GetLatestL1Timestamp() 831 bn := s.GetLatestL1BlockNumber() 832 833 // The L1Timestamp is 0 for QueueOriginSequencer transactions when 834 // running as the sequencer, the transactions are coming in via RPC. 835 // This code path also runs for replicas/verifiers so any logic involving 836 // `time.Now` can only run for the sequencer. All other nodes must listen 837 // to what the sequencer says is the timestamp, otherwise there will be a 838 // network split. 839 // Note that it should never be possible for the timestamp to be set to 840 // 0 when running as a verifier. 841 shouldMalleateTimestamp := !s.verifier && tx.QueueOrigin() == types.QueueOriginL1ToL2 842 if tx.L1Timestamp() == 0 || shouldMalleateTimestamp { 843 // Get the latest known timestamp 844 current := time.Unix(int64(ts), 0) 845 // Get the current clocktime 846 now := time.Now() 847 // If enough time has passed, then assign the 848 // transaction to have the timestamp now. Otherwise, 849 // use the current timestamp 850 if now.Sub(current) > s.timestampRefreshThreshold { 851 current = now 852 } 853 log.Info("Updating latest timestamp", "timestamp", current, "unix", current.Unix()) 854 tx.SetL1Timestamp(uint64(current.Unix())) 855 } else if tx.L1Timestamp() == 0 && s.verifier { 856 // This should never happen 857 log.Error("No tx timestamp found when running as verifier", "hash", tx.Hash().Hex()) 858 } else if tx.L1Timestamp() < ts { 859 // This should never happen, but sometimes does 860 log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex(), "latest", ts, "tx", tx.L1Timestamp()) 861 } 862 863 l1BlockNumber := tx.L1BlockNumber() 864 // Set the L1 blocknumber 865 if l1BlockNumber == nil { 866 tx.SetL1BlockNumber(bn) 867 } else if l1BlockNumber.Uint64() > bn { 868 s.SetLatestL1BlockNumber(l1BlockNumber.Uint64()) 869 } else if l1BlockNumber.Uint64() < bn { 870 // l1BlockNumber < latest l1BlockNumber 871 // indicates an error 872 log.Error("Blocknumber monotonicity violation", "hash", tx.Hash().Hex(), 873 "new", l1BlockNumber.Uint64(), "old", bn) 874 } 875 876 // Store the latest timestamp value 877 if tx.L1Timestamp() > ts { 878 s.SetLatestL1Timestamp(tx.L1Timestamp()) 879 } 880 881 index := s.GetLatestIndex() 882 if tx.GetMeta().Index == nil { 883 if index == nil { 884 tx.SetIndex(0) 885 } else { 886 tx.SetIndex(*index + 1) 887 } 888 } 889 890 // On restart, these values are repaired to handle 891 // the case where the index is updated but the 892 // transaction isn't yet added to the chain 893 s.SetLatestIndex(tx.GetMeta().Index) 894 if queueIndex := tx.GetMeta().QueueIndex; queueIndex != nil { 895 s.SetLatestEnqueueIndex(queueIndex) 896 } 897 898 // The index was set above so it is safe to dereference 899 log.Debug("Applying transaction to tip", "index", *tx.GetMeta().Index, "hash", tx.Hash().Hex(), "origin", tx.QueueOrigin().String()) 900 901 txs := types.Transactions{tx} 902 errCh := make(chan error, 1) 903 s.txFeed.Send(core.NewTxsEvent{ 904 Txs: txs, 905 ErrCh: errCh, 906 }) 907 // Block until the transaction has been added to the chain 908 log.Trace("Waiting for transaction to be added to chain", "hash", tx.Hash().Hex()) 909 910 select { 911 case err := <-errCh: 912 log.Error("Got error waiting for transaction to be added to chain", "msg", err) 913 s.SetLatestL1Timestamp(ts) 914 s.SetLatestL1BlockNumber(bn) 915 s.SetLatestIndex(index) 916 return err 917 case <-s.chainHeadCh: 918 // Update the cache when the transaction is from the owner 919 // of the gas price oracle 920 sender, _ := types.Sender(s.signer, tx) 921 owner := s.GasPriceOracleOwnerAddress() 922 if owner != nil && sender == *owner { 923 if err := s.updateGasPriceOracleCache(nil); err != nil { 924 s.SetLatestL1Timestamp(ts) 925 s.SetLatestL1BlockNumber(bn) 926 s.SetLatestIndex(index) 927 return err 928 } 929 } 930 return nil 931 } 932 } 933 934 // applyBatchedTransaction applies transactions that were batched to layer one. 935 // The sequencer checks for batches over time to make sure that it does not 936 // deviate from the L1 state and this is the main method of transaction 937 // ingestion for the verifier. 938 func (s *SyncService) applyBatchedTransaction(tx *types.Transaction) error { 939 if tx == nil { 940 return errors.New("nil transaction passed into applyBatchedTransaction") 941 } 942 index := tx.GetMeta().Index 943 if index == nil { 944 return errors.New("No index found on transaction") 945 } 946 log.Trace("Applying batched transaction", "index", *index) 947 err := s.applyIndexedTransaction(tx) 948 if err != nil { 949 return fmt.Errorf("Cannot apply batched transaction: %w", err) 950 } 951 s.SetLatestVerifiedIndex(index) 952 return nil 953 } 954 955 // verifyFee will verify that a valid fee is being paid. 956 func (s *SyncService) verifyFee(tx *types.Transaction) error { 957 fee, err := fees.CalculateTotalFee(tx, s.RollupGpo) 958 if err != nil { 959 return fmt.Errorf("invalid transaction: %w", err) 960 } 961 962 // Prevent transactions without enough balance from 963 // being accepted by the chain but allow through 0 964 // gas price transactions 965 cost := tx.Value() 966 if tx.GasPrice().Cmp(common.Big0) != 0 { 967 cost = cost.Add(cost, fee) 968 } 969 state, err := s.bc.State() 970 if err != nil { 971 return err 972 } 973 from, err := types.Sender(s.signer, tx) 974 if err != nil { 975 return fmt.Errorf("invalid transaction: %w", core.ErrInvalidSender) 976 } 977 if state.GetBalance(from).Cmp(cost) < 0 { 978 return fmt.Errorf("invalid transaction: %w", core.ErrInsufficientFunds) 979 } 980 981 if tx.GasPrice().Cmp(common.Big0) == 0 { 982 // Allow 0 gas price transactions only if it is the owner of the gas 983 // price oracle 984 gpoOwner := s.GasPriceOracleOwnerAddress() 985 if gpoOwner != nil { 986 if from == *gpoOwner { 987 return nil 988 } 989 } 990 // Exit early if fees are enforced and the gasPrice is set to 0 991 if s.enforceFees { 992 return errZeroGasPriceTx 993 } 994 // If fees are not enforced and the gas price is 0, return early 995 return nil 996 } 997 998 // Ensure that the user L2 gas price is high enough 999 l2GasPrice, err := s.RollupGpo.SuggestL2GasPrice(context.Background()) 1000 if err != nil { 1001 return err 1002 } 1003 1004 // Reject user transactions that do not have large enough of a gas price. 1005 // Allow for a buffer in case the gas price changes in between the user 1006 // calling `eth_gasPrice` and submitting the transaction. 1007 opts := fees.PaysEnoughOpts{ 1008 UserGasPrice: tx.GasPrice(), 1009 ExpectedGasPrice: l2GasPrice, 1010 ThresholdUp: s.feeThresholdUp, 1011 ThresholdDown: s.feeThresholdDown, 1012 } 1013 1014 // Check the error type and return the correct error message to the user 1015 if err := fees.PaysEnough(&opts); err != nil { 1016 if errors.Is(err, fees.ErrGasPriceTooLow) { 1017 return fmt.Errorf("%w: %d wei, use at least tx.gasPrice = %s wei", 1018 fees.ErrGasPriceTooLow, tx.GasPrice(), l2GasPrice) 1019 } 1020 if errors.Is(err, fees.ErrGasPriceTooHigh) { 1021 return fmt.Errorf("%w: %d wei, use at most tx.gasPrice = %s wei", 1022 fees.ErrGasPriceTooHigh, tx.GasPrice(), l2GasPrice) 1023 } 1024 return err 1025 } 1026 return nil 1027 } 1028 1029 // Higher level API for applying transactions. Should only be called for 1030 // queue origin sequencer transactions, as the contracts on L1 manage the same 1031 // validity checks that are done here. 1032 func (s *SyncService) ValidateAndApplySequencerTransaction(tx *types.Transaction) error { 1033 if s.verifier { 1034 return errors.New("Verifier does not accept transactions out of band") 1035 } 1036 if tx == nil { 1037 return errors.New("nil transaction passed to ValidateAndApplySequencerTransaction") 1038 } 1039 s.txLock.Lock() 1040 defer s.txLock.Unlock() 1041 if err := s.verifyFee(tx); err != nil { 1042 return err 1043 } 1044 log.Trace("Sequencer transaction validation", "hash", tx.Hash().Hex()) 1045 1046 qo := tx.QueueOrigin() 1047 if qo != types.QueueOriginSequencer { 1048 return fmt.Errorf("invalid transaction with queue origin %s", qo.String()) 1049 } 1050 if err := s.txpool.ValidateTx(tx); err != nil { 1051 return fmt.Errorf("invalid transaction: %w", err) 1052 } 1053 if err := s.applyTransaction(tx); err != nil { 1054 return err 1055 } 1056 return nil 1057 } 1058 1059 // syncer represents a function that can sync remote items and then returns the 1060 // index that it synced to as well as an error if it encountered one. It has 1061 // side effects on the state and its functionality depends on the current state 1062 type syncer func() (*uint64, error) 1063 1064 // rangeSyncer represents a function that syncs a range of items between its two 1065 // arguments (inclusive) 1066 type rangeSyncer func(uint64, uint64) error 1067 1068 // nextGetter is a type that represents a function that will return the next 1069 // index 1070 type nextGetter func() uint64 1071 1072 // indexGetter is a type that represents a function that returns an index and an 1073 // error if there is a problem fetching the index. The different types of 1074 // indices are canonical transaction chain indices, queue indices and batch 1075 // indices. It does not induce side effects on state 1076 type indexGetter func() (*uint64, error) 1077 1078 // isAtTip is a function that will determine if the local chain is at the tip 1079 // of the remote datasource 1080 func (s *SyncService) isAtTip(index *uint64, get indexGetter) (bool, error) { 1081 latest, err := get() 1082 if errors.Is(err, errElementNotFound) { 1083 if index == nil { 1084 return true, nil 1085 } 1086 return false, nil 1087 } 1088 if err != nil { 1089 return false, err 1090 } 1091 // There are no known enqueue transactions locally or remotely 1092 if latest == nil && index == nil { 1093 return true, nil 1094 } 1095 // Only one of the transactions are nil due to the check above so they 1096 // cannot be equal 1097 if latest == nil || index == nil { 1098 return false, nil 1099 } 1100 // The indices are equal 1101 if *latest == *index { 1102 return true, nil 1103 } 1104 // The local tip is greater than the remote tip. This should never happen 1105 if *latest < *index { 1106 return false, fmt.Errorf("is at tip mismatch: remote (%d) - local (%d): %w", *latest, *index, errShortRemoteTip) 1107 } 1108 // The indices are not equal 1109 return false, nil 1110 } 1111 1112 // syncToTip is a function that can be used to sync to the tip of an ordered 1113 // list of things. It is used to sync transactions, enqueue elements and batches 1114 func (s *SyncService) syncToTip(sync syncer, getTip indexGetter) error { 1115 s.loopLock.Lock() 1116 defer s.loopLock.Unlock() 1117 1118 for { 1119 index, err := sync() 1120 if errors.Is(err, errElementNotFound) { 1121 return nil 1122 } 1123 if err != nil { 1124 return err 1125 } 1126 isAtTip, err := s.isAtTip(index, getTip) 1127 if err != nil { 1128 return err 1129 } 1130 if isAtTip { 1131 return nil 1132 } 1133 } 1134 } 1135 1136 // sync will sync a range of items 1137 func (s *SyncService) sync(getLatest indexGetter, getNext nextGetter, syncer rangeSyncer) (*uint64, error) { 1138 latestIndex, err := getLatest() 1139 if err != nil { 1140 return nil, fmt.Errorf("Cannot sync: %w", err) 1141 } 1142 if latestIndex == nil { 1143 return nil, errors.New("Latest index is not defined") 1144 } 1145 1146 nextIndex := getNext() 1147 if nextIndex == *latestIndex+1 { 1148 return latestIndex, nil 1149 } 1150 if err := syncer(nextIndex, *latestIndex); err != nil { 1151 return nil, err 1152 } 1153 return latestIndex, nil 1154 } 1155 1156 // syncBatches will sync a range of batches from the current known tip to the 1157 // remote tip. 1158 func (s *SyncService) syncBatches() (*uint64, error) { 1159 index, err := s.sync(s.client.GetLatestTransactionBatchIndex, s.GetNextBatchIndex, s.syncTransactionBatchRange) 1160 if err != nil { 1161 return nil, fmt.Errorf("Cannot sync batches: %w", err) 1162 } 1163 return index, nil 1164 } 1165 1166 // syncTransactionBatchRange will sync a range of batched transactions from 1167 // start to end (inclusive) 1168 func (s *SyncService) syncTransactionBatchRange(start, end uint64) error { 1169 log.Info("Syncing transaction batch range", "start", start, "end", end) 1170 for i := start; i <= end; i++ { 1171 log.Debug("Fetching transaction batch", "index", i) 1172 _, txs, err := s.client.GetTransactionBatch(i) 1173 if err != nil { 1174 return fmt.Errorf("Cannot get transaction batch: %w", err) 1175 } 1176 for _, tx := range txs { 1177 if err := s.applyBatchedTransaction(tx); err != nil { 1178 return fmt.Errorf("cannot apply batched transaction: %w", err) 1179 } 1180 } 1181 s.SetLatestBatchIndex(&i) 1182 } 1183 return nil 1184 } 1185 1186 // syncQueue will sync from the local tip to the known tip of the remote 1187 // enqueue transaction feed. 1188 func (s *SyncService) syncQueue() (*uint64, error) { 1189 index, err := s.sync(s.client.GetLatestEnqueueIndex, s.GetNextEnqueueIndex, s.syncQueueTransactionRange) 1190 if err != nil { 1191 return nil, fmt.Errorf("Cannot sync queue: %w", err) 1192 } 1193 return index, nil 1194 } 1195 1196 // syncQueueTransactionRange will apply a range of queue transactions from 1197 // start to end (inclusive) 1198 func (s *SyncService) syncQueueTransactionRange(start, end uint64) error { 1199 log.Info("Syncing enqueue transactions range", "start", start, "end", end) 1200 for i := start; i <= end; i++ { 1201 tx, err := s.client.GetEnqueue(i) 1202 if err != nil { 1203 return fmt.Errorf("Canot get enqueue transaction; %w", err) 1204 } 1205 if err := s.applyTransaction(tx); err != nil { 1206 return fmt.Errorf("Cannot apply transaction: %w", err) 1207 } 1208 } 1209 return nil 1210 } 1211 1212 // syncTransactions will sync transactions to the remote tip based on the 1213 // backend 1214 func (s *SyncService) syncTransactions(backend Backend) (*uint64, error) { 1215 getLatest := func() (*uint64, error) { 1216 return s.client.GetLatestTransactionIndex(backend) 1217 } 1218 sync := func(start, end uint64) error { 1219 return s.syncTransactionRange(start, end, backend) 1220 } 1221 index, err := s.sync(getLatest, s.GetNextIndex, sync) 1222 if err != nil { 1223 return nil, fmt.Errorf("Cannot sync transactions with backend %s: %w", backend.String(), err) 1224 } 1225 return index, nil 1226 } 1227 1228 // syncTransactionRange will sync a range of transactions from 1229 // start to end (inclusive) from a specific Backend 1230 func (s *SyncService) syncTransactionRange(start, end uint64, backend Backend) error { 1231 log.Info("Syncing transaction range", "start", start, "end", end, "backend", backend.String()) 1232 for i := start; i <= end; i++ { 1233 tx, err := s.client.GetTransaction(i, backend) 1234 if err != nil { 1235 return fmt.Errorf("cannot fetch transaction %d: %w", i, err) 1236 } 1237 if err := s.applyTransaction(tx); err != nil { 1238 return fmt.Errorf("Cannot apply transaction: %w", err) 1239 } 1240 } 1241 return nil 1242 } 1243 1244 // SubscribeNewTxsEvent registers a subscription of NewTxsEvent and 1245 // starts sending event to the given channel. 1246 func (s *SyncService) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription { 1247 return s.scope.Track(s.txFeed.Subscribe(ch)) 1248 } 1249 1250 func stringify(i *uint64) string { 1251 if i == nil { 1252 return "<nil>" 1253 } 1254 return strconv.FormatUint(*i, 10) 1255 } 1256 1257 // IngestTransaction should only be called by trusted parties as it skips all 1258 // validation and applies the transaction 1259 func (s *SyncService) IngestTransaction(tx *types.Transaction) error { 1260 return s.applyTransaction(tx) 1261 }