Search
Optimistic rollup protocols move all execution off the layer 1 (L1) Ethereum chain, complete execution on a layer 2 (L2) chain, and return the results of the L2 execution back to the L1. These protocols have a sequencer that executes and rolls up the L2 transactions by batching multiple transactions into a single transaction.
If a sequencer becomes unavailable, it is impossible to access read/write APIs that consumers are using and applications on the L2 network will be down for most users without interacting directly through the L1 optimistic rollup contracts. The L2 has not stopped, but it would be unfair to continue providing service on your applications when only a few users can use them.
To help your applications identify when the sequencer is unavailable, you can use a data feed that tracks the last known status of the sequencer at a given point in time. This is to allow customers to prevent mass liquidations by providing a grace period to allow customers to react to such an event.
L2 sequencer feeds are available on the following networks:
L2 sequencer uptime feeds are architected similar to other Chainlink feeds. The diagram below shows how these feeds update and how a consumer retrieves the status of the Arbitrum sequencer.
validate
function in the ArbitrumValidator
contract by calling it through the ValidatorProxy
contract.ArbitrumValidator
checks to see if the latest update is different from the previous update. If it detects a difference, it places a message in the Arbitrum inbox contract.ArbitrumSequencerUptimeFeed
contract. The message calls the updateStatus
function in the ArbitrumSequencerUptimeFeed
contract and updates the latest sequencer status to 0 if the sequencer is up and 1 if it is down. It also records the block timestamp to indicate when the message was sent from the L1 network.ArbitrumSequencerUptimeFeed
contract.If the Arbitrum network becomes unavailable, the ArbitrumValidator
contract continues to send messages to the L2 network through the delayed inbox on L1. This message stays there until the sequencer is back up again. When the sequencer comes back online after downtime, it processes all transactions from the delayed inbox before it accepts new transactions. The message that signals when the sequencer is down will be processed before any new messages with transactions that require the sequencer to be operational.
Create your consumer contract for uptime feeds similarly to contracts you would use for other Chainlink data feeds. You will need the following items:
AggregatorV2V3Interface.sol
contract: Use this interface to create a flagsFeed
object that points to the sequencer feed proxy.You can use the sequencer uptime feed on Arbitrum, but this example uses an Ethereum Rinkeby testnet feed for development and testing purposes.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol";
/**
* Find information on LINK Token Contracts here: https://docs.chain.link/docs/link-token-contracts/
*/
contract ArbitrumPriceConsumer {
// Identifier of the Sequencer offline flag on the Flags contract
AggregatorV2V3Interface internal priceFeed;
AggregatorV2V3Interface internal sequencerUptimeFeed;
/**
* Network: Rinkeby
* Data Feed: BTC/USD
* Data Feed Proxy Address: 0x2431452A0010a43878bF198e170F6319Af6d27F4
* Sequencer Uptime Proxy Address: 0x13E99C19833F557672B67C70508061A2E1e54162
* For a list of available sequencer proxy addresses, see:
* https://docs.chain.link/docs/l2-sequencer-flag/
*/
constructor() {
priceFeed = AggregatorV2V3Interface(0x2431452A0010a43878bF198e170F6319Af6d27F4);
sequencerUptimeFeed = AggregatorV2V3Interface(0x13E99C19833F557672B67C70508061A2E1e54162);
}
/**
* Returns the latest price
*/
function getLatestPrice() public view returns (int) {
if (checkSequencerState()) {
// If the sequencer is down, do not perform any critical operations
revert("L2 sequencer down: Chainlink feeds are not being updated");
}
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) = priceFeed.latestRoundData();
return price;
}
/**
* Check if the L2 sequencer is running
*/
function checkSequencerState() public view returns (bool sequencerIsUp) {
(
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
) = sequencerUptimeFeed.latestRoundData();
// Answer == 0: Sequencer is up
// Snswer == 1: Sequencer is down
if (answer == 0 && (block.timestamp - updatedAt) < 3600) {
return true;
}
return false;
}
}
This example includes a modified getLatestPrice
function that reverts if checkSequencerState
returns false. The checkSequencerState
function reads the answer from the sequencer uptime feed and returns either a 1
or a 0
.
The updatedAt
timestamp is the block timestamp when the answer updated on the L1 network, Ethereum Mainnet. Use this to ensure the latest answer is recent enough to be trustworthy.
You can find proxy addresses for the L2 sequencer feeds on the following networks: