Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sequencer inbox optimization #110

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module.exports = {
printWidth: 100,
singleQuote: false,
bracketSpacing: false,
compiler: '0.8.6',
compiler: '0.8.9',
},
},
],
Expand Down
24 changes: 13 additions & 11 deletions LICENSE → LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ Additional Use Grant: You may use the Licensed Work in a production environment
to provide a point of interface to permit end users or applications
utilizing the Covered Arbitrum Chains to interact and query the
state of a Covered Arbitrum Chain, including without limitation
validating the correctness of the posted chain state. For purposes
of this Additional Use Grant, the "Covered Arbitrum Chains" are
means (a) Arbitrum One (chainid:42161), Arbitrum Nova (chainid:42170),
Arbitrum Rinkeby testnet/Rinkarby (chainid:421611), and
Arbitrum Nitro Goerli testnet (chainid:421613) (b) any future
blockchains authorized to be designated as Covered Arbitrum Chains
by the decentralized autonomous organization governing the Arbitrum
network; and (c) any “Layer 3” Arbitrum-based blockchain that is built
on and settles to another Covered Arbitrum Chain.


validating the correctness of the posted chain state, or to deploy
and operate (x) a blockchain that settles to a Covered Arbitrum Chain
or (y) a blockchain in accordance with, and subject to, the [Arbitrum
Expansion Program Term of Use](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf). For purposes of this
Additional Use Grant, the "Covered Arbitrum Chains" are
(a) Arbitrum One (chainid:42161), Arbitrum Nova (chainid:42170),
rbitrum Rinkeby testnet/Rinkarby (chainid:421611),Arbitrum Nitro
Goerli testnet (chainid:421613), and Arbitrum Sepolia Testnet
(chainid:421614); (b) any future blockchains authorized to be
designated as Covered Arbitrum Chains by the decentralized autonomous
organization governing the Arbitrum network; and (c) any “Layer 3”
Arbitrum-based blockchain that is built on and settles to another
Covered Arbitrum Chain.



Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,19 @@ cd nitro-contracts
yarn install
yarn build
```

## License

Nitro is currently licensed under a [Business Source License](./LICENSE), similar to our friends at Uniswap and Aave, with an "Additional Use Grant" to ensure that everyone can have full comfort using and running nodes on all public Arbitrum chains.

The Additional Use Grant also permits the deployment of the Nitro software, in a permissionless fashion and without cost, as a new blockchain provided that the chain settles to either Arbitrum One or Arbitrum Nova.

For those that prefer to deploy the Nitro software either directly on Ethereum (i.e. an L2) or have it settle to another Layer-2 on top of Ethereum, the [Arbitrum Expansion Program (the "AEP")](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf) was recently established. The AEP allows for the permissionless deployment in the aforementioned fashion provided that 10% of net revenue is contributed back to the Arbitrum community in accordance with the requirements of the AEP.

## Contact

Discord - [Arbitrum](https://discord.com/invite/5KE54JwyTs)

Twitter: [Arbitrum](https://twitter.com/arbitrum)


2 changes: 1 addition & 1 deletion deploy/BridgeStubCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module.exports = async hre => {
const { deploy } = deployments
const { deployer } = await getNamedAccounts()

await deploy('BridgeStub', { from: deployer, args: [] })
await deploy('BridgeStub', { from: deployer, args: [deployer] })
}

module.exports.tags = ['BridgeStub', 'test']
Expand Down
13 changes: 8 additions & 5 deletions deploy/SequencerInboxStubCreator.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Toolkit4844 } from '../test/contract/toolkit4844'

module.exports = async hre => {
const { deployments, getNamedAccounts, ethers } = hre
const { deployments, getSigners, getNamedAccounts, ethers } = hre
const { deploy } = deployments
const { deployer } = await getNamedAccounts()

const bridge = await ethers.getContract('BridgeStub')
const blobBasefeeReader = await ethers.getContract('BlobBasefeeReader')
const dataHashReader = await ethers.getContract('DataHashReader')
const reader4844 = await Toolkit4844.deployReader4844(
await ethers.getSigner(deployer)
)
const maxTime = {
delayBlocks: 10000,
futureBlocks: 10000,
Expand All @@ -19,8 +22,8 @@ module.exports = async hre => {
deployer,
maxTime,
117964,
dataHashReader,
blobBasefeeReader,
reader4844.address,
false,
],
})
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"build:all": "yarn build && yarn build:forge",
"build": "hardhat compile",
"build:forge:sol": "forge build --skip *.yul",
"build:forge:yul": "FOUNDRY_PROFILE=yul forge build --skip *.sol --skip *BlobBasefeeReader.yul && FOUNDRY_PROFILE=yul forge build --skip *.sol --skip *DataHashesReader.yul",
"build:forge:yul": "FOUNDRY_PROFILE=yul forge build --skip *.sol",
"build:forge": "yarn build:forge:sol && yarn build:forge:yul",
"lint:test": "eslint ./test",
"solhint": "solhint -f table src/**/*.sol",
Expand All @@ -36,6 +36,7 @@
"test:e2e": "hardhat test test/e2e/*.ts",
"postinstall": "patch-package",
"deploy-factory": "hardhat run scripts/deployment.ts",
"deploy-rollup": "hardhat run scripts/rollupCreation.ts",
"deploy-eth-rollup": "hardhat run scripts/createEthRollup.ts",
"deploy-erc20-rollup": "hardhat run scripts/createERC20Rollup.ts"
},
Expand Down
8 changes: 4 additions & 4 deletions scripts/config.ts.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export const config = {
'{"chainId":13331370,"homesteadBlock":0,"daoForkBlock":null,"daoForkSupport":true,"eip150Block":0,"eip150Hash":"0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"clique":{"period":0,"epoch":0},"arbitrum":{"EnableArbOS":true,"AllowDebugPrecompiles":false,"DataAvailabilityCommittee":false,"InitialArbOSVersion":10,"InitialChainOwner":"0x1234123412341234123412341234123412341234","GenesisBlockNum":0}}',
genesisBlockNum: ethers.BigNumber.from('0'),
sequencerInboxMaxTimeVariation: {
delayBlocks: ethers.BigNumber.from('5760'),
futureBlocks: ethers.BigNumber.from('12'),
delaySeconds: ethers.BigNumber.from('86400'),
futureSeconds: ethers.BigNumber.from('3600'),
delayBlocks: 5760,
futureBlocks: 12,
delaySeconds: 86400,
futureSeconds: 3600,
},
},
validators: [
Expand Down
6 changes: 5 additions & 1 deletion scripts/deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ async function deployAllContracts(
const ethBridge = await deployContract('Bridge', signer, [])
const ethSequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
false,
])
const ethInbox = await deployContract('Inbox', signer, [maxDataSize])
const ethRollupEventInbox = await deployContract(
Expand All @@ -91,7 +92,10 @@ async function deployAllContracts(
const ethOutbox = await deployContract('Outbox', signer, [])

const erc20Bridge = await deployContract('ERC20Bridge', signer, [])
const erc20SequencerInbox = ethSequencerInbox
const erc20SequencerInbox = await deployContract('SequencerInbox', signer, [
maxDataSize,
true,
])
const erc20Inbox = await deployContract('ERC20Inbox', signer, [maxDataSize])
const erc20RollupEventInbox = await deployContract(
'ERC20RollupEventInbox',
Expand Down
2 changes: 2 additions & 0 deletions scripts/testSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const getCustomNetworks = async (
`docker exec ${sequencerContainer} cat /config/deployment.json`
).toString()

console.log('deploymentData', deploymentData)

const parsedDeploymentData = JSON.parse(deploymentData) as {
bridge: string
inbox: string
Expand Down
34 changes: 31 additions & 3 deletions src/bridge/AbsBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ import {
NotSequencerInbox,
NotOutbox,
InvalidOutboxSet,
BadSequencerMessageNumber
BadSequencerMessageNumber,
EmptyDelayedMessagesRead,
DelayedBackwards,
DelayedTooFar
} from "../libraries/Error.sol";
import "./IBridge.sol";
import "./Messages.sol";
import "../libraries/DelegateCallAware.sol";
import "./ISequencerInbox.sol";

import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol";

Expand Down Expand Up @@ -55,8 +59,15 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {

uint256 public override sequencerReportedSubMessageCount;

uint256 public totalDelayedMessagesRead;

address internal constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);

function postUpgradeInit() external onlyDelegated onlyProxyOwner {
totalDelayedMessagesRead = ISequencerInbox(sequencerInbox).totalDelayedMessagesRead();
if (totalDelayedMessagesRead == 0) revert EmptyDelayedMessagesRead();
}

modifier onlyRollupOrOwner() {
if (msg.sender != address(rollup)) {
address rollupOwner = rollup.owner();
Expand Down Expand Up @@ -101,7 +112,9 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {
bytes32 dataHash,
uint256 afterDelayedMessagesRead,
uint256 prevMessageCount,
uint256 newMessageCount
uint256 newMessageCount,
TimeBounds memory timeBounds,
BatchDataLocation batchDataLocation
)
external
onlySequencerInbox
Expand All @@ -119,6 +132,9 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {
) {
revert BadSequencerMessageNumber(sequencerReportedSubMessageCount, prevMessageCount);
}
if (afterDelayedMessagesRead > delayedInboxAccs.length) revert DelayedTooFar();
if (afterDelayedMessagesRead < totalDelayedMessagesRead) revert DelayedBackwards();

sequencerReportedSubMessageCount = newMessageCount;
seqMessageIndex = sequencerInboxAccs.length;
if (sequencerInboxAccs.length > 0) {
Expand All @@ -129,6 +145,18 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {
}
acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc));
sequencerInboxAccs.push(acc);
totalDelayedMessagesRead = afterDelayedMessagesRead;

emit SequencerBatchDelivered(
seqMessageIndex,
beforeAcc,
acc,
delayedAcc,
afterDelayedMessagesRead,
timeBounds,
batchDataLocation,
msg.sender
);
}

/// @inheritdoc IBridge
Expand Down Expand Up @@ -304,5 +332,5 @@ abstract contract AbsBridge is Initializable, DelegateCallAware, IBridge {
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[40] private __gap;
uint256[39] private __gap;
}
1 change: 1 addition & 0 deletions src/bridge/AbsOutbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ abstract contract AbsOutbox is DelegateCallAware, IOutbox {
});
bridge = _bridge;
rollup = address(_bridge.rollup());
if (address(rollup) == address(0)) revert RollupNotChanged();
}

function postUpgradeInit() external onlyDelegated onlyProxyOwner {
Expand Down
18 changes: 17 additions & 1 deletion src/bridge/IBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

// solhint-disable-next-line compiler-version
pragma solidity >=0.6.9 <0.9.0;
pragma experimental ABIEncoderV2;

import "./IOwnable.sol";

Expand Down Expand Up @@ -48,6 +49,17 @@ interface IBridge {
bytes data
);

event SequencerBatchDelivered(
uint256 indexed batchSequenceNumber,
bytes32 indexed beforeAcc,
bytes32 indexed afterAcc,
bytes32 delayedAcc,
uint256 afterDelayedMessagesRead,
TimeBounds timeBounds,
BatchDataLocation dataLocation,
address sequencerInbox
);

event InboxToggle(address indexed inbox, bool enabled);

event OutboxToggle(address indexed outbox, bool enabled);
Expand Down Expand Up @@ -88,13 +100,17 @@ interface IBridge {

function sequencerMessageCount() external view returns (uint256);

function totalDelayedMessagesRead() external view returns (uint256);

// ---------- onlySequencerInbox functions ----------

function enqueueSequencerMessage(
bytes32 dataHash,
uint256 afterDelayedMessagesRead,
uint256 prevMessageCount,
uint256 newMessageCount
uint256 newMessageCount,
TimeBounds memory timeBounds,
BatchDataLocation dataLocation
)
external
returns (
Expand Down
Loading
Loading