Skip to content

Commit fa19e22

Browse files
Merge pull request #79 from OffchainLabs/anytrust-mode
Add --l2-anytrust option to run in AnyTrust mode
2 parents 3da0ec9 + 02621d2 commit fa19e22

File tree

5 files changed

+328
-11
lines changed

5 files changed

+328
-11
lines changed

docker-compose.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,54 @@ services:
367367
- "config:/config"
368368
- /var/run/docker.sock:/var/run/docker.sock
369369

370+
datool:
371+
image: nitro-node-dev-testnode
372+
entrypoint: /usr/local/bin/datool
373+
volumes:
374+
- "config:/config"
375+
- "das-committee-a-data:/das-committee-a"
376+
- "das-committee-b-data:/das-committee-b"
377+
- "das-mirror-data:/das-mirror"
378+
command:
379+
380+
das-committee-a:
381+
pid: host # allow debugging
382+
image: nitro-node-dev-testnode
383+
entrypoint: /usr/local/bin/daserver
384+
ports:
385+
- "127.0.0.1:9876:9876"
386+
- "127.0.0.1:9877:9877"
387+
volumes:
388+
- "config:/config"
389+
- "das-committee-a-data:/das"
390+
command:
391+
- --conf.file=/config/l2_das_committee.json
392+
393+
das-committee-b:
394+
pid: host # allow debugging
395+
image: nitro-node-dev-testnode
396+
entrypoint: /usr/local/bin/daserver
397+
ports:
398+
- "127.0.0.1:8876:9876"
399+
- "127.0.0.1:8877:9877"
400+
volumes:
401+
- "config:/config"
402+
- "das-committee-b-data:/das"
403+
command:
404+
- --conf.file=/config/l2_das_committee.json
405+
406+
das-mirror:
407+
pid: host # allow debugging
408+
image: nitro-node-dev-testnode
409+
entrypoint: /usr/local/bin/daserver
410+
ports:
411+
- "127.0.0.1:7877:9877"
412+
volumes:
413+
- "config:/config"
414+
- "das-mirror-data:/das"
415+
command:
416+
- --conf.file=/config/l2_das_mirror.json
417+
370418
volumes:
371419
l1data:
372420
consensus:
@@ -383,3 +431,6 @@ volumes:
383431
config:
384432
postgres-data:
385433
tokenbridge-data:
434+
das-committee-a-data:
435+
das-committee-b-data:
436+
das-mirror-data:

scripts/config.ts

Lines changed: 183 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as fs from 'fs';
22
import * as consts from './consts'
3+
import { ethers } from "ethers";
34
import { namedAccount, namedAddress } from './accounts'
45

56
const path = require("path");
@@ -160,10 +161,22 @@ function writeGethGenesisConfig(argv: any) {
160161
fs.writeFileSync(path.join(consts.configpath, "val_jwt.hex"), val_jwt)
161162
}
162163

164+
type ChainInfo = {
165+
[key: string]: any;
166+
};
167+
168+
// Define a function to return ChainInfo
169+
function getChainInfo(): ChainInfo {
170+
const filePath = path.join(consts.configpath, "l2_chain_info.json");
171+
const fileContents = fs.readFileSync(filePath).toString();
172+
const chainInfo: ChainInfo = JSON.parse(fileContents);
173+
return chainInfo;
174+
}
175+
163176
function writeConfigs(argv: any) {
164177
const valJwtSecret = path.join(consts.configpath, "val_jwt.hex")
165178
const chainInfoFile = path.join(consts.configpath, "l2_chain_info.json")
166-
const baseConfig = {
179+
let baseConfig = {
167180
"parent-chain": {
168181
"connection": {
169182
"url": argv.l1url,
@@ -181,7 +194,7 @@ function writeConfigs(argv: any) {
181194
"parent-chain-wallet" : {
182195
"account": namedAddress("validator"),
183196
"password": consts.l1passphrase,
184-
"pathname": consts.l1keystore,
197+
"pathname": consts.l1keystore,
185198
},
186199
"disable-challenge": false,
187200
"enable": false,
@@ -215,7 +228,7 @@ function writeConfigs(argv: any) {
215228
"parent-chain-wallet" : {
216229
"account": namedAddress("sequencer"),
217230
"password": consts.l1passphrase,
218-
"pathname": consts.l1keystore,
231+
"pathname": consts.l1keystore,
219232
},
220233
"data-poster": {
221234
"redis-signer": {
@@ -229,6 +242,17 @@ function writeConfigs(argv: any) {
229242
"url": argv.validationNodeUrl,
230243
"jwtsecret": valJwtSecret,
231244
}
245+
},
246+
"data-availability": {
247+
"enable": argv.anytrust,
248+
"rpc-aggregator": dasBackendsJsonConfig(argv),
249+
"rest-aggregator": {
250+
"enable": true,
251+
"urls": ["http://das-mirror:9877"],
252+
},
253+
// TODO Fix das config to not need this redundant config
254+
"parent-chain-node-url": argv.l1url,
255+
"sequencer-inbox-address": "not_set"
232256
}
233257
},
234258
"execution": {
@@ -250,6 +274,7 @@ function writeConfigs(argv: any) {
250274
},
251275
}
252276

277+
baseConfig.node["data-availability"]["sequencer-inbox-address"] = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]);
253278

254279
const baseConfJSON = JSON.stringify(baseConfig)
255280

@@ -264,6 +289,9 @@ function writeConfigs(argv: any) {
264289
simpleConfig.node["batch-poster"].enable = true
265290
simpleConfig.node["batch-poster"]["redis-url"] = ""
266291
simpleConfig.execution["sequencer"].enable = true
292+
if (argv.anytrust) {
293+
simpleConfig.node["data-availability"]["rpc-aggregator"].enable = true
294+
}
267295
fs.writeFileSync(path.join(consts.configpath, "sequencer_config.json"), JSON.stringify(simpleConfig))
268296
} else {
269297
let validatorConfig = JSON.parse(baseConfJSON)
@@ -286,6 +314,9 @@ function writeConfigs(argv: any) {
286314
let posterConfig = JSON.parse(baseConfJSON)
287315
posterConfig.node["seq-coordinator"].enable = true
288316
posterConfig.node["batch-poster"].enable = true
317+
if (argv.anytrust) {
318+
posterConfig.node["data-availability"]["rpc-aggregator"].enable = true
319+
}
289320
fs.writeFileSync(path.join(consts.configpath, "poster_config.json"), JSON.stringify(posterConfig))
290321
}
291322

@@ -353,7 +384,7 @@ function writeL2ChainConfig(argv: any) {
353384
"arbitrum": {
354385
"EnableArbOS": true,
355386
"AllowDebugPrecompiles": true,
356-
"DataAvailabilityCommittee": false,
387+
"DataAvailabilityCommittee": argv.anytrust,
357388
"InitialArbOSVersion": 32,
358389
"InitialChainOwner": argv.l2owner,
359390
"GenesisBlockNum": 0
@@ -396,6 +427,93 @@ function writeL3ChainConfig(argv: any) {
396427
fs.writeFileSync(path.join(consts.configpath, "l3_chain_config.json"), l3ChainConfigJSON)
397428
}
398429

430+
function writeL2DASCommitteeConfig(argv: any) {
431+
const sequencerInboxAddr = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]);
432+
const l2DASCommitteeConfig = {
433+
"data-availability": {
434+
"key": {
435+
"key-dir": "/das/keys"
436+
},
437+
"local-file-storage": {
438+
"data-dir": "/das/data",
439+
"enable": true,
440+
"enable-expiry": true
441+
},
442+
"sequencer-inbox-address": sequencerInboxAddr,
443+
"parent-chain-node-url": argv.l1url
444+
},
445+
"enable-rest": true,
446+
"enable-rpc": true,
447+
"log-level": "INFO",
448+
"rest-addr": "0.0.0.0",
449+
"rest-port": "9877",
450+
"rpc-addr": "0.0.0.0",
451+
"rpc-port": "9876"
452+
}
453+
const l2DASCommitteeConfigJSON = JSON.stringify(l2DASCommitteeConfig)
454+
455+
fs.writeFileSync(path.join(consts.configpath, "l2_das_committee.json"), l2DASCommitteeConfigJSON)
456+
}
457+
458+
function writeL2DASMirrorConfig(argv: any, sequencerInboxAddr: string) {
459+
const l2DASMirrorConfig = {
460+
"data-availability": {
461+
"local-file-storage": {
462+
"data-dir": "/das/data",
463+
"enable": true,
464+
"enable-expiry": false
465+
},
466+
"sequencer-inbox-address": sequencerInboxAddr,
467+
"parent-chain-node-url": argv.l1url,
468+
"rest-aggregator": {
469+
"enable": true,
470+
"sync-to-storage": {
471+
"eager": false,
472+
"ignore-write-errors": false,
473+
"state-dir": "/das/metadata",
474+
"sync-expired-data": true
475+
},
476+
"urls": ["http://das-committee-a:9877", "http://das-committee-b:9877"],
477+
}
478+
},
479+
"enable-rest": true,
480+
"enable-rpc": false,
481+
"log-level": "INFO",
482+
"rest-addr": "0.0.0.0",
483+
"rest-port": "9877"
484+
}
485+
const l2DASMirrorConfigJSON = JSON.stringify(l2DASMirrorConfig)
486+
487+
fs.writeFileSync(path.join(consts.configpath, "l2_das_mirror.json"), l2DASMirrorConfigJSON)
488+
}
489+
490+
function writeL2DASKeysetConfig(argv: any) {
491+
const l2DASKeysetConfig = {
492+
"keyset": dasBackendsJsonConfig(argv)
493+
}
494+
const l2DASKeysetConfigJSON = JSON.stringify(l2DASKeysetConfig)
495+
496+
fs.writeFileSync(path.join(consts.configpath, "l2_das_keyset.json"), l2DASKeysetConfigJSON)
497+
}
498+
499+
function dasBackendsJsonConfig(argv: any) {
500+
const backends = {
501+
"enable": false,
502+
"assumed-honest": 1,
503+
"backends": [
504+
{
505+
"url": "http://das-committee-a:9876",
506+
"pubkey": argv.dasBlsA
507+
},
508+
{
509+
"url": "http://das-committee-b:9876",
510+
"pubkey": argv.dasBlsB
511+
}
512+
]
513+
}
514+
return backends
515+
}
516+
399517
export const writeConfigCommand = {
400518
command: "write-config",
401519
describe: "writes config files",
@@ -405,7 +523,23 @@ export const writeConfigCommand = {
405523
describe: "simple config (sequencer is also poster, validator)",
406524
default: false,
407525
},
408-
},
526+
anytrust: {
527+
boolean: true,
528+
describe: "run nodes in anytrust mode",
529+
default: false
530+
},
531+
dasBlsA: {
532+
string: true,
533+
describe: "DAS committee member A BLS pub key",
534+
default: ""
535+
},
536+
dasBlsB: {
537+
string: true,
538+
describe: "DAS committee member B BLS pub key",
539+
default: ""
540+
},
541+
542+
},
409543
handler: (argv: any) => {
410544
writeConfigs(argv)
411545
}
@@ -430,6 +564,13 @@ export const writeGethGenesisCommand = {
430564
export const writeL2ChainConfigCommand = {
431565
command: "write-l2-chain-config",
432566
describe: "writes l2 chain config file",
567+
builder: {
568+
anytrust: {
569+
boolean: true,
570+
describe: "enable anytrust in chainconfig",
571+
default: false
572+
},
573+
},
433574
handler: (argv: any) => {
434575
writeL2ChainConfig(argv)
435576
}
@@ -442,3 +583,40 @@ export const writeL3ChainConfigCommand = {
442583
writeL3ChainConfig(argv)
443584
}
444585
}
586+
587+
export const writeL2DASCommitteeConfigCommand = {
588+
command: "write-l2-das-committee-config",
589+
describe: "writes daserver committee member config file",
590+
handler: (argv: any) => {
591+
writeL2DASCommitteeConfig(argv)
592+
}
593+
}
594+
595+
export const writeL2DASMirrorConfigCommand = {
596+
command: "write-l2-das-mirror-config",
597+
describe: "writes daserver mirror config file",
598+
handler: (argv: any) => {
599+
const sequencerInboxAddr = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]);
600+
writeL2DASMirrorConfig(argv, sequencerInboxAddr)
601+
}
602+
}
603+
604+
export const writeL2DASKeysetConfigCommand = {
605+
command: "write-l2-das-keyset-config",
606+
describe: "writes DAS keyset config",
607+
builder: {
608+
dasBlsA: {
609+
string: true,
610+
describe: "DAS committee member A BLS pub key",
611+
default: ""
612+
},
613+
dasBlsB: {
614+
string: true,
615+
describe: "DAS committee member B BLS pub key",
616+
default: ""
617+
},
618+
},
619+
handler: (argv: any) => {
620+
writeL2DASKeysetConfig(argv)
621+
}
622+
}

scripts/ethcommands.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,25 @@ export const createERC20Command = {
372372
},
373373
};
374374

375+
// Will revert if the keyset is already valid.
376+
async function setValidKeyset(argv: any, upgradeExecutorAddr: string, sequencerInboxAddr: string, keyset: string){
377+
const innerIface = new ethers.utils.Interface(["function setValidKeyset(bytes)"])
378+
const innerData = innerIface.encodeFunctionData("setValidKeyset", [keyset]);
379+
380+
// The Executor contract is the owner of the SequencerInbox so calls must be made
381+
// through it.
382+
const outerIface = new ethers.utils.Interface(["function executeCall(address,bytes)"])
383+
argv.data = outerIface.encodeFunctionData("executeCall", [sequencerInboxAddr, innerData]);
384+
385+
argv.from = "l2owner";
386+
argv.to = "address_" + upgradeExecutorAddr
387+
argv.ethamount = "0"
388+
389+
await sendTransaction(argv, 0);
390+
391+
argv.provider.destroy();
392+
}
393+
375394
export const transferERC20Command = {
376395
command: "transfer-erc20",
377396
describe: "transfers ERC20 token",
@@ -526,6 +545,27 @@ export const sendRPCCommand = {
526545
}
527546
}
528547

548+
export const setValidKeysetCommand = {
549+
command: "set-valid-keyset",
550+
describe: "sets the anytrust keyset",
551+
handler: async (argv: any) => {
552+
argv.provider = new ethers.providers.WebSocketProvider(argv.l1url);
553+
const deploydata = JSON.parse(
554+
fs
555+
.readFileSync(path.join(consts.configpath, "deployment.json"))
556+
.toString()
557+
);
558+
const sequencerInboxAddr = ethers.utils.hexlify(deploydata["sequencer-inbox"]);
559+
const upgradeExecutorAddr = ethers.utils.hexlify(deploydata["upgrade-executor"]);
560+
561+
const keyset = fs
562+
.readFileSync(path.join(consts.configpath, "l2_das_keyset.hex"))
563+
.toString()
564+
565+
await setValidKeyset(argv, upgradeExecutorAddr, sequencerInboxAddr, keyset)
566+
}
567+
};
568+
529569
export const waitForSyncCommand = {
530570
command: "wait-for-sync",
531571
describe: "wait for rpc to sync",

0 commit comments

Comments
 (0)