Skip to content

Commit 7c841ee

Browse files
authored
Merge pull request #109 from OffchainLabs/4844-only
feat: 4844 implementation
2 parents b2b52d9 + 86b2b09 commit 7c841ee

34 files changed

+2384
-349
lines changed

.github/workflows/contract-tests.yml

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
- name: Install packages
3434
run: yarn
3535

36-
- name: Run unit tests
36+
- name: Build
3737
run: forge test
3838
tests:
3939
name: Contract tests
@@ -44,6 +44,13 @@ jobs:
4444
steps:
4545
- name: Checkout
4646
uses: actions/checkout@v2
47+
with:
48+
submodules: recursive
49+
50+
- name: Install Foundry
51+
uses: foundry-rs/foundry-toolchain@v1
52+
with:
53+
version: nightly
4754

4855
- name: Setup nodejs
4956
uses: actions/setup-node@v2
@@ -67,7 +74,7 @@ jobs:
6774
run: yarn lint:test
6875

6976
- name: Build
70-
run: yarn build
77+
run: yarn build:all
7178

7279
- name: Run tests
7380
run: yarn hardhat --network hardhat test test/contract/*.spec.ts
@@ -91,3 +98,37 @@ jobs:
9198
files: ./contracts/coverage.json
9299
verbose: false
93100
token: ${{ secrets.CODECOV_TOKEN }}
101+
test-4844:
102+
name: 4844 tests
103+
runs-on: ubuntu-latest
104+
steps:
105+
- uses: actions/checkout@v3
106+
with:
107+
submodules: recursive
108+
109+
- name: Install Foundry
110+
uses: foundry-rs/foundry-toolchain@v1
111+
with:
112+
version: nightly
113+
114+
- uses: OffchainLabs/actions/run-nitro-test-node@test-node-args
115+
with:
116+
nitro-testnode-ref: deneb-integration
117+
args: --pos
118+
no-token-bridge: true
119+
120+
- name: Setup nodejs
121+
uses: actions/setup-node@v2
122+
with:
123+
node-version: '18'
124+
cache: 'yarn'
125+
cache-dependency-path: '**/yarn.lock'
126+
127+
- name: Install dependencies
128+
run: yarn install
129+
130+
- name: Build
131+
run: yarn build:all
132+
133+
- name: Test 4844
134+
run: yarn test:4844

.prettierrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = {
1414
printWidth: 100,
1515
singleQuote: false,
1616
bracketSpacing: false,
17-
compiler: '0.8.6',
17+
compiler: '0.8.9',
1818
},
1919
},
2020
],

deploy/SequencerInbox.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ module.exports = async hre => {
33
const { deploy } = deployments
44
const { deployer } = await getNamedAccounts()
55

6+
const blobBasefeeReader = await ethers.getContract('BlobBasefeeReader')
7+
const dataHashReader = await ethers.getContract('DataHashReader')
8+
69
await deploy('SequencerInbox', { from: deployer, args: [117964] })
710
}
811

deploy/SequencerInboxStubCreator.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1+
import { Toolkit4844 } from '../test/contract/toolkit4844'
2+
13
module.exports = async hre => {
2-
const { deployments, getNamedAccounts, ethers } = hre
4+
const { deployments, getSigners, getNamedAccounts, ethers } = hre
35
const { deploy } = deployments
46
const { deployer } = await getNamedAccounts()
57

68
const bridge = await ethers.getContract('BridgeStub')
9+
const reader4844 = await Toolkit4844.deployReader4844(
10+
await ethers.getSigner(deployer)
11+
)
712
const maxTime = {
813
delayBlocks: 10000,
914
futureBlocks: 10000,
@@ -12,7 +17,7 @@ module.exports = async hre => {
1217
}
1318
await deploy('SequencerInboxStub', {
1419
from: deployer,
15-
args: [bridge.address, deployer, maxTime, 117964],
20+
args: [bridge.address, deployer, maxTime, 117964, reader4844.address],
1621
})
1722
}
1823

foundry.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
[profile.default]
2-
src = 'src'
2+
src = 'src/'
33
out = 'out'
44
libs = ['node_modules', 'lib']
55
test = 'test/foundry'
6-
cache_path = 'forge-cache'
6+
cache_path = 'forge-cache/sol'
77
optimizer = true
88
optimizer_runs = 20000
99
via_ir = false
1010
solc_version = '0.8.9'
1111

12+
[profile.yul]
13+
src = 'yul'
14+
out = 'out/yul'
15+
libs = ['node_modules', 'lib']
16+
cache_path = 'forge-cache/yul'
17+
1218
[fmt]
1319
number_underscore = 'thousands'
1420
line_length = 100

hardhat.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import '@typechain/hardhat'
66
import 'solidity-coverage'
77
import 'hardhat-gas-reporter'
88
import 'hardhat-ignore-warnings'
9+
// import '@tovarishfin/hardhat-yul';
910
import dotenv from 'dotenv'
1011

1112
dotenv.config()

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@
1818
},
1919
"scripts": {
2020
"prepublishOnly": "hardhat clean && hardhat compile",
21+
"build:all": "yarn build && yarn build:forge",
2122
"build": "hardhat compile",
23+
"build:forge:sol": "forge build --skip *.yul",
24+
"build:forge:yul": "FOUNDRY_PROFILE=yul forge build --skip *.sol",
25+
"build:forge": "yarn build:forge:sol && yarn build:forge:yul",
2226
"lint:test": "eslint ./test",
2327
"solhint": "solhint -f table src/**/*.sol",
2428
"prettier:solidity": "prettier --write src/**/*.sol",
2529
"format": "prettier './**/*.{js,json,md,ts,yml,sol}' --write && yarn run lint:test --fix",
2630
"build:0.6": "INTERFACE_TESTER_SOLC_VERSION=0.6.9 yarn run build",
2731
"build:0.7": "INTERFACE_TESTER_SOLC_VERSION=0.7.0 yarn run build",
32+
"test": "DISABLE_GAS_REPORTER=true hardhat --network hardhat test test/contract/*.spec.ts",
33+
"test:4844": "DISABLE_GAS_REPORTER=true hardhat --network hardhat test test/contract/*.spec.4844.ts",
2834
"test:compatibility": "yarn run build:0.6 && yarn run build:0.7",
2935
"test:storage": "./test/storage/test.bash",
3036
"test:e2e": "hardhat test test/e2e/*.ts",
@@ -46,6 +52,7 @@
4652
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
4753
"@nomiclabs/hardhat-etherscan": "^3.1.0",
4854
"@nomiclabs/hardhat-waffle": "^2.0.1",
55+
"@tovarishfin/hardhat-yul": "^3.0.5",
4956
"@typechain/ethers-v5": "^10.0.0",
5057
"@typechain/hardhat": "^6.0.0",
5158
"@types/chai": "^4.3.0",

scripts/rollupCreation.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,11 @@ export async function createRollup(feeToken?: string) {
8585
maxDataSize: maxDataSize,
8686
nativeToken: feeToken,
8787
deployFactoriesToL2: true,
88-
maxFeePerGasForRetryables: MAX_FER_PER_GAS
88+
maxFeePerGasForRetryables: MAX_FER_PER_GAS,
8989
}
90-
const createRollupTx = await rollupCreator.createRollup(
91-
deployParams,
92-
{
93-
value: feeCost,
94-
}
95-
96-
)
90+
const createRollupTx = await rollupCreator.createRollup(deployParams, {
91+
value: feeCost,
92+
})
9793
const createRollupReceipt = await createRollupTx.wait()
9894

9995
const rollupCreatedEvent = createRollupReceipt.events?.find(

src/bridge/IBridge.sol

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ pragma solidity >=0.6.9 <0.9.0;
88
import "./IOwnable.sol";
99

1010
interface IBridge {
11+
/// @dev This is an instruction to offchain readers to inform them where to look
12+
/// for sequencer inbox batch data. This is not the type of data (eg. das, brotli encoded, or blob versioned hash)
13+
/// and this enum is not used in the state transition function, rather it informs an offchain
14+
/// reader where to find the data so that they can supply it to the replay binary
15+
enum BatchDataLocation {
16+
/// @notice The data can be found in the transaction call data
17+
TxInput,
18+
/// @notice The data can be found in an event emitted during the transaction
19+
SeparateBatchEvent,
20+
/// @notice This batch contains no data
21+
NoData,
22+
/// @notice The data can be found in the 4844 data blobs on this transaction
23+
Blob
24+
}
25+
26+
struct TimeBounds {
27+
uint64 minTimestamp;
28+
uint64 maxTimestamp;
29+
uint64 minBlockNumber;
30+
uint64 maxBlockNumber;
31+
}
32+
1133
event MessageDelivered(
1234
uint256 indexed messageIndex,
1335
bytes32 indexed beforeInboxAcc,

src/bridge/ISequencerInbox.sol

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,10 @@ import "./IBridge.sol";
1212

1313
interface ISequencerInbox is IDelayedMessageProvider {
1414
struct MaxTimeVariation {
15-
uint256 delayBlocks;
16-
uint256 futureBlocks;
17-
uint256 delaySeconds;
18-
uint256 futureSeconds;
19-
}
20-
21-
struct TimeBounds {
22-
uint64 minTimestamp;
23-
uint64 maxTimestamp;
24-
uint64 minBlockNumber;
25-
uint64 maxBlockNumber;
26-
}
27-
28-
enum BatchDataLocation {
29-
TxInput,
30-
SeparateBatchEvent,
31-
NoData
15+
uint64 delayBlocks;
16+
uint64 futureBlocks;
17+
uint64 delaySeconds;
18+
uint64 futureSeconds;
3219
}
3320

3421
event SequencerBatchDelivered(
@@ -37,8 +24,8 @@ interface ISequencerInbox is IDelayedMessageProvider {
3724
bytes32 indexed afterAcc,
3825
bytes32 delayedAcc,
3926
uint256 afterDelayedMessagesRead,
40-
TimeBounds timeBounds,
41-
BatchDataLocation dataLocation
27+
IBridge.TimeBounds timeBounds,
28+
IBridge.BatchDataLocation dataLocation
4229
);
4330

4431
event OwnerFunctionCalled(uint256 indexed id);
@@ -61,10 +48,41 @@ interface ISequencerInbox is IDelayedMessageProvider {
6148
function HEADER_LENGTH() external view returns (uint256);
6249

6350
/// @dev If the first batch data byte after the header has this bit set,
64-
/// the sequencer inbox has authenticated the data. Currently not used.
51+
/// the sequencer inbox has authenticated the data. Currently only used for 4844 blob support.
52+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
6553
// solhint-disable-next-line func-name-mixedcase
6654
function DATA_AUTHENTICATED_FLAG() external view returns (bytes1);
6755

56+
/// @dev If the first data byte after the header has this bit set,
57+
/// then the batch data is to be found in 4844 data blobs
58+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
59+
// solhint-disable-next-line func-name-mixedcase
60+
function DATA_BLOB_HEADER_FLAG() external view returns (bytes1);
61+
62+
/// @dev If the first data byte after the header has this bit set,
63+
/// then the batch data is a das message
64+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
65+
// solhint-disable-next-line func-name-mixedcase
66+
function DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);
67+
68+
/// @dev If the first data byte after the header has this bit set,
69+
/// then the batch data is a das message that employs a merklesization strategy
70+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
71+
// solhint-disable-next-line func-name-mixedcase
72+
function TREE_DAS_MESSAGE_HEADER_FLAG() external view returns (bytes1);
73+
74+
/// @dev If the first data byte after the header has this bit set,
75+
/// then the batch data has been brotli compressed
76+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
77+
// solhint-disable-next-line func-name-mixedcase
78+
function BROTLI_MESSAGE_HEADER_FLAG() external view returns (bytes1);
79+
80+
/// @dev If the first data byte after the header has this bit set,
81+
/// then the batch data uses a zero heavy encoding
82+
/// See: https://github.com/OffchainLabs/nitro/blob/69de0603abf6f900a4128cab7933df60cad54ded/arbstate/das_reader.go
83+
// solhint-disable-next-line func-name-mixedcase
84+
function ZERO_HEAVY_MESSAGE_HEADER_FLAG() external view returns (bytes1);
85+
6886
function rollup() external view returns (IOwnable);
6987

7088
function isBatchPoster(address) external view returns (bool);
@@ -78,14 +96,15 @@ interface ISequencerInbox is IDelayedMessageProvider {
7896
uint64 creationBlock;
7997
}
8098

99+
/// @dev returns 4 uint256 to be compatible with older version
81100
function maxTimeVariation()
82101
external
83102
view
84103
returns (
85-
uint256,
86-
uint256,
87-
uint256,
88-
uint256
104+
uint256 delayBlocks,
105+
uint256 futureBlocks,
106+
uint256 delaySeconds,
107+
uint256 futureSeconds
89108
);
90109

91110
function dasKeySetInfo(bytes32) external view returns (bool, uint64);
@@ -130,6 +149,15 @@ interface ISequencerInbox is IDelayedMessageProvider {
130149
IGasRefunder gasRefunder
131150
) external;
132151

152+
function addSequencerL2BatchFromOrigin(
153+
uint256 sequenceNumber,
154+
bytes calldata data,
155+
uint256 afterDelayedMessagesRead,
156+
IGasRefunder gasRefunder,
157+
uint256 prevMessageCount,
158+
uint256 newMessageCount
159+
) external;
160+
133161
function addSequencerL2Batch(
134162
uint256 sequenceNumber,
135163
bytes calldata data,
@@ -139,6 +167,14 @@ interface ISequencerInbox is IDelayedMessageProvider {
139167
uint256 newMessageCount
140168
) external;
141169

170+
function addSequencerL2BatchFromBlobs(
171+
uint256 sequenceNumber,
172+
uint256 afterDelayedMessagesRead,
173+
IGasRefunder gasRefunder,
174+
uint256 prevMessageCount,
175+
uint256 newMessageCount
176+
) external;
177+
142178
// ---------- onlyRollupOrOwner functions ----------
143179

144180
/**

0 commit comments

Comments
 (0)