Skip to content

Commit 2202813

Browse files
authored
Merge pull request #143 from OffchainLabs/feat/add-env-script
feat: add env-script
2 parents 7314f49 + 5ba44cb commit 2202813

8 files changed

Lines changed: 256 additions & 84 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ From root directory:
1212
yarn install
1313
```
1414

15+
## Environment Setup
16+
17+
To simplify providing environment variables across all tutorials, a helper script automates creating `.env` files from each existing `.env-sample`.
18+
19+
```bash
20+
yarn setup-envs
21+
22+
# To update existing .env files as well
23+
yarn setup-envs --update
24+
```
25+
1526
## Testing
1627

1728
1. Start the nitro-testnode (you can find instructions [here](https://docs.arbitrum.io/run-arbitrum-node/run-local-full-chain-simulation)) with the following parameters:
@@ -26,6 +37,10 @@ yarn install
2637
yarn run testAll
2738
```
2839

40+
### Notes on RPCs and Finality
41+
42+
Using public testnet RPCs can be slow because many tutorials wait for transaction finality or multiple confirmations. Some tests may take 10–15 minutes to complete on testnets. For faster and more reliable execution, prefer running a local node and pointing your environment variables (`CHAIN_RPC`, `PARENT_CHAIN_RPC`, and `L1_RPC` when applicable) to local RPC endpoints.
43+
2944
## What's included?
3045

3146
#### :white_check_mark: Basics

customNetwork.json

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
"chainID": 412346,
44
"confirmPeriodBlocks": 20,
55
"ethBridge": {
6-
"bridge": "0x5eCF728ffC5C5E802091875f96281B5aeECf6C49",
7-
"inbox": "0x9f8c1c641336A371031499e3c362e40d58d0f254",
8-
"outbox": "0x50143333b44Ea46255BEb67255C9Afd35551072F",
9-
"rollup": "0xe5Ab92C74CD297F0a1F2914cE37204FC5Bc4e82D",
10-
"sequencerInbox": "0x18d19C5d3E685f5be5b9C86E097f0E439285D216"
6+
"bridge": "0xd21d0cA137A64165E3C3702a37C5D42E6a5CdACC",
7+
"inbox": "0xF52c6E85A9E6287942fD913DfCc269EB571816a6",
8+
"outbox": "0xbf2265Cd6Fd551e5EAA862Fd81BA317D585eE693",
9+
"rollup": "0x1b172F52EC0EFFeeC7946903F20410B5d6571AA0",
10+
"sequencerInbox": "0x7F6958d308593dC0BdEa73c4bcD742965E1C79af"
1111
},
1212
"explorerUrl": "",
1313
"isArbitrum": true,
@@ -19,17 +19,17 @@
1919
"nitroGenesisL1Block": 0,
2020
"depositTimeout": 900000,
2121
"tokenBridge": {
22-
"parentGatewayRouter": "0x093AAa96CD4387A68FC0e24C60140938Dc812549",
22+
"parentGatewayRouter": "0x145899e2EF2A3f460Cfb2F7897615F5758000F66",
2323
"childGatewayRouter": "0x32656396981868E925280FB772b3f806892cf4bF",
24-
"parentErc20Gateway": "0x00D9fE1a2B67B8151aEdE8855c95E58D73FB4245",
24+
"parentErc20Gateway": "0x4D9Aa26aCee73293ba84fB1FcA8100006239860E",
2525
"childErc20Gateway": "0x7424e3DAAAAcd867c85ceB75c1E00119F2ee5eb7",
26-
"parentCustomGateway": "0x8407E6180dC009D20D26D4BABB4790C1d4E6D2aA",
26+
"parentCustomGateway": "0xC9ba2864E0E5dC3B78a539fA5e50b4508595A236",
2727
"childCustomGateway": "0x0B35cfE62314C3852A0942b5830c728353BD654F",
28-
"parentWethGateway": "0xB8F48Ba39fCfB44d70F6008fe1bf4F3E744044AF",
28+
"parentWethGateway": "0xCb24A87c3Dfc5b6DC8f1Da8D62D731fA1109A32C",
2929
"childWethGateway": "0x67aE8014BD1A0c1Ed747715d22b3b3a188aC324B",
3030
"parentWeth": "0x7E32b54800705876d3b5cFbc7d9c226a211F7C1a",
3131
"childWeth": "0xA1abD387192e3bb4e84D3109181F9f005aBaF5CA",
32-
"parentProxyAdmin": "0x2A1f38c9097e7883570e0b02BFBE6869Cc25d8a3",
32+
"parentProxyAdmin": "0x275FC51309e5928Cb085b463ADEF5cbD45c76b62",
3333
"childProxyAdmin": "0x9F95547ABB0FfC92b4E37b3124d1e8613d5aB74A",
3434
"parentMultiCall": "0x49117fC32930E324F2E9A7BeA588FFb26008b8eC",
3535
"childMultiCall": "0x6B1E93aE298B64e8f5b9f43B65Dd8F1eaA6DD4c3"
@@ -41,11 +41,11 @@
4141
"chainID": 333333,
4242
"confirmPeriodBlocks": 20,
4343
"ethBridge": {
44-
"bridge": "0xA584795e24628D9c067A6480b033C9E96281fcA3",
45-
"inbox": "0xDcA690902d3154886Ec259308258D10EA5450996",
46-
"outbox": "0xda243bD61B011024FC923164db75Dde198AC6175",
47-
"rollup": "0x47b238E195b638b8972Cb3649e5d6775c279245d",
48-
"sequencerInbox": "0x16c54EE2015CD824415c2077F4103f444E00A8cb"
44+
"bridge": "0xFbd865f29BadF3fdcf14b7e742F78c8DdF7fa4C9",
45+
"inbox": "0x7CB5a1892d31936a13CeE3a4A8183Ed40300e87c",
46+
"outbox": "0x3dAEcE87269310A2f055920ef5C84679ca50F218",
47+
"rollup": "0x9129f7A7f4D5A87F971Fe15C554AD1CF22ceb4EF",
48+
"sequencerInbox": "0x99c807B58c00DE2b068e521AAC227A1e8ADe1fa9"
4949
},
5050
"explorerUrl": "",
5151
"isArbitrum": true,
@@ -57,17 +57,17 @@
5757
"nitroGenesisL1Block": 0,
5858
"depositTimeout": 900000,
5959
"tokenBridge": {
60-
"parentGatewayRouter": "0xfE03DBdf7A126994dBd749631D7fbaB58C618c58",
60+
"parentGatewayRouter": "0x9a6E8E638451781B47b8632a11E56020270A335B",
6161
"childGatewayRouter": "0x8B6BC759226f8Fe687c8aD8Cc0DbF85E095e9297",
62-
"parentErc20Gateway": "0x6B0805Fc6e275ef66a0901D0CE68805631E271e5",
62+
"parentErc20Gateway": "0x7A6b9Ca6e4f87E6a641c1AbD7671aD42bF538977",
6363
"childErc20Gateway": "0xaa7d51aFFEeB32d99b1CB2fd6d81D7adA4a896e8",
64-
"parentCustomGateway": "0xA191D519260A06b32f8D04c84b9F457B8Caa0514",
64+
"parentCustomGateway": "0xDCa39C8Fbd686cb8838106Ed94C0B9e9802697d6",
6565
"childCustomGateway": "0xD4816AeF8f85A3C1E01Cd071a81daD4fa941625f",
66-
"parentWethGateway": "0x77603b0ea6a797C74Fa9ef11b5BdE04A4E03D550",
66+
"parentWethGateway": "0x3bF927fc03d13bD2199b02a029ABb490D13706b3",
6767
"childWethGateway": "0xA6AB233B3c7bfd0399834897b5073974A3D467e2",
6868
"parentWeth": "0xA1abD387192e3bb4e84D3109181F9f005aBaF5CA",
6969
"childWeth": "0x582a8dBc77f665dF2c49Ce0a138978e9267dd968",
70-
"parentProxyAdmin": "0x1A61102c26ad3f64bA715B444C93388491fd8E68",
70+
"parentProxyAdmin": "0x74513d47D265527f0647eD5B90072578c609B378",
7171
"childProxyAdmin": "0x36C56eC2CF3a3f53db9F01d0A5Ae84b36fb0A1e2",
7272
"parentMultiCall": "0x20a3627Dcc53756E38aE3F92717DE9B23617b422",
7373
"childMultiCall": "0x052B15c8Ff0544287AE689C4F2FC53A3905d7Db3"

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"lint": "eslint .",
1515
"prettier:format": "prettier './**/*.{js,json,md,sol,ts,yml}' --write && yarn run lint --fix",
1616
"prettier:check": "prettier './**/*.{js,json,md,sol,ts,yml}' --check && yarn run lint",
17-
"testAll": "tests/runAll.sh"
17+
"testAll": "tests/runAll.sh",
18+
"setup-envs": "node scripts/setup-envs.js"
1819
},
1920
"devDependencies": {
2021
"@offchainlabs/eslint-config-typescript": "^0.2.1",

packages/arb-shared-dependencies/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,21 @@ const requireEnvVariables = (envVars) => {
5353
console.log('Environmental variables properly set 👍');
5454
};
5555

56-
const addCustomNetworkFromFile = () => {
56+
const addCustomNetworkFromFile = (registerFn) => {
5757
const pathToCustomNetworkFile = path.join(__dirname, '..', '..', 'customNetwork.json');
5858
if (!fs.existsSync(pathToCustomNetworkFile)) {
5959
return;
6060
}
6161

62+
// Use the provided register function, or fall back to the local one
63+
const register = registerFn || registerCustomArbitrumNetwork;
64+
6265
const customNetworkFileContents = fs.readFileSync(pathToCustomNetworkFile, 'utf8');
6366
const customNetworkInformation = JSON.parse(customNetworkFileContents);
6467
if (customNetworkInformation instanceof Array) {
65-
customNetworkInformation.map((customNetwork) => registerCustomArbitrumNetwork(customNetwork));
68+
customNetworkInformation.map((customNetwork) => register(customNetwork));
6669
} else {
67-
registerCustomArbitrumNetwork(customNetworkInformation);
70+
register(customNetworkInformation);
6871
}
6972
};
7073

packages/block-verification-in-parent-chain-assertion/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Block verification in an assertion posted on the parent chain
22

3-
This tutorial shows how to verify whether a block of a chain has been processed as part of an RBlock assertion on its parent chain.
3+
This tutorial shows how to verify whether a block of a chain has been processed as part of an assertion on its parent chain.
44

5-
It uses the `Rollup` contract to find the latest confirmed (or created if configured in the script) RBlock/node, find the event that created it, and get the latest processed block hash of the child chain that's part of the assertion of that RBlock/node.
5+
It uses the `Rollup` contract to find the latest confirmed assertion hash, find the `AssertionCreated` event that created it, and get the latest processed block hash of the child chain that's part of that assertion's `afterState`.
66

77
Then it checks whether the block number passed as argument was created before the latest block hash of the child chain processed.
88

9-
See [./exec.js](./scripts/exec.js) for inline explanations.
9+
See [./exec.ts](./scripts/exec.ts) for inline explanations.
1010

1111
## Set environment variables
1212

packages/block-verification-in-parent-chain-assertion/scripts/exec.ts

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { providers, Contract } from 'ethers';
2-
import { getArbitrumNetwork } from '@arbitrum/sdk';
3-
import { RollupCore__factory } from '@arbitrum/sdk/dist/lib/abi/factories/RollupCore__factory';
2+
import { getArbitrumNetwork, registerCustomArbitrumNetwork } from '@arbitrum/sdk';
3+
import { BoldRollupUserLogic__factory } from '@arbitrum/sdk/dist/lib/abi-bold/factories/BoldRollupUserLogic__factory';
44
import { arbLog, requireEnvVariables, addCustomNetworkFromFile } from 'arb-shared-dependencies';
55
require('dotenv').config();
66
requireEnvVariables(['CHAIN_RPC', 'PARENT_CHAIN_RPC']);
@@ -11,93 +11,64 @@ requireEnvVariables(['CHAIN_RPC', 'PARENT_CHAIN_RPC']);
1111
const parentChainProvider = new providers.JsonRpcProvider(process.env.PARENT_CHAIN_RPC);
1212
const childChainProvider = new providers.JsonRpcProvider(process.env.CHAIN_RPC);
1313

14-
/**
15-
* Use the latest node created instead of the last confirmed one
16-
*/
17-
const useCreatedNodeInsteadOfConfirmed = false;
18-
1914
const main = async (childChainBlockNumberToVerify: number) => {
2015
await arbLog(
2116
'Find whether a block of the child chain has been processed as part of an RBlock on the parent chain',
2217
);
2318

24-
/**
25-
* Add the custom network configuration to the SDK if present
26-
*/
27-
addCustomNetworkFromFile();
19+
addCustomNetworkFromFile(registerCustomArbitrumNetwork);
2820

29-
/**
30-
* Use childChainNetwork to find the Rollup contract's address and instantiate a contract handler
31-
*/
3221
const childChainNetwork = await getArbitrumNetwork(childChainProvider);
3322
const rollupAddress = childChainNetwork.ethBridge.rollup;
34-
const rollup = new Contract(rollupAddress, RollupCore__factory.abi, parentChainProvider);
23+
const rollup = new Contract(rollupAddress, BoldRollupUserLogic__factory.abi, parentChainProvider);
3524
console.log(`Rollup contract found at address ${rollup.address}`);
3625

37-
/**
38-
* Get the latest node created or confirmed
39-
*/
40-
const nodeId = useCreatedNodeInsteadOfConfirmed
41-
? await rollup.latestNodeCreated()
42-
: await rollup.latestConfirmed();
43-
console.log(
44-
`Latest ${useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'} Rblock/node: ${nodeId}`,
45-
);
26+
const assertionHash: string = await rollup.latestConfirmed();
27+
console.log(`Latest confirmed assertion hash: ${assertionHash}`);
4628

47-
/**
48-
* Find the NodeCreated event
49-
*/
50-
const nodeCreatedEventFilter = rollup.filters.NodeCreated(nodeId);
51-
const nodeCreatedEvents = await rollup.queryFilter(nodeCreatedEventFilter);
52-
if (!nodeCreatedEvents) {
53-
throw new Error(`INTERNAL ERROR: NodeCreated events not found for Rblock/node: ${nodeId}`);
29+
const assertionCreatedEventFilter = (rollup as any).filters.AssertionCreated(assertionHash);
30+
const assertionCreatedEvents = await rollup.queryFilter(assertionCreatedEventFilter);
31+
if (!assertionCreatedEvents || assertionCreatedEvents.length === 0) {
32+
throw new Error(
33+
`INTERNAL ERROR: AssertionCreated events not found for assertion: ${assertionHash}`,
34+
);
5435
}
55-
const nodeCreatedEvent = nodeCreatedEvents[0];
56-
console.log(`NodeCreated event found in transaction ${nodeCreatedEvent.transactionHash}`);
36+
const assertionCreatedEvent = assertionCreatedEvents[0];
37+
console.log(
38+
`AssertionCreated event found in transaction ${assertionCreatedEvent.transactionHash}`,
39+
);
5740

58-
/**
59-
* Finding the assertion within the NodeCreated event, and getting the afterState
60-
*/
61-
if (!nodeCreatedEvent.args) {
41+
if (!assertionCreatedEvent.args) {
6242
throw new Error(
63-
`INTERNAL ERROR: NodeCreated event does not have an assertion for Rblock/node: ${nodeId}`,
43+
`INTERNAL ERROR: AssertionCreated event does not have an assertion for hash: ${assertionHash}`,
6444
);
6545
}
66-
const assertion = nodeCreatedEvent.args.assertion;
46+
const assertion = (assertionCreatedEvent as any).args.assertion;
6747
const afterState = assertion.afterState;
6848

69-
/**
70-
* Latest child chain's block hash processed is in the first element of the bytes32Vals property in the globalState
71-
*/
49+
// Latest child chain's block hash processed is in the first element of the bytes32Vals property in the globalState
7250
const lastChildChainBlockHash = afterState.globalState.bytes32Vals[0];
7351
console.log(
7452
`Last block hash of the child chain processed in this Rblock/node: ${lastChildChainBlockHash}`,
7553
);
7654

77-
/**
78-
* Getting the block number from that block hash
79-
*/
55+
// Getting the block number from that block hash
56+
8057
const lastChildChainBlock = await childChainProvider.getBlock(lastChildChainBlockHash);
8158
const lastChildChainBlockNumber = lastChildChainBlock.number;
8259
console.log(
8360
`Last block number of the child chain processed in this Rblock/node: ${lastChildChainBlockNumber}`,
8461
);
8562

86-
/**
87-
* Final verification
88-
*/
63+
// Final verification
8964
console.log(`************`);
9065
if (lastChildChainBlockNumber > childChainBlockNumberToVerify) {
9166
console.log(
92-
`${childChainBlockNumberToVerify} has been processed as part of the latest ${
93-
useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'
94-
} RBlock/node`,
67+
`${childChainBlockNumberToVerify} has been processed as part of the latest confirmed assertion`,
9568
);
9669
} else {
9770
console.log(
98-
`${childChainBlockNumberToVerify} has NOT been processed as part of the latest ${
99-
useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'
100-
} RBlock/node`,
71+
`${childChainBlockNumberToVerify} has NOT been processed as part of the latest confirmed assertion`,
10172
);
10273
}
10374
console.log(`************`);
@@ -106,9 +77,7 @@ const main = async (childChainBlockNumberToVerify: number) => {
10677
// Getting the transaction hash from the command arguments
10778
if (process.argv.length < 3) {
10879
console.log(
109-
`Missing block number of the child chain to verify whether it has been processed in the latest ${
110-
useCreatedNodeInsteadOfConfirmed ? 'created' : 'confirmed'
111-
} RBlock/node`,
80+
'Missing block number of the child chain to verify whether it has been processed in the latest confirmed assertion',
11281
);
11382
console.log(`Usage: yarn run exec <block number>`);
11483
process.exit(1);

0 commit comments

Comments
 (0)