Nitro Testnode Fork Diff

diff: ignored:
+1898
-224
+3905
-0

The original nitro codebase can be found at github.com/OffchainLabs/nitro-testnode. And the fork at github.com/Layr-Labs/nitro-testnode.

Added support for EigenDA:

  • Updated config generation script to express EigenDA chain params

  • Updated rollup creator deployment script to target layr-labs/nitro-contracts

  • Updated core docker compose to wire EigenDA proxy dependency

diff --git OffchainLabs/nitro-testnode/docker-compose.yaml Layr-Labs/nitro-testnode/docker-compose.yaml index 81deb6d1b73dd67ea4cdf7f86a3304c78b6e1998..d730417fbc39b2caca6da44b1ceb6e24cf767da8 100644 --- OffchainLabs/nitro-testnode/docker-compose.yaml +++ Layr-Labs/nitro-testnode/docker-compose.yaml @@ -47,7 +47,7 @@ ports: - "127.0.0.1:6379:6379"   geth: - image: ethereum/client-go:v1.10.23 + image: ethereum/client-go:stable ports: - "127.0.0.1:8545:8545" - "127.0.0.1:8551:8551" @@ -66,7 +66,7 @@ - --authrpc.vhosts=* - --authrpc.port=8551 - --authrpc.addr=0.0.0.0 - --http.vhosts=* - - --http.api=engine,personal,eth,net,web3 + - --http.api=engine,personal,eth,net,web3,debug - --http.corsdomain=* - --ws - --ws.addr=0.0.0.0 @@ -77,13 +77,14 @@ - --password=/datadir/passphrase - --authrpc.jwtsecret=/config/jwt.hex - --nodiscover - --syncmode=full + - --state.scheme=hash - --dev - --dev.period=1 - --mine - --miner.etherbase=0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E - --gcmode=archive   - # Creates a genesis state for the beacon chain using a YAML configuration file and + # Creates a genesis state for the beacon chain using a YAML configuration file and # a deterministic set of validators # TODO: Make num validators customizable create_beacon_chain_genesis: @@ -91,14 +92,17 @@ image: "gcr.io/prysmaticlabs/prysm/cmd/prysmctl:latest" command: - testnet - generate-genesis + - --fork=deneb - --num-validators=64 + - --genesis-time-delay=15 - --output-ssz=/consensus/genesis.ssz - --chain-config-file=/config/prysm.yaml + - --geth-genesis-json-in=/config/geth_genesis.json volumes: - "consensus:/consensus" - "config:/config"   - # Runs a Prysm beacon chain from a specified genesis state created in the previous step + # Runs a Prysm beacon chain from a specified genesis state created in the previous step # and connects to go-ethereum in the same network as the execution client. # The account used in go-ethereum is set as the suggested fee recipient for transactions # proposed via the validators attached to the beacon node. @@ -108,16 +112,17 @@ command: - --datadir=/consensus/beacondata - --rpc-port=5000 - --min-sync-peers=0 - - --interop-genesis-state=/consensus/genesis.ssz + - --genesis-state=/consensus/genesis.ssz - --interop-eth1data-votes - --bootstrap-node= - --chain-config-file=/config/prysm.yaml - --rpc-host=0.0.0.0 - --grpc-gateway-host=0.0.0.0 - - --chain-id=32382 + - --chain-id=1337 - --execution-endpoint=http://geth:8551 - --accept-terms-of-use - --jwt-secret=/config/jwt.hex + - --suggested-fee-recipient=0x000000000000000000000000000000000000dEaD depends_on: geth: condition: service_started @@ -161,7 +166,18 @@ - "seqdata:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - "tokenbridge-data:/tokenbridge-data" - command: --conf.file /config/sequencer_config.json --node.feed.output.enable --node.feed.output.port 9642 --http.api net,web3,eth,txpool,debug --node.seq-coordinator.my-url ws://sequencer:8548 --graphql.enable --graphql.vhosts * --graphql.corsdomain * + command: + - --conf.file=/config/sequencer_config.json + - --node.feed.output.enable + - --node.feed.output.port=9642 + - --http.api=net,web3,eth,txpool,debug,timeboost,auctioneer + - --node.seq-coordinator.my-url=http://sequencer:8547 + - --graphql.enable + - --graphql.vhosts=* + - --graphql.corsdomain=* + - --metrics + - --pprof + depends_on: - geth   @@ -175,7 +191,13 @@ - "127.0.0.1:8648:8548" volumes: - "seqdata_b:/home/user/.arbitrum/local/nitro" - "config:/config" - command: --conf.file /config/sequencer_config.json --node.seq-coordinator.my-url ws://sequencer_b:8548 + command: + - --conf.file=/config/sequencer_config.json + - --node.seq-coordinator.my-url=http://sequencer_b:8547 + - --http.api=net,web3,eth,txpool,debug,timeboost,auctioneer + - --metrics + - --pprof + depends_on: - geth - redis @@ -190,7 +212,13 @@ - "127.0.0.1:8748:8548" volumes: - "seqdata_c:/home/user/.arbitrum/local/nitro" - "config:/config" - command: --conf.file /config/sequencer_config.json --node.seq-coordinator.my-url ws://sequencer_c:8548 + command: + - --conf.file=/config/sequencer_config.json + - --node.seq-coordinator.my-url=http://sequencer_c:8547 + - --http.api=net,web3,eth,txpool,debug,timeboost,auctioneer + - --metrics + - --pprof + depends_on: - geth - redis @@ -205,7 +233,13 @@ - "127.0.0.1:8848:8548" volumes: - "seqdata_d:/home/user/.arbitrum/local/nitro" - "config:/config" - command: --conf.file /config/sequencer_config.json --node.seq-coordinator.my-url ws://sequencer_d:8548 + command: + - --conf.file=/config/sequencer_config.json + - --node.seq-coordinator.my-url=http://sequencer_d:8547 + - --http.api=net,web3,eth,txpool,debug,timeboost,auctioneer + - --metrics + - --pprof + depends_on: - geth - redis @@ -221,7 +255,7 @@ volumes: - "unsafestaker-data:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/unsafe_staker_config.json + command: --conf.file /config/unsafe_staker_config.json --metrics depends_on: - sequencer - redis @@ -238,7 +272,7 @@ volumes: - "poster-data:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/poster_config.json + command: --conf.file /config/poster_config.json --metrics depends_on: - geth - redis @@ -254,7 +288,7 @@ volumes: - "poster-data-b:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/poster_config.json + command: --conf.file /config/poster_config.json --metrics depends_on: - geth - redis @@ -270,7 +304,7 @@ volumes: - "poster-data-c:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/poster_config.json + command: --conf.file /config/poster_config.json --metrics depends_on: - geth - redis @@ -286,7 +320,7 @@ volumes: - "validator-data:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/validator_config.json --http.port 8547 --http.api net,web3,arb,debug --ws.port 8548 + command: --conf.file /config/validator_config.json --http.port 8547 --http.api net,web3,arb,debug --ws.port 8548 --metrics depends_on: - sequencer - validation_node @@ -302,7 +336,7 @@ volumes: - "validator-data:/home/user/.arbitrum/local/nitro" - "l1keystore:/home/user/l1keystore" - "config:/config" - command: --conf.file /config/l3node_config.json --http.port 3347 --http.api net,web3,arb,debug,eth --ws.port 3348 + command: --conf.file /config/l3node_config.json --http.port 3347 --http.api net,web3,arb,debug,eth --ws.port 3348 --metrics depends_on: - sequencer - validation_node @@ -315,7 +349,7 @@ ports: - "127.0.0.1:8949:8549" volumes: - "config:/config" - command: --conf.file /config/validation_node_config.json + command: --conf.file /config/validation_node_config.json --metrics   scripts: build: scripts/ @@ -330,7 +364,7 @@ image: nitro-node-dev-testnode entrypoint: /usr/local/bin/relay ports: - "127.0.0.1:9652:9652" - command: --chain.id 412346 --node.feed.input.url ws://sequencer:9642 --node.feed.output.port 9652 + command: --chain.id 412346 --node.feed.input.url ws://sequencer:9642 --node.feed.output.port 9652 --metrics   tokenbridge: depends_on: @@ -346,6 +380,26 @@ - ARB_URL=http://sequencer:8547 - ETH_URL=http://geth:8545 volumes: - "tokenbridge-data:/workspace" + - /var/run/docker.sock:/var/run/docker.sock + + boldupgrader: + depends_on: + - geth + - sequencer + pid: host + build: + context: boldupgrader/ + args: + BOLD_CONTRACTS_BRANCH: ${BOLD_CONTRACTS_BRANCH:-} + environment: + - L1_RPC_URL=http://geth:8545 + - L1_PRIV_KEY=0xdc04c5399f82306ec4b4d654a342f40e2e0620fe39950d967e1e574b32d4dd36 + - CONFIG_NETWORK_NAME=local + - DEPLOYED_CONTRACTS_DIR=./scripts/files/ + - DISABLE_VERIFICATION=true + volumes: + - "config:/config" + - "boldupgrader-data:/workspace" - /var/run/docker.sock:/var/run/docker.sock   rollupcreator: @@ -361,6 +415,148 @@ volumes: - "config:/config" - /var/run/docker.sock:/var/run/docker.sock   + datool: + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/datool + volumes: + - "config:/config" + - "das-committee-a-data:/das-committee-a" + - "das-committee-b-data:/das-committee-b" + - "das-mirror-data:/das-mirror" + command: + + das-committee-a: + pid: host # allow debugging + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/daserver + ports: + - "127.0.0.1:9876:9876" + - "127.0.0.1:9877:9877" + volumes: + - "config:/config" + - "das-committee-a-data:/das" + command: + - --conf.file=/config/l2_das_committee.json + + das-committee-b: + pid: host # allow debugging + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/daserver + ports: + - "127.0.0.1:8876:9876" + - "127.0.0.1:8877:9877" + volumes: + - "config:/config" + - "das-committee-b-data:/das" + command: + - --conf.file=/config/l2_das_committee.json + + das-mirror: + pid: host # allow debugging + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/daserver + ports: + - "127.0.0.1:7877:9877" + volumes: + - "config:/config" + - "das-mirror-data:/das" + command: + - --conf.file=/config/l2_das_mirror.json + + timeboost-auctioneer: + pid: host # allow debugging + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/autonomous-auctioneer + volumes: + - "config:/config" + - "timeboost-auctioneer-data:/data" + - "l1keystore:/home/user/l1keystore" + command: + - --conf.file=/config/autonomous_auctioneer_config.json + depends_on: + - redis + + timeboost-bid-validator: + pid: host # allow debugging + image: nitro-node-dev-testnode + entrypoint: /usr/local/bin/autonomous-auctioneer + ports: + - "127.0.0.1:9372:8547" + volumes: + - "config:/config" + command: + - --conf.file=/config/bid_validator_config.json + - --http.addr=0.0.0.0 + - --http.vhosts=* + - --http.corsdomain=* + - --http.api=auctioneer + - --log-level=INFO + depends_on: + - redis + + eigenda_proxy: + container_name: eigenda-proxy + image: ghcr.io/layr-labs/eigenda-proxy:v1.6.1 + environment: + - EIGENDA_PROXY_ADDR=0.0.0.0 + - EIGENDA_PROXY_PORT=4242 + - EIGENDA_PROXY_MEMSTORE_ENABLED=true + ## Disable this when using real testnet + - EIGENDA_PROXY_EIGENDA_CERT_VERIFICATION_DISABLED=true + - EIGENDA_PROXY_MEMSTORE_EXPIRATION=45m + - EIGENDA_PROXY_EIGENDA_SIGNER_PRIVATE_KEY_HEX=$EIGENDA_SIGNER_PRIVATE_KEY + - EIGENDA_PROXY_EIGENDA_DISPERSER_RPC=disperser-holesky.eigenda.xyz:443 + ## Uncomment these when pointed against real testnet + # - EIGENDA_PROXY_EIGENDA_SERVICE_MANAGER_ADDR=0xD4A7E1Bd8015057293f0D0A557088c286942e84b + # - EIGENDA_PROXY_EIGENDA_ETH_RPC=https://ethereum-holesky-rpc.publicnode.com + # - EIGENDA_PROXY_EIGENDA_CONFIRMATION_DEPTH=0 + - EIGENDA_PROXY_METRICS_ADDR=0.0.0.0 + - EIGENDA_PROXY_METRICS_ENABLED=true + - EIGENDA_PROXY_METRICS_PORT=7300 + ports: + - 4242:4242 + - 7300:7300 + + prometheus: + image: prom/prometheus:latest + container_name: prometheus + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + command: + - "--config.file=/etc/prometheus/prometheus.yml" + + grafana: + image: grafana/grafana:latest + container_name: grafana + ports: + - "127.0.0.1:3000:3000" + volumes: + - ./grafana/provisioning/:/etc/grafana/provisioning/:ro + - ./grafana/dashboards:/var/lib/grafana/dashboards + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + depends_on: + - prometheus + + loki: + image: grafana/loki:3.1.1 + restart: unless-stopped + volumes: + - ./loki:/etc/loki + ports: + - 3200:3200 + command: -config.file=/etc/loki/config.yaml + + promtail: + image: grafana/promtail:3.1.1 + restart: unless-stopped + volumes: + - ./promtail:/etc/promtail + - /var/run/docker.sock:/var/run/docker.sock # Mount Docker socket to read container logs + command: -config.file=/etc/promtail/config.yaml + volumes: l1data: consensus: @@ -374,6 +570,12 @@ validator-data: poster-data: poster-data-b: poster-data-c: + grafana-data: config: postgres-data: tokenbridge-data: + das-committee-a-data: + das-committee-b-data: + das-mirror-data: + timeboost-auctioneer-data: + boldupgrader-data:
diff --git OffchainLabs/nitro-testnode/rollupcreator/Dockerfile Layr-Labs/nitro-testnode/rollupcreator/Dockerfile index 17b065a90ce648bdae16f8dc735be321beeb84e6..459a04ecb19fad5d847f71f8a5e5690fbf6697a1 100644 --- OffchainLabs/nitro-testnode/rollupcreator/Dockerfile +++ Layr-Labs/nitro-testnode/rollupcreator/Dockerfile @@ -1,14 +1,14 @@ -FROM node:16-bullseye-slim -ARG NITRO_CONTRACTS_BRANCH=main +FROM node:20-bookworm-slim RUN apt-get update && \ - apt-get install -y git docker.io python3 build-essential curl jq + apt-get install -y git docker.io python3 make gcc g++ curl jq +ARG NITRO_CONTRACTS_BRANCH=eigenda-v2.1.3 WORKDIR /workspace -RUN git clone --no-checkout https://github.com/OffchainLabs/nitro-contracts.git ./ -RUN git checkout ${NITRO_CONTRACTS_BRANCH} +RUN git clone --no-checkout https://github.com/layr-labs/nitro-contracts.git ./ +RUN git checkout f6dd563ab81124a811ac3a660082897b04736196 +RUN yarn install && yarn cache clean RUN curl -L https://foundry.paradigm.xyz | bash ENV PATH="${PATH}:/root/.foundry/bin" -RUN foundryup +RUN foundryup --install 1.0.0 RUN touch scripts/config.ts -RUN yarn install RUN yarn build:all ENTRYPOINT ["yarn"]
diff --git OffchainLabs/nitro-testnode/scripts/config.ts Layr-Labs/nitro-testnode/scripts/config.ts index eefcdd29b4ff91d3348929bcd454721dbdeceaeb..6402a0834b2eaf5e01355015198ff76c48b6bc90 100644 --- OffchainLabs/nitro-testnode/scripts/config.ts +++ Layr-Labs/nitro-testnode/scripts/config.ts @@ -1,5 +1,6 @@ import * as fs from 'fs'; import * as consts from './consts' +import { ethers } from "ethers"; import { namedAccount, namedAddress } from './accounts'   const path = require("path"); @@ -13,16 +14,31 @@ # Genesis GENESIS_FORK_VERSION: 0x20000089   # Altair -ALTAIR_FORK_EPOCH: 1 +ALTAIR_FORK_EPOCH: 0 ALTAIR_FORK_VERSION: 0x20000090   # Merge -BELLATRIX_FORK_EPOCH: 2 +BELLATRIX_FORK_EPOCH: 0 BELLATRIX_FORK_VERSION: 0x20000091 TERMINAL_TOTAL_DIFFICULTY: 50   +# Capella +CAPELLA_FORK_EPOCH: 0 +CAPELLA_FORK_VERSION: 0x20000092 +MAX_WITHDRAWALS_PER_PAYLOAD: 16 + +# DENEB +DENEB_FORK_EPOCH: 0 +DENEB_FORK_VERSION: 0x20000093 + +# ELECTRA +ELECTRA_FORK_VERSION: 0x20000094 + +# FULU +FULU_FORK_VERSION: 0x20000095 + # Time parameters -SECONDS_PER_SLOT: 12 +SECONDS_PER_SLOT: 2 SLOTS_PER_EPOCH: 6   # Deposit contract @@ -36,8 +52,7 @@ const gethConfig = ` { "config": { "ChainName": "l1_chain", - "chainId": 32382, - "consensus": "clique", + "chainId": 1337, "homesteadBlock": 0, "daoForkSupport": true, "eip150Block": 0, @@ -54,13 +69,19 @@ "londonBlock": 0, "terminalBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "arrowGlacierBlock": 0, "grayGlacierBlock": 0, - "clique": { - "period": 5, - "epoch": 30000 - }, - "terminalTotalDifficulty": 50 + "shanghaiTime": 0, + "cancunTime": 1706778826, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + } + } }, - "difficulty": "1", + "difficulty": "0", "extradata": "0x00000000000000000000000000000000000000000000000000000000000000003f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E0B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x42", "timestamp": "0x0", @@ -150,10 +171,23 @@ const val_jwt = `0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` fs.writeFileSync(path.join(consts.configpath, "val_jwt.hex"), val_jwt) }   +type ChainInfo = { + [key: string]: any; +}; + +// Define a function to return ChainInfo +function getChainInfo(): ChainInfo { + const filePath = path.join(consts.configpath, "l2_chain_info.json"); + const fileContents = fs.readFileSync(filePath).toString(); + const chainInfo: ChainInfo = JSON.parse(fileContents); + return chainInfo; +} + function writeConfigs(argv: any) { const valJwtSecret = path.join(consts.configpath, "val_jwt.hex") const chainInfoFile = path.join(consts.configpath, "l2_chain_info.json") - const baseConfig = { + let baseConfig = { + "ensure-rollup-deployment": false, "parent-chain": { "connection": { "url": argv.l1url, @@ -164,14 +198,18 @@ "id": 412346, "info-files": [chainInfoFile], }, "node": { + "eigen-da": { + "enable": false, + "rpc": "http://eigenda_proxy:4242" + }, "staker": { "dangerous": { "without-block-validator": false }, - "parent-chain-wallet" : { + "parent-chain-wallet": { "account": namedAddress("validator"), "password": consts.l1passphrase, - "pathname": consts.l1keystore, + "pathname": consts.l1keystore, }, "disable-challenge": false, "enable": false, @@ -200,12 +238,15 @@ }, "batch-poster": { "enable": false, "redis-url": argv.redisUrl, - "max-delay": "30s", + "max-delay": "10s", + "wait-for-max-delay": false, + "max-eigenda-batch-size": 16_000_000, // 16MB + "enable-eigenda-failover": false, "l1-block-bound": "ignore", - "parent-chain-wallet" : { + "parent-chain-wallet": { "account": namedAddress("sequencer"), "password": consts.l1passphrase, - "pathname": consts.l1keystore, + "pathname": consts.l1keystore, }, "data-poster": { "redis-signer": { @@ -219,11 +260,22 @@ "validation-server": { "url": argv.validationNodeUrl, "jwtsecret": valJwtSecret, } + }, + "data-availability": { + "enable": argv.anytrust, + "rpc-aggregator": dasBackendsJsonConfig(argv), + "rest-aggregator": { + "enable": true, + "urls": ["http://das-mirror:9877"], + }, + // TODO Fix das config to not need this redundant config + "parent-chain-node-url": argv.l1url, + "sequencer-inbox-address": "not_set" } }, "execution": { "sequencer": { - "enable": false, + "enable": false }, "forwarding-target": "null", }, @@ -238,8 +290,14 @@ "addr": "0.0.0.0", "vhosts": "*", "corsdomain": "*" }, + "metrics": true, }   + baseConfig.node["data-availability"]["sequencer-inbox-address"] = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]); + + if (argv.eigenda) { + baseConfig.node["eigen-da"].enable = true + }   const baseConfJSON = JSON.stringify(baseConfig)   @@ -254,8 +312,12 @@ simpleConfig.node["delayed-sequencer"].enable = true simpleConfig.node["batch-poster"].enable = true simpleConfig.node["batch-poster"]["redis-url"] = "" simpleConfig.execution["sequencer"].enable = true + if (argv.anytrust) { + simpleConfig.node["data-availability"]["rpc-aggregator"].enable = true + } fs.writeFileSync(path.join(consts.configpath, "sequencer_config.json"), JSON.stringify(simpleConfig)) } else { + console.log("regular") let validatorConfig = JSON.parse(baseConfJSON) validatorConfig.node.staker.enable = true validatorConfig.node.staker["use-smart-contract-wallet"] = true @@ -271,11 +333,21 @@ sequencerConfig.node.sequencer = true sequencerConfig.node["seq-coordinator"].enable = true sequencerConfig.execution["sequencer"].enable = true sequencerConfig.node["delayed-sequencer"].enable = true + if (argv.timeboost) { + sequencerConfig.execution.sequencer.dangerous = {}; + sequencerConfig.execution.sequencer.dangerous.timeboost = { + "enable": false, // Create it false initially, turn it on with sed in test-node.bash after contract setup. + "redis-url": argv.redisUrl + }; + } fs.writeFileSync(path.join(consts.configpath, "sequencer_config.json"), JSON.stringify(sequencerConfig))   let posterConfig = JSON.parse(baseConfJSON) posterConfig.node["seq-coordinator"].enable = true posterConfig.node["batch-poster"].enable = true + if (argv.anytrust) { + posterConfig.node["data-availability"]["rpc-aggregator"].enable = true + } fs.writeFileSync(path.join(consts.configpath, "poster_config.json"), JSON.stringify(posterConfig)) }   @@ -316,6 +388,7 @@ "auth": { "jwtsecret": valJwtSecret, "addr": "0.0.0.0", }, + "metrics": true, })) fs.writeFileSync(path.join(consts.configpath, "validation_node_config.json"), JSON.stringify(validationNodeConfig)) } @@ -343,12 +416,18 @@ }, "arbitrum": { "EnableArbOS": true, "AllowDebugPrecompiles": true, - "DataAvailabilityCommittee": false, - "InitialArbOSVersion": 30, + "DataAvailabilityCommittee": argv.anytrust, + "InitialArbOSVersion": 32, // TODO For Timeboost, this still needs to be set to 31 + "EigenDA": false, "InitialChainOwner": argv.l2owner, "GenesisBlockNum": 0 } } + + if (argv.eigenda) { + l2ChainConfig.arbitrum.EigenDA = true + } + const l2ChainConfigJSON = JSON.stringify(l2ChainConfig) fs.writeFileSync(path.join(consts.configpath, "l2_chain_config.json"), l2ChainConfigJSON) } @@ -377,25 +456,196 @@ "arbitrum": { "EnableArbOS": true, "AllowDebugPrecompiles": true, "DataAvailabilityCommittee": false, - "InitialArbOSVersion": 30, + "InitialArbOSVersion": 32, "InitialChainOwner": argv.l2owner, + "EigenDA": false, "GenesisBlockNum": 0 } } + + if (argv.eigenda) { + l3ChainConfig.arbitrum.EigenDA = true + } + const l3ChainConfigJSON = JSON.stringify(l3ChainConfig) fs.writeFileSync(path.join(consts.configpath, "l3_chain_config.json"), l3ChainConfigJSON) }   +function writeL2DASCommitteeConfig(argv: any) { + const sequencerInboxAddr = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]); + const l2DASCommitteeConfig = { + "data-availability": { + "key": { + "key-dir": "/das/keys" + }, + "local-file-storage": { + "data-dir": "/das/data", + "enable": true, + "enable-expiry": true + }, + "sequencer-inbox-address": sequencerInboxAddr, + "parent-chain-node-url": argv.l1url + }, + "enable-rest": true, + "enable-rpc": true, + "log-level": "INFO", + "rest-addr": "0.0.0.0", + "rest-port": "9877", + "rpc-addr": "0.0.0.0", + "rpc-port": "9876" + } + const l2DASCommitteeConfigJSON = JSON.stringify(l2DASCommitteeConfig) + + fs.writeFileSync(path.join(consts.configpath, "l2_das_committee.json"), l2DASCommitteeConfigJSON) +} + +function writeL2DASMirrorConfig(argv: any, sequencerInboxAddr: string) { + const l2DASMirrorConfig = { + "data-availability": { + "local-file-storage": { + "data-dir": "/das/data", + "enable": true, + "enable-expiry": false + }, + "sequencer-inbox-address": sequencerInboxAddr, + "parent-chain-node-url": argv.l1url, + "rest-aggregator": { + "enable": true, + "sync-to-storage": { + "eager": false, + "ignore-write-errors": false, + "state-dir": "/das/metadata", + "sync-expired-data": true + }, + "urls": ["http://das-committee-a:9877", "http://das-committee-b:9877"], + } + }, + "enable-rest": true, + "enable-rpc": false, + "log-level": "INFO", + "rest-addr": "0.0.0.0", + "rest-port": "9877" + } + const l2DASMirrorConfigJSON = JSON.stringify(l2DASMirrorConfig) + + fs.writeFileSync(path.join(consts.configpath, "l2_das_mirror.json"), l2DASMirrorConfigJSON) +} + +function writeL2DASKeysetConfig(argv: any) { + const l2DASKeysetConfig = { + "keyset": dasBackendsJsonConfig(argv) + } + const l2DASKeysetConfigJSON = JSON.stringify(l2DASKeysetConfig) + + fs.writeFileSync(path.join(consts.configpath, "l2_das_keyset.json"), l2DASKeysetConfigJSON) +} + +function dasBackendsJsonConfig(argv: any) { + const backends = { + "enable": false, + "assumed-honest": 1, + "backends": [ + { + "url": "http://das-committee-a:9876", + "pubkey": argv.dasBlsA + }, + { + "url": "http://das-committee-b:9876", + "pubkey": argv.dasBlsB + } + ] + } + return backends +} + +export const writeTimeboostConfigsCommand = { + command: "write-timeboost-configs", + describe: "writes configs for the timeboost autonomous auctioneer and bid validator", + builder: { + "auction-contract": { + string: true, + describe: "auction contract address", + demandOption: true + }, + }, + handler: (argv: any) => { + writeAutonomousAuctioneerConfig(argv) + writeBidValidatorConfig(argv) + } +} + +function writeAutonomousAuctioneerConfig(argv: any) { + const autonomousAuctioneerConfig = { + "auctioneer-server": { + "auction-contract-address": argv.auctionContract, + "db-directory": "/data", + "redis-url": "redis://redis:6379", + "use-redis-coordinator": true, + "redis-coordinator-url": "redis://redis:6379", + "wallet": { + "account": namedAddress("auctioneer"), + "password": consts.l1passphrase, + "pathname": consts.l1keystore + }, + }, + "bid-validator": { + "enable": false + } + } + const autonomousAuctioneerConfigJSON = JSON.stringify(autonomousAuctioneerConfig) + fs.writeFileSync(path.join(consts.configpath, "autonomous_auctioneer_config.json"), autonomousAuctioneerConfigJSON) +} + +function writeBidValidatorConfig(argv: any) { + const bidValidatorConfig = { + "auctioneer-server": { + "enable": false + }, + "bid-validator": { + "auction-contract-address": argv.auctionContract, + "redis-url": "redis://redis:6379", + "sequencer-endpoint": "http://sequencer:8547" + } + } + const bidValidatorConfigJSON = JSON.stringify(bidValidatorConfig) + fs.writeFileSync(path.join(consts.configpath, "bid_validator_config.json"), bidValidatorConfigJSON) +} + export const writeConfigCommand = { command: "write-config", describe: "writes config files", builder: { simple: { - boolean: true, - describe: "simple config (sequencer is also poster, validator)", - default: false, + boolean: true, + describe: "simple config (sequencer is also poster, validator)", + default: false, + }, + eigenda:{ + boolean: true, + default: false, + describe: "config with EigenDA enabled", + }, + anytrust: { + boolean: true, + describe: "run nodes in anytrust mode", + default: false + }, + dasBlsA: { + string: true, + describe: "DAS committee member A BLS pub key", + default: "" + }, + dasBlsB: { + string: true, + describe: "DAS committee member B BLS pub key", + default: "" + }, + timeboost: { + boolean: true, + describe: "run sequencer in timeboost mode", + default: false }, - }, + }, handler: (argv: any) => { writeConfigs(argv) } @@ -420,6 +670,18 @@ export const writeL2ChainConfigCommand = { command: "write-l2-chain-config", describe: "writes l2 chain config file", + builder: { + anytrust: { + boolean: true, + describe: "enable anytrust in chainconfig", + default: false + }, + eigenda:{ + boolean: true, + default: false, + describe: "config with EigenDA enabled", + }, + }, handler: (argv: any) => { writeL2ChainConfig(argv) } @@ -428,7 +690,52 @@ export const writeL3ChainConfigCommand = { command: "write-l3-chain-config", describe: "writes l3 chain config file", + builder: { + eigenda:{ + boolean: true, + default: false, + describe: "config with EigenDA enabled", + }, + }, handler: (argv: any) => { writeL3ChainConfig(argv) } } + +export const writeL2DASCommitteeConfigCommand = { + command: "write-l2-das-committee-config", + describe: "writes daserver committee member config file", + handler: (argv: any) => { + writeL2DASCommitteeConfig(argv) + } +} + +export const writeL2DASMirrorConfigCommand = { + command: "write-l2-das-mirror-config", + describe: "writes daserver mirror config file", + handler: (argv: any) => { + const sequencerInboxAddr = ethers.utils.hexlify(getChainInfo()[0]["rollup"]["sequencer-inbox"]); + writeL2DASMirrorConfig(argv, sequencerInboxAddr) + } +} + +export const writeL2DASKeysetConfigCommand = { + command: "write-l2-das-keyset-config", + describe: "writes DAS keyset config", + builder: { + dasBlsA: { + string: true, + describe: "DAS committee member A BLS pub key", + default: "" + }, + dasBlsB: { + string: true, + describe: "DAS committee member B BLS pub key", + default: "" + }, + }, + handler: (argv: any) => { + writeL2DASKeysetConfig(argv) + } +} +

Added optional observability to the testnode environment:

  • Prometheus agent for collecting service metrics

  • Loki for log collecting

  • PProf on sequencer resources to capture key performance metrics

  • Grafana dashboard to capture key throughput and reliability metrics

Observability can be enabled by passing --monitor to the root level test-node.bash script.

diff --git OffchainLabs/nitro-testnode/grafana/provisioning/dashboards/all.yml Layr-Labs/nitro-testnode/grafana/provisioning/dashboards/all.yml new file mode 100644 index 0000000000000000000000000000000000000000..36fd178a858175095dedcd602d6001c6ecb2f30c --- /dev/null +++ Layr-Labs/nitro-testnode/grafana/provisioning/dashboards/all.yml @@ -0,0 +1,11 @@ +apiVersion: 1 + +providers: + - name: 'default' + orgId: 1 + folder: '' + type: file + disableDeletion: true + editable: true + options: + path: /var/lib/grafana/dashboards \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/grafana/provisioning/datasources/all.yml Layr-Labs/nitro-testnode/grafana/provisioning/datasources/all.yml new file mode 100644 index 0000000000000000000000000000000000000000..af7179f3f86355c624ca71cf77d73f7cbb924d81 --- /dev/null +++ Layr-Labs/nitro-testnode/grafana/provisioning/datasources/all.yml @@ -0,0 +1,15 @@ +apiVersion: 1 + +deleteDatasources: +- name: 'Prometheus' + +datasources: +- access: 'proxy' + editable: true + is_default: true + name: 'Prometheus' + uid: 'ddshms3dlineoe' + org_id: 1 + type: 'prometheus' + url: 'http://prometheus:9090' + version: 1 \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/loki/config.yaml Layr-Labs/nitro-testnode/loki/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..493a9085ebaddd7dabdef2101136d3a97f99998f --- /dev/null +++ Layr-Labs/nitro-testnode/loki/config.yaml @@ -0,0 +1,39 @@ +auth_enabled: false + +server: + http_listen_port: 3200 + +common: + instance_addr: 127.0.0.1 + path_prefix: /loki + storage: + filesystem: + chunks_directory: /loki/chunks + rules_directory: /loki/rules + replication_factor: 1 + ring: + kvstore: + store: inmemory + +schema_config: + configs: + - from: 2020-10-24 + store: tsdb + object_store: filesystem + schema: v13 + index: + prefix: index_ + period: 24h + +# By default, Loki will send anonymous, but uniquely-identifiable usage and configuration +# analytics to Grafana Labs. These statistics are sent to https://stats.grafana.org/ +# +# Statistics help us better understand how Loki is used, and they show us performance +# levels for most users. This helps us prioritize features and documentation. +# For more information on what's sent, look at +# https://github.com/grafana/loki/blob/main/pkg/usagestats/stats.go +# Refer to the buildReport method to see what goes into a report. +# +# If you would like to disable reporting, uncomment the following lines: +#analytics: +# reporting_enabled: false \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/prometheus/prometheus.yml Layr-Labs/nitro-testnode/prometheus/prometheus.yml new file mode 100644 index 0000000000000000000000000000000000000000..52d71cd685d394a10105263c889c6a0464596b63 --- /dev/null +++ Layr-Labs/nitro-testnode/prometheus/prometheus.yml @@ -0,0 +1,41 @@ +global: + scrape_interval: 15s + scrape_timeout: 10s + evaluation_interval: 15s + +scrape_configs: + + - job_name: 'prometheus' + scrape_interval: 5s + static_configs: + - targets: ['localhost:9090'] + + - job_name: 'eigenda_proxy' + honor_timestamps: true + metrics_path: /debug/metrics/prometheus + static_configs: + - targets: ["eigenda_proxy:7300"] + + - job_name: 'sequencer' + honor_timestamps: true + metrics_path: /debug/metrics/prometheus + static_configs: + - targets: ["sequencer:6070"] + + - job_name: 'poster' + honor_timestamps: true + metrics_path: /debug/metrics/prometheus + static_configs: + - targets: ["poster:6070"] + + - job_name: 'validator' + honor_timestamps: true + metrics_path: /debug/metrics/prometheus + static_configs: + - targets: ["validator:6070"] + + - job_name: 'validation_node' + honor_timestamps: true + metrics_path: /debug/metrics/prometheus + static_configs: + - targets: ["validation_node:6070"]
diff --git OffchainLabs/nitro-testnode/promtail/config.yaml Layr-Labs/nitro-testnode/promtail/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f2a6bfd7e859cffde952bf73cc6cb190847a3e7 --- /dev/null +++ Layr-Labs/nitro-testnode/promtail/config.yaml @@ -0,0 +1,21 @@ +server: + http_listen_port: 9080 + grpc_listen_port: 0 + +positions: + filename: /tmp/positions.yaml + +clients: + - url: http://loki:3200/loki/api/v1/push + +scrape_configs: + - job_name: docker + docker_sd_configs: + - host: unix:///var/run/docker.sock + filters: + - name: name + values: ["sequencer", "poster", "validation*", "validator", "eigenda-proxy"] + relabel_configs: + - source_labels: ["__meta_docker_container_name"] + regex: "/(.*)" + target_label: "container" \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/test-node.bash Layr-Labs/nitro-testnode/test-node.bash index dd112c95b5f893e858c2b86c0cd0f935f75f8d3b..62e4c0c0a0bc51874f77904b9c3f19665de5fec5 100755 --- OffchainLabs/nitro-testnode/test-node.bash +++ Layr-Labs/nitro-testnode/test-node.bash @@ -1,22 +1,26 @@ #!/usr/bin/env bash   -set -e +set -eu   -NITRO_NODE_VERSION=offchainlabs/nitro-node:v3.0.1-cf4b74e-dev -BLOCKSCOUT_VERSION=offchainlabs/blockscout:v1.0.0-c8db5b1 +NITRO_NODE_VERSION=ghcr.io/layr-labs/nitro/nitro-node-dev:ethenotethan--update-eigenda-version +BLOCKSCOUT_VERSION=offchainlabs/blockscout:v1.1.0-0e716c8   -# This commit matches the v1.2.1 contracts, with additional support for CacheManger deployment. -# Once v1.2.2 is released, we can switch to that version. -DEFAULT_NITRO_CONTRACTS_VERSION="867663657b98a66b60ff244e46226e0cb368ab94" -DEFAULT_TOKEN_BRIDGE_VERSION="v1.2.1" +DEFAULT_NITRO_CONTRACTS_VERSION="eigenda-v3.1.0" +DEFAULT_TOKEN_BRIDGE_VERSION="v1.2.2" + +# The is the latest bold-merge commit in nitro-contracts at the time +DEFAULT_BOLD_CONTRACTS_VERSION="42d80e40"   # Set default versions if not overriden by provided env vars : ${NITRO_CONTRACTS_BRANCH:=$DEFAULT_NITRO_CONTRACTS_VERSION} +: ${BOLD_CONTRACTS_BRANCH:=$DEFAULT_BOLD_CONTRACTS_VERSION} : ${TOKEN_BRIDGE_BRANCH:=$DEFAULT_TOKEN_BRIDGE_VERSION} export NITRO_CONTRACTS_BRANCH +export BOLD_CONTRACTS_BRANCH export TOKEN_BRIDGE_BRANCH   echo "Using NITRO_CONTRACTS_BRANCH: $NITRO_CONTRACTS_BRANCH" +echo "Using BOLD_CONTRACTS_BRANCH: $BOLD_CONTRACTS_BRANCH" echo "Using TOKEN_BRIDGE_BRANCH: $TOKEN_BRIDGE_BRANCH"   mydir=`dirname $0` @@ -37,22 +41,41 @@ force_init=false fi   run=true -force_build=false +ci=false validate=false detach=false +nowait=false blockscout=false tokenbridge=false l3node=false consensusclient=false +boldupgrade=false redundantsequencers=0 -dev_build_nitro=false -dev_build_blockscout=false l3_custom_fee_token=false +l3_custom_fee_token_pricer=false l3_token_bridge=false +l3_custom_fee_token_decimals=18 batchposters=1 devprivkey=b6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 l1chainid=1337 simple=true +l2anytrust=false +l2timeboost=false + +# Use the dev versions of nitro/blockscout +dev_nitro=false +dev_blockscout=false +dev_contracts=false + +# Rebuild docker images +build_dev_nitro=false +build_dev_blockscout=false +build_utils=false +force_build_utils=false +build_node_images=false + +eigenda=false +monitor=false while [[ $# -gt 0 ]]; do case $1 in --init) @@ -66,10 +89,14 @@ else exit 0 fi fi + build_utils=true + build_node_images=true shift ;; --init-force) force_init=true + build_utils=true + build_node_images=true shift ;; --dev) @@ -77,21 +104,71 @@ simple=false shift if [[ $# -eq 0 || $1 == -* ]]; then # If no argument after --dev, set both flags to true - dev_build_nitro=true - dev_build_blockscout=true + dev_nitro=true + build_dev_nitro=true + dev_blockscout=true + build_dev_blockscout=true else while [[ $# -gt 0 && $1 != -* ]]; do if [[ $1 == "nitro" ]]; then - dev_build_nitro=true + dev_nitro=true + build_dev_nitro=true elif [[ $1 == "blockscout" ]]; then - dev_build_blockscout=true + dev_blockscout=true + build_dev_blockscout=true fi shift done fi + ;; + --dev-contracts) + dev_contracts=true + ;; + --ci) + ci=true + shift ;; --build) - force_build=true + build_dev_nitro=true + build_dev_blockscout=true + build_utils=true + build_node_images=true + shift + ;; + --no-build) + build_dev_nitro=false + build_dev_blockscout=false + build_utils=false + build_node_images=false + shift + ;; + --build-dev-nitro) + build_dev_nitro=true + shift + ;; + --no-build-dev-nitro) + build_dev_nitro=false + shift + ;; + --build-dev-blockscout) + build_dev_blockscout=true + shift + ;; + --no-build-dev-blockscout) + build_dev_blockscout=false + shift + ;; + --build-utils) + build_utils=true + shift + ;; + --no-build-utils) + build_utils=false + shift + ;; + --force-build-utils) + force_build_utils=true + build_utils=true shift ;; --validate) @@ -119,6 +196,14 @@ --detach) detach=true shift ;; + --nowait) + if ! $detach; then + echo "Error: --nowait requires --detach to be provided." + exit 1 + fi + nowait=true + shift + ;; --batchposters) simple=false batchposters=$2 @@ -131,7 +216,11 @@ shift ;; --pos) consensusclient=true - l1chainid=32382 + l1chainid=1337 + shift + ;; + --bold-upgrade) + boldupgrade=true shift ;; --l3node) @@ -146,6 +235,27 @@ fi l3_custom_fee_token=true shift ;; + --l3-fee-token-pricer) + if ! $l3_custom_fee_token; then + echo "Error: --l3-fee-token-pricer requires --l3-fee-token to be provided." + exit 1 + fi + l3_custom_fee_token_pricer=true + shift + ;; + --l3-fee-token-decimals) + if ! $l3_custom_fee_token; then + echo "Error: --l3-fee-token-decimals requires --l3-fee-token to be provided." + exit 1 + fi + l3_custom_fee_token_decimals=$2 + if [[ $l3_custom_fee_token_decimals -lt 0 || $l3_custom_fee_token_decimals -gt 36 ]]; then + echo "l3-fee-token-decimals must be in range [0,36], value: $l3_custom_fee_token_decimals." + exit 1 + fi + shift + shift + ;; --l3-token-bridge) if ! $l3node; then echo "Error: --l3-token-bridge requires --l3node to be provided." @@ -154,6 +264,14 @@ fi l3_token_bridge=true shift ;; + --l2-anytrust) + l2anytrust=true + shift + ;; + --l2-timeboost) + l2timeboost=true + shift + ;; --redundantsequencers) simple=false redundantsequencers=$2 @@ -172,19 +290,35 @@ --no-simple) simple=false shift ;; + --eigenda) + eigenda=true + shift + ;; + --monitor) + prometheus=true + grafana=true + loki=true + promtail=true + shift + ;; *) echo Usage: $0 \[OPTIONS..] echo $0 script [SCRIPT-ARGS] echo echo OPTIONS: echo --build rebuild docker images + echo --no-build don\'t rebuild docker images echo --dev build nitro and blockscout dockers from source instead of pulling them. Disables simple mode + echo --dev-contracts build scripts with local development version of contracts echo --init remove all data, rebuild, deploy new rollup echo --pos l1 is a proof-of-stake chain \(using prysm for consensus\) echo --validate heavy computation, validating all blocks in WASM echo --l3node deploys an L3 node on top of the L2 echo --l3-fee-token L3 chain is set up to use custom fee token. Only valid if also '--l3node' is provided + echo --l3-fee-token-decimals Number of decimals to use for custom fee token. Only valid if also '--l3-fee-token' is provided echo --l3-token-bridge Deploy L2-L3 token bridge. Only valid if also '--l3node' is provided + echo --l2-anytrust run the L2 as an AnyTrust chain + echo --l2-timeboost run the L2 with Timeboost enabled, including auctioneer and bid validator echo --batchposters batch posters [0-3] echo --redundantsequencers redundant sequencers [0-3] echo --detach detach from nodes after running them @@ -194,29 +328,28 @@ echo --tokenbridge deploy L1-L2 token bridge. echo --no-tokenbridge don\'t build or launch tokenbridge echo --no-run does not launch nodes \(useful with build or init\) echo --no-simple run a full configuration with separate sequencer/batch-poster/validator/relayer + echo --build-dev-nitro rebuild dev nitro docker image + echo --no-build-dev-nitro don\'t rebuild dev nitro docker image + echo --build-dev-blockscout rebuild dev blockscout docker image + echo --no-build-dev-blockscout don\'t rebuild dev blockscout docker image + echo --build-utils rebuild scripts, rollupcreator, boldupgrader, token bridge docker images + echo --no-build-utils don\'t rebuild scripts, rollupcreator, boldupgrader, token bridge docker images + echo --force-build-utils force rebuilding utils, useful if NITRO_CONTRACTS_ or TOKEN_BRIDGE_BRANCH changes + echo --eigenda run using EigenDA for data availability + echo --monitor start Prometheus, Loki, Promtail and Grafana server echo echo script runs inside a separate docker. For SCRIPT-ARGS, run $0 script --help exit 0 esac done   -if $force_init; then - force_build=true -fi   -if $dev_build_nitro; then - if [[ "$(docker images -q nitro-node-dev:latest 2> /dev/null)" == "" ]]; then - force_build=true - fi -fi +NODES="sequencer"   -if $dev_build_blockscout; then - if [[ "$(docker images -q blockscout:latest 2> /dev/null)" == "" ]]; then - force_build=true - fi +if $eigenda; then + NODES="$NODES eigenda_proxy" fi   -NODES="sequencer" INITIAL_SEQ_NODES="sequencer"   if ! $simple; then @@ -255,52 +388,71 @@ fi if $blockscout; then NODES="$NODES blockscout" fi -if $force_build; then - echo == Building.. - if $dev_build_nitro; then - if ! [ -n "${NITRO_SRC+set}" ]; then - NITRO_SRC=`dirname $PWD` - fi - if ! grep ^FROM "${NITRO_SRC}/Dockerfile" | grep nitro-node 2>&1 > /dev/null; then - echo nitro source not found in "$NITRO_SRC" - echo execute from a sub-directory of nitro or use NITRO_SRC environment variable - exit 1 - fi - docker build "$NITRO_SRC" -t nitro-node-dev --target nitro-node-dev + +if $monitor; then + NODES="$NODES prometheus grafana loki promtail" +fi + +if $l2timeboost; then + NODES="$NODES timeboost-auctioneer timeboost-bid-validator" +fi + +if $dev_nitro && $build_dev_nitro; then + echo == Building Nitro + if ! [ -n "${NITRO_SRC+set}" ]; then + NITRO_SRC=`dirname $PWD` + fi + if ! grep ^FROM "${NITRO_SRC}/Dockerfile" | grep nitro-node 2>&1 > /dev/null; then + echo nitro source not found in "$NITRO_SRC" + echo execute from a sub-directory of nitro or use NITRO_SRC environment variable + exit 1 fi - if $dev_build_blockscout; then - if $blockscout; then - docker build blockscout -t blockscout -f blockscout/docker/Dockerfile - fi + docker build "$NITRO_SRC" -t nitro-node-dev --target nitro-node-dev +fi +if $dev_blockscout && $build_dev_blockscout; then + if $blockscout; then + echo == Building Blockscout + docker build blockscout -t blockscout -f blockscout/docker/Dockerfile fi +fi   - LOCAL_BUILD_NODES="scripts rollupcreator" - if $tokenbridge || $l3_token_bridge; then +if $build_utils; then + LOCAL_BUILD_NODES="scripts rollupcreator boldupgrader" + # always build tokenbridge in CI mode to avoid caching issues + if $tokenbridge || $l3_token_bridge || $ci; then LOCAL_BUILD_NODES="$LOCAL_BUILD_NODES tokenbridge" fi - docker compose build --no-rm $LOCAL_BUILD_NODES -fi   -if $dev_build_nitro; then +# if [ "$ci" == true ]; then +# # workaround to cache docker layers and keep using docker-compose in CI +# docker buildx bake --allow=fs=/tmp --file docker-compose.yaml --file docker-compose-ci-cache.json $LOCAL_BUILD_NODES +# else + UTILS_NOCACHE="" + if $force_build_utils; then + UTILS_NOCACHE="--no-cache" + fi + docker compose build --no-rm $UTILS_NOCACHE $LOCAL_BUILD_NODES + fi +# fi + +if $dev_nitro; then docker tag nitro-node-dev:latest nitro-node-dev-testnode else docker pull $NITRO_NODE_VERSION docker tag $NITRO_NODE_VERSION nitro-node-dev-testnode fi   -if $dev_build_blockscout; then - if $blockscout; then +if $blockscout; then + if $dev_blockscout; then docker tag blockscout:latest blockscout-testnode - fi -else - if $blockscout; then + else docker pull $BLOCKSCOUT_VERSION docker tag $BLOCKSCOUT_VERSION blockscout-testnode fi fi   -if $force_build; then - docker compose build --no-rm $NODES scripts +if $build_node_images; then + docker compose build --no-rm $NODES fi   if $force_init; then @@ -322,29 +474,32 @@ docker compose run --entrypoint sh geth -c "echo passphrase > /datadir/passphrase" docker compose run --entrypoint sh geth -c "chown -R 1000:1000 /keystore" docker compose run --entrypoint sh geth -c "chown -R 1000:1000 /config"   - if $consensusclient; then - echo == Writing configs - docker compose run scripts write-geth-genesis-config + echo == Writing geth configs + docker compose run scripts write-geth-genesis-config   - echo == Writing configs + if $consensusclient; then + echo == Writing prysm configs docker compose run scripts write-prysm-config   - echo == Initializing go-ethereum genesis configuration - docker compose run geth init --datadir /datadir/ /config/geth_genesis.json + echo == Creating prysm genesis + docker compose run create_beacon_chain_genesis + fi   - echo == Starting geth - docker compose up --wait geth + echo == Initializing go-ethereum genesis configuration + docker compose run geth init --state.scheme hash --datadir /datadir/ /config/geth_genesis.json   - echo == Creating prysm genesis - docker compose up create_beacon_chain_genesis - + if $consensusclient; then echo == Running prysm docker compose up --wait prysm_beacon_chain docker compose up --wait prysm_validator - else - docker compose up --wait geth fi   + echo == Starting geth + docker compose up --wait geth + + echo == Waiting for geth to sync + docker compose run scripts wait-for-sync --url http://geth:8545 + echo == Funding validator, sequencer and l2owner docker compose run scripts send-l1 --ethamount 1000 --to validator --wait docker compose run scripts send-l1 --ethamount 1000 --to sequencer --wait @@ -356,8 +511,13 @@ docker compose run scripts send-l1 --ethamount 0.0001 --from user_l1user --to user_l1user_b --wait --delay 500 --times 1000000 > /dev/null &   l2ownerAddress=`docker compose run scripts print-address --account l2owner | tail -n 1 | tr -d '\r\n'`   - echo == Writing l2 chain config - docker compose run scripts --l2owner $l2ownerAddress write-l2-chain-config + if $l2anytrust; then + echo "== Writing l2 chain config (anytrust enabled)" + docker compose run scripts --l2owner $l2ownerAddress write-l2-chain-config --anytrust --eigenda $eigenda + else + echo == Writing l2 chain config + docker compose run scripts --l2owner $l2ownerAddress write-l2-chain-config --eigenda $eigenda + fi   sequenceraddress=`docker compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'` l2ownerKey=`docker compose run scripts print-private-key --account l2owner | tail -n 1 | tr -d '\r\n'` @@ -365,14 +525,54 @@ wasmroot=`docker compose run --entrypoint sh sequencer -c "cat /home/user/target/machines/latest/module-root.txt"`   echo == Deploying L2 chain docker compose run -e PARENT_CHAIN_RPC="http://geth:8545" -e DEPLOYER_PRIVKEY=$l2ownerKey -e PARENT_CHAIN_ID=$l1chainid -e CHILD_CHAIN_NAME="arb-dev-test" -e MAX_DATA_SIZE=117964 -e OWNER_ADDRESS=$l2ownerAddress -e WASM_MODULE_ROOT=$wasmroot -e SEQUENCER_ADDRESS=$sequenceraddress -e AUTHORIZE_VALIDATORS=10 -e CHILD_CHAIN_CONFIG_PATH="/config/l2_chain_config.json" -e CHAIN_DEPLOYMENT_INFO="/config/deployment.json" -e CHILD_CHAIN_INFO="/config/deployed_chain_info.json" rollupcreator create-rollup-testnode - docker compose run --entrypoint sh rollupcreator -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json" + if $l2timeboost; then + docker compose run --entrypoint sh rollupcreator -c 'jq ".[] | .\"track-block-metadata-from\"=1 | [.]" /config/deployed_chain_info.json > /config/l2_chain_info.json' + else + docker compose run --entrypoint sh rollupcreator -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json" + fi + +fi # $force_init + +anytrustNodeConfigLine="" +timeboostNodeConfigLine="" + +# Remaining init may require AnyTrust committee/mirrors to have been started +if $l2anytrust; then + if $force_init; then + echo == Generating AnyTrust Config + docker compose run --user root --entrypoint sh datool -c "mkdir /das-committee-a/keys /das-committee-a/data /das-committee-a/metadata /das-committee-b/keys /das-committee-b/data /das-committee-b/metadata /das-mirror/data /das-mirror/metadata" + docker compose run --user root --entrypoint sh datool -c "chown -R 1000:1000 /das*" + docker compose run datool keygen --dir /das-committee-a/keys + docker compose run datool keygen --dir /das-committee-b/keys + docker compose run scripts write-l2-das-committee-config + docker compose run scripts write-l2-das-mirror-config   + das_bls_a=`docker compose run --entrypoint sh datool -c "cat /das-committee-a/keys/das_bls.pub"` + das_bls_b=`docker compose run --entrypoint sh datool -c "cat /das-committee-b/keys/das_bls.pub"` + + docker compose run scripts write-l2-das-keyset-config --dasBlsA $das_bls_a --dasBlsB $das_bls_b + docker compose run --entrypoint sh datool -c "/usr/local/bin/datool dumpkeyset --conf.file /config/l2_das_keyset.json | grep 'Keyset: ' | awk '{ printf \"%s\", \$2 }' > /config/l2_das_keyset.hex" + docker compose run scripts set-valid-keyset + + anytrustNodeConfigLine="--anytrust --dasBlsA $das_bls_a --dasBlsB $das_bls_b" + fi + + if $run; then + echo == Starting AnyTrust committee and mirror + docker compose up --wait das-committee-a das-committee-b das-mirror + fi +fi + +if $force_init; then + if $l2timeboost; then + timeboostNodeConfigLine="--timeboost" + fi if $simple; then echo == Writing configs - docker compose run scripts write-config --simple + docker compose run scripts write-config --simple $anytrustNodeConfigLine $timeboostNodeConfigLine --eigenda $eigenda else echo == Writing configs - docker compose run scripts write-config + docker compose run scripts write-config $anytrustNodeConfigLine $timeboostNodeConfigLine --eigenda $eigenda   echo == Initializing redis docker compose up --wait redis @@ -383,11 +583,31 @@ echo == Funding l2 funnel and dev key docker compose up --wait $INITIAL_SEQ_NODES docker compose run scripts bridge-funds --ethamount 100000 --wait docker compose run scripts send-l2 --ethamount 100 --to l2owner --wait + rollupAddress=`docker compose run --entrypoint sh poster -c "jq -r '.[0].rollup.rollup' /config/deployed_chain_info.json | tail -n 1 | tr -d '\r\n'"` + + if $l2timeboost; then + docker compose run scripts send-l2 --ethamount 100 --to auctioneer --wait + biddingTokenAddress=`docker compose run scripts create-erc20 --deployer auctioneer | tail -n 1 | awk '{ print $NF }'` + auctionContractAddress=`docker compose run scripts deploy-express-lane-auction --bidding-token $biddingTokenAddress | tail -n 1 | awk '{ print $NF }'` + auctioneerAddress=`docker compose run scripts print-address --account auctioneer | tail -n1 | tr -d '\r\n'` + echo == Starting up Timeboost auctioneer and bid validator. + echo == Bidding token: $biddingTokenAddress, auction contract $auctionContractAddress + docker compose run scripts write-timeboost-configs --auction-contract $auctionContractAddress + docker compose run --user root --entrypoint sh timeboost-auctioneer -c "chown -R 1000:1000 /data" + + echo == Funding alice and bob user accounts for timeboost testing + docker compose run scripts send-l2 --ethamount 10 --to user_alice --wait + docker compose run scripts send-l2 --ethamount 10 --to user_bob --wait + docker compose run scripts transfer-erc20 --token $biddingTokenAddress --amount 10000 --from auctioneer --to user_alice + docker compose run scripts transfer-erc20 --token $biddingTokenAddress --amount 10000 --from auctioneer --to user_bob + + docker compose run --entrypoint sh scripts -c "sed -i 's/\(\"execution\":{\"sequencer\":{\"enable\":true,\"dangerous\":{\"timeboost\":{\"enable\":\)false/\1true,\"auction-contract-address\":\"$auctionContractAddress\",\"auctioneer-address\":\"$auctioneerAddress\"/' /config/sequencer_config.json" --wait + docker compose restart $INITIAL_SEQ_NODES + fi   if $tokenbridge; then echo == Deploying L1-L2 token bridge sleep 10 # no idea why this sleep is needed but without it the deploy fails randomly - rollupAddress=`docker compose run --entrypoint sh poster -c "jq -r '.[0].rollup.rollup' /config/deployed_chain_info.json | tail -n 1 | tr -d '\r\n'"` docker compose run -e ROLLUP_OWNER_KEY=$l2ownerKey -e ROLLUP_ADDRESS=$rollupAddress -e PARENT_KEY=$devprivkey -e PARENT_RPC=http://geth:8545 -e CHILD_KEY=$devprivkey -e CHILD_RPC=http://sequencer:8547 tokenbridge deploy:local:token-bridge docker compose run --entrypoint sh tokenbridge -c "cat network.json && cp network.json l1l2_network.json && cp network.json localNetwork.json" echo @@ -396,6 +616,22 @@ echo == Deploy CacheManager on L2 docker compose run -e CHILD_CHAIN_RPC="http://sequencer:8547" -e CHAIN_OWNER_PRIVKEY=$l2ownerKey rollupcreator deploy-cachemanager-testnode   + # NOTE: Disabling script due to high bug frequency and limited correctness guarantees + # if $boldupgrade; then + # echo == Deploying WETH as BOLD stake token + # stakeTokenAddress=`docker compose run scripts create-weth --deployer l2owner --deposit 100 | tail -n 1 | awk '{ print $NF }'` + # echo BOLD stake token address: $stakeTokenAddress + # docker compose run scripts transfer-erc20 --token $stakeTokenAddress --l1 --amount 100 --from l2owner --to validator + # echo == Preparing BOLD upgrade + # docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-prepare + # # retry this 10 times because the staker might not have made a node yet + # for i in {1..10}; do + # docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-populate-lookup && break || true + # echo "Failed to populate lookup table, retrying..." + # sleep 10 + # done + # docker compose run -e TESTNODE_MODE=true -e ROLLUP_ADDRESS=$rollupAddress -e STAKE_TOKEN=$stakeTokenAddress boldupgrader script:bold-local-execute + # fi   if $l3node; then echo == Funding l3 users @@ -417,13 +653,20 @@ echo == Writing l3 chain config l3owneraddress=`docker compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` echo l3owneraddress $l3owneraddress - docker compose run scripts --l2owner $l3owneraddress write-l3-chain-config + docker compose run scripts --l2owner $l3owneraddress write-l3-chain-config --eigenda $eigenda   + EXTRA_L3_DEPLOY_FLAG="" if $l3_custom_fee_token; then echo == Deploying custom fee token - nativeTokenAddress=`docker compose run scripts create-erc20 --deployer user_fee_token_deployer --mintTo user_token_bridge_deployer --bridgeable $tokenbridge | tail -n 1 | awk '{ print $NF }'` - docker compose run scripts transfer-erc20 --token $nativeTokenAddress --amount 100 --from user_token_bridge_deployer --to l3owner + nativeTokenAddress=`docker compose run scripts create-erc20 --deployer user_fee_token_deployer --bridgeable $tokenbridge --decimals $l3_custom_fee_token_decimals | tail -n 1 | awk '{ print $NF }'` + docker compose run scripts transfer-erc20 --token $nativeTokenAddress --amount 10000 --from user_fee_token_deployer --to l3owner + docker compose run scripts transfer-erc20 --token $nativeTokenAddress --amount 10000 --from user_fee_token_deployer --to user_token_bridge_deployer EXTRA_L3_DEPLOY_FLAG="-e FEE_TOKEN_ADDRESS=$nativeTokenAddress" + if $l3_custom_fee_token_pricer; then + echo == Deploying custom fee token pricer + feeTokenPricerAddress=`docker compose run scripts create-fee-token-pricer --deployer user_fee_token_deployer | tail -n 1 | awk '{ print $NF }'` + EXTRA_L3_DEPLOY_FLAG="$EXTRA_L3_DEPLOY_FLAG -e FEE_TOKEN_PRICER_ADDRESS=$feeTokenPricerAddress" + fi fi   echo == Deploying L3 @@ -448,18 +691,22 @@ l2Weth=`docker compose run --entrypoint sh tokenbridge -c "cat l1l2_network.json" | jq -r '.l2Network.tokenBridge.l2Weth'` fi docker compose run -e PARENT_WETH_OVERRIDE=$l2Weth -e ROLLUP_OWNER_KEY=$l3ownerkey -e ROLLUP_ADDRESS=$rollupAddress -e PARENT_RPC=http://sequencer:8547 -e PARENT_KEY=$deployer_key -e CHILD_RPC=http://l3node:3347 -e CHILD_KEY=$deployer_key tokenbridge deploy:local:token-bridge docker compose run --entrypoint sh tokenbridge -c "cat network.json && cp network.json l2l3_network.json" + + # set L3 UpgradeExecutor, deployed by token bridge creator in previous step, to be the L3 chain owner. L3owner (EOA) and alias of L2 UpgradeExectuor have the executor role on the L3 UpgradeExecutor + echo == Set L3 UpgradeExecutor to be chain owner + tokenBridgeCreator=`docker compose run --entrypoint sh tokenbridge -c "cat l2l3_network.json" | jq -r '.l1TokenBridgeCreator'` + docker compose run scripts transfer-l3-chain-ownership --creator $tokenBridgeCreator echo fi   echo == Fund L3 accounts if $l3_custom_fee_token; then - docker compose run scripts bridge-native-token-to-l3 --amount 50000 --from user_token_bridge_deployer --wait - docker compose run scripts send-l3 --ethamount 500 --from user_token_bridge_deployer --wait - docker compose run scripts send-l3 --ethamount 500 --from user_token_bridge_deployer --to "key_0x$devprivkey" --wait + docker compose run scripts bridge-native-token-to-l3 --amount 5000 --from user_fee_token_deployer --wait + docker compose run scripts send-l3 --ethamount 100 --from user_fee_token_deployer --wait else docker compose run scripts bridge-to-l3 --ethamount 50000 --wait fi - docker compose run scripts send-l3 --ethamount 100 --to l3owner --wait + docker compose run scripts send-l3 --ethamount 10 --to l3owner --wait   echo == Deploy CacheManager on L3 docker compose run -e CHILD_CHAIN_RPC="http://l3node:3347" -e CHAIN_OWNER_PRIVKEY=$l3ownerkey rollupcreator deploy-cachemanager-testnode @@ -470,7 +717,11 @@ if $run; then UP_FLAG="" if $detach; then - UP_FLAG="--wait" + if $nowait; then + UP_FLAG="--detach" + else + UP_FLAG="--wait" + fi fi   echo == Launching Sequencer

Added a flood.ts script which generates tx traffic targeting a specific byte rate.

E.g:

  docker compose run scripts flood --serial true --rounds 1000 --targetThroughput 100_000

This will target 100,000 Kb/s.

diff --git OffchainLabs/nitro-testnode/scripts/flood.ts Layr-Labs/nitro-testnode/scripts/flood.ts new file mode 100644 index 0000000000000000000000000000000000000000..002af3ade68d0dbb7a5dc90458c637a5ce1867e2 --- /dev/null +++ Layr-Labs/nitro-testnode/scripts/flood.ts @@ -0,0 +1,149 @@ +import { runStress } from './stress'; +import { ethers } from 'ethers'; +import { namedAccount, namedAddress } from './accounts'; + +function randomInRange(maxSize: number): number { + return Math.ceil(Math.random() * maxSize); +} + +function generateRandomBytes(size: number): string { + let result = ''; + const hexChars = '0123456789abcdef'; + for (let i = 0; i < size; i++) { + const byte = Math.floor(Math.random() * 256); + result += hexChars[(byte >> 4) & 0xf] + hexChars[byte & 0xf]; // Convert byte to two hex characters + } + return result; +} + +function generateRandomHexData(size: number): string { + return '0x' + generateRandomBytes(size); +} + +async function sendTransaction(argv: any, threadId: number) { + console.log("sending tx from", argv.from, "to", argv.to) + const account = namedAccount(argv.from, threadId).connect(argv.provider) + const startNonce = await account.getTransactionCount("pending") + const response = await + account.sendTransaction({ + to: namedAddress(argv.to, threadId), + value: ethers.utils.parseEther(argv.ethamount), + data: argv.data, + nonce: startNonce, + }) + console.log(response) + if (argv.wait) { + const receipt = await response.wait() + console.log(receipt) + } + if (argv.delay > 0) { + await new Promise(f => setTimeout(f, argv.delay)); + } +} + +// flood simulation +async function simulateNetworkFlood(argv: any) { + // fund the users + console.log(`fund all users`) + const funding_argv = { + ...argv, + ethamount: "100", + threads: 1, + wait: true, + from: `funnel` + } + for (let i = 0; i <= argv.user_count; i++) { + funding_argv.to = `user_${i}` + await runStress(funding_argv, sendTransaction) + } + + console.log(`start sending transactions`) + argv.ethamount = "0.0001" + + // throughput / threads = avg tx size < 127size + // if throughput target is set, we will not respect the maxTxDataSize setting + if (argv.targetThroughput > 0) { + argv.delay = 1000 // 1 second delay + // We don't care about the float throughput, just send 1 more transaction of the same average size + argv.threads = argv.targetThroughput > 125_000 ? argv.targetThroughput / 125_000 + 1 : 1 + const size = argv.targetThroughput / argv.threads + for (let i = 0; i < argv.rounds; i++) { + argv.from = `user_${randomInRange(argv.user_count)}`; + argv.to = `user_${randomInRange(argv.user_count)}`; // don't care if sending to self + argv.data = generateRandomHexData(size); + + console.log(`prepared transactions`, { transaction_count: i, size: size, argv: argv }) + const startTime = Date.now(); + runStress(argv, sendTransaction); + const timeSpent = Date.now() - startTime; + const secondsTick = Math.max(0, 1000 - timeSpent); + await new Promise(resolve => setTimeout(resolve, secondsTick)); + } + } else { + for (let i = 0; i < argv.rounds; i++) { + argv.from = `user_${randomInRange(argv.user_count)}`; + argv.to = `user_${randomInRange(argv.user_count)}`; // don't care if sending to self + argv.threads = randomInRange(argv.threads) + const size = randomInRange(argv.maxTxDataSize) + argv.data = generateRandomHexData(size); + + console.log(`prepared transactions`, { transaction_count: i, size: size, argv: argv }) + await runStress(argv, sendTransaction); + } + } +} + +export const floodCommand = { + command: "flood", + describe: "Simulates network activity by sending arbitrary transactions among random user_count", + builder: { + user_count: { + number: true, + describe: "Number of active user_count", + default: 10, + }, + rounds: { + number: true, + describe: "Number of rounds of transactions to send (total transactions = rounds * threads); if targetThroughput rate is set, rounds should represents the total second of the tests", + default: 12000, + }, + // this is something we can read from the rollup creator + maxTxDataSize: { + number: true, + describe: "Maximum transaction data size in bytes", + default: 58982, + }, + threads: { + number: true, + describe: "Number of threads per transaction", + default: 100, + }, + delay: { + number: true, + describe: "Delay between transactions in milliseconds", + default: 0, + }, + serial: { + boolean: true, + describe: "Run transactions serially (in sequence)", + default: false, + }, + wait: { + boolean: true, + describe: "Wait for transaction confirmations", + default: false, + }, + targetThroughput: { + number: true, + describe: "Target throughput in total transactions data size sent per second; if this is set, number of threads will be disregarded (Default is 16kb)", + default: 0, + }, + }, + handler: async (argv: any) => { + argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + await simulateNetworkFlood(argv); + argv.provider.destroy(); + + }, +}; +
diff --git OffchainLabs/nitro-testnode/scripts/index.ts Layr-Labs/nitro-testnode/scripts/index.ts index 2fd189f6110252c29f9007cbce64ece090a70d5d..889af67df4587405b1ea698b5ab32b19793db565 100644 --- OffchainLabs/nitro-testnode/scripts/index.ts +++ Layr-Labs/nitro-testnode/scripts/index.ts @@ -2,7 +2,17 @@ import { hideBin } from "yargs/helpers"; import Yargs from "yargs/yargs"; import { stressOptions } from "./stress"; import { redisReadCommand, redisInitCommand } from "./redis"; -import { writeConfigCommand, writeGethGenesisCommand, writePrysmCommand, writeL2ChainConfigCommand, writeL3ChainConfigCommand } from "./config"; +import { + writeConfigCommand, + writeGethGenesisCommand, + writePrysmCommand, + writeL2ChainConfigCommand, + writeL3ChainConfigCommand, + writeL2DASCommitteeConfigCommand, + writeL2DASMirrorConfigCommand, + writeL2DASKeysetConfigCommand, + writeTimeboostConfigsCommand +} from "./config"; import { printAddressCommand, namedAccountHelpString, @@ -14,12 +24,19 @@ bridgeFundsCommand, bridgeNativeTokenToL3Command, bridgeToL3Command, createERC20Command, + deployExpressLaneAuctionContractCommand, + createWETHCommand, transferERC20Command, sendL1Command, sendL2Command, sendL3Command, sendRPCCommand, + setValidKeysetCommand, + waitForSyncCommand, + transferL3ChainOwnershipCommand, + createFeeTokenPricerCommand, } from "./ethcommands"; +import { floodCommand } from "./flood";   async function main() { await Yargs(hideBin(process.argv)) @@ -30,27 +47,39 @@ l2url: { string: true, default: "ws://sequencer:8548" }, l3url: { string: true, default: "ws://l3node:3348" }, validationNodeUrl: { string: true, default: "ws://validation_node:8549" }, l2owner: { string: true, default: "0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E" }, + committeeMember: { string: true, default: "not_set" }, }) .options(stressOptions) .command(bridgeFundsCommand) .command(bridgeToL3Command) .command(bridgeNativeTokenToL3Command) .command(createERC20Command) + .command(createFeeTokenPricerCommand) + .command(deployExpressLaneAuctionContractCommand) + .command(createWETHCommand) .command(transferERC20Command) .command(sendL1Command) .command(sendL2Command) .command(sendL3Command) .command(sendRPCCommand) + .command(floodCommand) + .command(setValidKeysetCommand) + .command(transferL3ChainOwnershipCommand) .command(writeConfigCommand) .command(writeGethGenesisCommand) .command(writeL2ChainConfigCommand) .command(writeL3ChainConfigCommand) + .command(writeL2DASCommitteeConfigCommand) + .command(writeL2DASMirrorConfigCommand) + .command(writeL2DASKeysetConfigCommand) .command(writePrysmCommand) .command(writeAccountsCommand) + .command(writeTimeboostConfigsCommand) .command(printAddressCommand) .command(printPrivateKeyCommand) .command(redisReadCommand) .command(redisInitCommand) + .command(waitForSyncCommand) .strict() .demandCommand(1, "a command must be specified") .epilogue(namedAccountHelpString)
diff --git OffchainLabs/nitro-testnode/.clabot Layr-Labs/nitro-testnode/.clabot new file mode 100644 index 0000000000000000000000000000000000000000..55cb5e6179c3c9327e96d53274e481562838d22d --- /dev/null +++ Layr-Labs/nitro-testnode/.clabot @@ -0,0 +1,5 @@ +{ + "contributors": "https://api.github.com/repos/OffchainLabs/clabot-config/contents/nitro-contributors.json", + "message": "We require contributors to sign our Contributor License Agreement. In order for us to review and merge your code, please sign the linked documents below to get yourself added. https://na3.docusign.net/Member/PowerFormSigning.aspx?PowerFormId=b15c81cc-b5ea-42a6-9107-3992526f2898&env=na3&acct=6e152afc-6284-44af-a4c1-d8ef291db402&v=2", + "label": "s" +}
diff --git OffchainLabs/nitro-testnode/.github/workflows/ci.yml Layr-Labs/nitro-testnode/.github/workflows/ci.yml index a78e451ce5c2c9cd54de4268a3194ee519c12d1f..1f104f404ae6a9dd3e65ac1d8e2a0d9cf3665d24 100644 --- OffchainLabs/nitro-testnode/.github/workflows/ci.yml +++ Layr-Labs/nitro-testnode/.github/workflows/ci.yml @@ -2,36 +2,72 @@ name: CI run-name: CI triggered from @${{ github.actor }} of ${{ github.head_ref }}   on: - workflow_dispatch: - merge_group: - pull_request: - push: - branches: - - master - - develop - + workflow_dispatch: + merge_group: + pull_request: + push: + branches: + - master + - main + - develop + - release + # run this job on the default branch daily + # the docker compose file contains some images with tags like 'latest' and 'stable' + # we nightly run here just to double check no bugs have been merged into those tags and are now on release + schedule: + - cron: '0 0 * * *'   jobs: build_and_run: - runs-on: ubuntu-8 + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + pos: [pos, no-pos] + l3node: [l3node, l3node-token-6, no-l3node] + tokenbridge: [tokenbridge, no-tokenbridge] + simple: [simple, no-simple] + eigenda: [eigenda, no-eigenda]   steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive   - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - driver-opts: network=host + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host   - - name: Cache Docker layers - uses: actions/cache@v3 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ hashFiles('Dockerfile') }} - restore-keys: ${{ runner.os }}-buildx- - - - name: Startup Nitro testnode - run: ${{ github.workspace }}/.github/workflows/testnode.bash + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache-eigenda + key: ${{ runner.os }}-buildx-${{ hashFiles('**/Dockerfile') }} + restore-keys: ${{ runner.os }}-buildx- + + - name: Startup Nitro testnode + env: + EIGENDA_SIGNER_PRIVATE_KEY: ${{ secrets.EIGENDA_SIGNER_PRIVATE_KEY }} + run: EIGENDA_SIGNER_PRIVATE_KEY=$EIGENDA_SIGNER_PRIVATE_KEY ${{ github.workspace }}/.github/workflows/testnode.bash --init-force ${{ (matrix.l3node == 'l3node' && '--l3node') || (matrix.l3node == 'l3node-token-6' && '--l3node --l3-fee-token --l3-token-bridge --l3-fee-token-decimals 6') || '' }} ${{ matrix.tokenbridge == 'tokenbridge' && '--tokenbridge' || '--no-tokenbridge' }} --detach ${{ matrix.pos == 'pos' && '--pos' || '' }} --simple ${{ (matrix.simple == 'simple' && '--simple') || (matrix.simple == 'no-simple' && '--no-simple') || '' }} ${{ matrix.eigenda == 'eigenda' && '--eigenda' || '' }} + + # # NOTE: Disabling script due to high bug frequency and limited correctness guarantees + # bold_upgrade: + # runs-on: ubuntu-latest + + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + # with: + # submodules: recursive + + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v3 + # with: + # driver-opts: network=host + + # - name: Startup Nitro testnode + # env: + # EIGENDA_SIGNER_PRIVATE_KEY: ${{ secrets.EIGENDA_SIGNER_PRIVATE_KEY }} + # run: EIGENDA_SIGNER_PRIVATE_KEY=$EIGENDA_SIGNER_PRIVATE_KEY ${{ github.workspace }}/.github/workflows/testnode.bash --init-force --bold-upgrade --simple --detach
diff --git OffchainLabs/nitro-testnode/.github/workflows/pages.yml Layr-Labs/nitro-testnode/.github/workflows/pages.yml new file mode 100644 index 0000000000000000000000000000000000000000..21b6e1c250f3245a98af627d741f749ffc97aeb8 --- /dev/null +++ Layr-Labs/nitro-testnode/.github/workflows/pages.yml @@ -0,0 +1,47 @@ +name: Build and publish forkdiff github-pages +permissions: + contents: read + pages: write + id-token: write +on: + push: + branches: + - main + +jobs: + build: + concurrency: ci-${{ github.ref }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 1000 # make sure to fetch the old commit we diff against + + - name: Build forkdiff + uses: "docker://protolambda/forkdiff:0.1.0" + with: + args: -repo=/github/workspace -fork=/github/workspace/fork.yaml -out=/github/workspace/index.html + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Build with Jekyll + uses: actions/jekyll-build-pages@v1 + with: + source: ./ + destination: ./_site + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/.github/workflows/testnode.bash Layr-Labs/nitro-testnode/.github/workflows/testnode.bash index 0e57e13d00e186b65895a45613715a1925a7ed5d..63e5edf31f3444b8f29a4dd3f1b562f5ff7a6799 100755 --- OffchainLabs/nitro-testnode/.github/workflows/testnode.bash +++ Layr-Labs/nitro-testnode/.github/workflows/testnode.bash @@ -5,24 +5,36 @@ # Start the test node and get PID, to terminate it once send-l2 is done. cd ${GITHUB_WORKSPACE}   -# TODO once develop is merged into nitro-contract's master, remove the NITRO_CONTRACTS_BRANCH env var -./test-node.bash --init-force --l3node --no-simple --detach +./test-node.bash "$@" --ci + +if [ $? -ne 0 ]; then + echo "test-node.bash failed" + docker compose logs --tail=1000 + exit 1 +fi +   START=$(date +%s) L2_TRANSACTION_SUCCEEDED=false -L3_TRANSACTION_SUCCEEDED=false +# if we're not running an l3node then we just set l3 to success by default +L3_TRANSACTION_SUCCEEDED=true +for arg in "$@"; do + if [ "$arg" = "--l3node" ]; then + L3_TRANSACTION_SUCCEEDED=false + fi +done SUCCEEDED=false   while true; do if [ "$L2_TRANSACTION_SUCCEEDED" = false ]; then - if ${GITHUB_WORKSPACE}/test-node.bash script send-l2 --ethamount 100 --to user_l2user --wait; then + if ${GITHUB_WORKSPACE}/test-node.bash script send-l2 --ethamount 2 --to user_l2user --wait; then echo "Sending l2 transaction succeeded" L2_TRANSACTION_SUCCEEDED=true fi fi   if [ "$L3_TRANSACTION_SUCCEEDED" = false ]; then - if ${GITHUB_WORKSPACE}/test-node.bash script send-l3 --ethamount 100 --to user_l3user --wait; then + if ${GITHUB_WORKSPACE}/test-node.bash script send-l3 --ethamount 2 --to user_l3user --wait; then echo "Sending l3 transaction succeeded" L3_TRANSACTION_SUCCEEDED=true fi @@ -44,10 +56,10 @@ sleep 10 done   -docker-compose stop +docker compose stop   if [ "$SUCCEEDED" = false ]; then - docker-compose logs + docker compose logs exit 1 fi
diff --git OffchainLabs/nitro-testnode/.gitignore Layr-Labs/nitro-testnode/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..dbe9c82b3610ccd58d1c681848dcd322e500051e --- /dev/null +++ Layr-Labs/nitro-testnode/.gitignore @@ -0,0 +1 @@ +.vscode/ \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/README.md Layr-Labs/nitro-testnode/README.md index e8c3983d37faf340adf3dd0e6c6c8e3b84bcead0..c61ae520231194e302aa5f7edd2c8f17e8948739 100644 --- OffchainLabs/nitro-testnode/README.md +++ Layr-Labs/nitro-testnode/README.md @@ -46,6 +46,44 @@ To see more options, use `--help`.   ## Further information   +### Branch Selection Guide (for devs working *on* nitro-testnode) + +This repository maintains two main branches with distinct purposes. + +#### `release` branch + +Target branch for changes that should be immediately available to external users. + +**Examples of changes for `release`:** +* Bug fixes for existing functionality +* Documentation improvements +* Updates to support newly released Nitro features +* Configuration updates for published Nitro releases + +> 💡 Changes here will later be merged into `master` + +#### `master` branch + +Target branch for changes supporting unreleased Nitro features. + +**Examples of changes for `master`:** +* Support for new configuration options being developed in Nitro +* Integration tests for upcoming Nitro features +* Breaking changes that depend on unreleased Nitro versions + +> 💡 Changes here will be merged into `release` when the corresponding Nitro features are released + +#### Branch Flow + +##### For immediate public consumption +1. Push to `release` +2. Later merge into `master` + +##### For unreleased Nitro features +1. Push to `master` +2. Merge into `release` when the feature is released + + ### Working with docker containers   **sequencer** is the main docker to be used to access the nitro testchain. It's http and websocket interfaces are exposed at localhost ports 8547 and 8548 ports, respectively.
diff --git OffchainLabs/nitro-testnode/boldupgrader/Dockerfile Layr-Labs/nitro-testnode/boldupgrader/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..f3efd0e231bc63def5aeca6c635d74aacebd4755 --- /dev/null +++ Layr-Labs/nitro-testnode/boldupgrader/Dockerfile @@ -0,0 +1,14 @@ +FROM node:20-bookworm-slim +RUN apt-get update && \ + apt-get install -y git docker.io python3 make gcc g++ curl jq +ARG BOLD_CONTRACTS_BRANCH=bold-merge-script +WORKDIR /workspace +RUN git clone --no-checkout https://github.com/Layr-Labs/nitro-contracts.git ./ +RUN git checkout f6dd563ab81124a811ac3a660082897b04736196 +RUN yarn install && yarn cache clean +RUN curl -L https://foundry.paradigm.xyz | bash +ENV PATH="${PATH}:/root/.foundry/bin" +RUN foundryup --install 1.0.0 +RUN touch scripts/config.ts +RUN yarn build:all +ENTRYPOINT ["yarn"] \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/docker-compose-ci-cache.json Layr-Labs/nitro-testnode/docker-compose-ci-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..f2f3d908dec50c8c6c5afb48a0638c8c6037decd --- /dev/null +++ Layr-Labs/nitro-testnode/docker-compose-ci-cache.json @@ -0,0 +1,48 @@ +{ + "target": { + "scripts": { + "cache-from": [ + "type=local,src=/tmp/.buildx-cache-eigenda" + ], + "cache-to": [ + "type=local,dest=/tmp/.buildx-cache-eigenda,mode=max" + ], + "output": [ + "type=docker" + ] + }, + "rollupcreator": { + "cache-from": [ + "type=local,src=/tmp/.buildx-cache-eigenda" + ], + "cache-to": [ + "type=local,dest=/tmp/.buildx-cache-eigenda,mode=max" + ], + "output": [ + "type=docker" + ] + }, + "boldupgrader": { + "cache-from": [ + "type=local,src=/tmp/.buildx-cache-eigenda" + ], + "cache-to": [ + "type=local,dest=/tmp/.buildx-cache-eigenda,mode=max" + ], + "output": [ + "type=docker" + ] + }, + "tokenbridge": { + "cache-from": [ + "type=local,src=/tmp/.buildx-cache-eigenda" + ], + "cache-to": [ + "type=local,dest=/tmp/.buildx-cache-eigenda,mode=max" + ], + "output": [ + "type=docker" + ] + } + } +}
diff --git OffchainLabs/nitro-testnode/fork.yaml Layr-Labs/nitro-testnode/fork.yaml new file mode 100644 index 0000000000000000000000000000000000000000..76dcf4233b4380a7548d28cb0d327f12dd9153b9 --- /dev/null +++ Layr-Labs/nitro-testnode/fork.yaml @@ -0,0 +1,78 @@ +title: "layr-labs/nitro-testnode" # Define the HTML page title +logo: "logo.png" +footer: | # define the footer with markdown + [Nitro Testnode](https://github.com/Layr-Labs/nitro-testnode) fork overview &middot created with [Forkdiff](https://github.com/protolambda/forkdiff) +base: + name: OffchainLabs/nitro-testnode + url: https://github.com/OffchainLabs/nitro-testnode + hash: f328006579cbefe22c6c57de3d6b86397fde4438 +fork: + name: Layr-Labs/nitro-testnode + url: https://github.com/Layr-Labs/nitro-testnode + ref: refs/heads/main + +def: + title: "Nitro Testnode Fork Diff" + description: | # description in markdown + The original nitro codebase can be found at [`github.com/OffchainLabs/nitro-testnode`](https://github.com/OffchainLabs/nitro). + And the fork at [`github.com/Layr-Labs/nitro-testnode`](https://github.com/Layr-Labs/nitro). + + sub: + + - title: "EigenDA Support" + description: | + Added support for EigenDA: + + - Updated config generation script to express EigenDA chain params + + - Updated rollup creator deployment script to target `layr-labs/nitro-contracts` + + - Updated core docker compose to wire EigenDA proxy dependency + + globs: + - "scripts/config.ts" + - "rollupcreator/Dockerfile" + - "docker-compose.yaml" + + - title: "Observability" + description: | + Added optional observability to the testnode environment: + + - Prometheus agent for collecting service metrics + + - Loki for log collecting + + - PProf on sequencer resources to capture key performance metrics + + - Grafana dashboard to capture key throughput and reliability metrics + + Observability can be enabled by passing `--monitor` to the root level `test-node.bash` script. + + globs: + - "loki/**" + - "grafana/**" + - "prometheus/**" + - "promtail/**" + - "test-node.bash" + + - title: "Throughput Testing" + description: | + Added a `flood.ts` script which generates tx traffic targeting a specific byte rate. + + E.g: + ``` + docker compose run scripts flood --serial true --rounds 1000 --targetThroughput 100_000 + ``` + + This will target 100,000 Kb/s. + + globs: + - "scripts/index.ts" + - "scripts/flood.ts" + + + + + +ignore: + - "grafana/dashboards/Throughput-testing.json"
diff --git OffchainLabs/nitro-testnode/scripts/Dockerfile Layr-Labs/nitro-testnode/scripts/Dockerfile index c5b7050c29c189fd4d51c3d35c8f5ed75b97f45a..5ef046283aa9eda63e9b6acaa091fd3bdf9ea24b 100644 --- OffchainLabs/nitro-testnode/scripts/Dockerfile +++ Layr-Labs/nitro-testnode/scripts/Dockerfile @@ -1,7 +1,15 @@ -FROM node:16-bullseye-slim +# Stage 1: Base build environment +FROM node:20-bookworm-slim AS base WORKDIR /workspace COPY ./package.json ./yarn.lock ./ RUN yarn + +# Stage 2: Copy files and run build +FROM base AS pre-build COPY ./*.ts ./tsconfig.json ./ +RUN echo "Intermediate image created before yarn build" + +# Stage 3: Final build +FROM pre-build AS final RUN yarn build ENTRYPOINT ["node", "index.js"]
diff --git OffchainLabs/nitro-testnode/scripts/accounts.ts Layr-Labs/nitro-testnode/scripts/accounts.ts index 20c1cbbed9edcd28098fc32e72b1fe20afff9ce8..233d5f49a87114be6eef694406b908cbd63b8c7f 100644 --- OffchainLabs/nitro-testnode/scripts/accounts.ts +++ Layr-Labs/nitro-testnode/scripts/accounts.ts @@ -5,7 +5,7 @@ import * as crypto from "crypto"; import { runStress } from "./stress"; const path = require("path");   -const specialAccounts = 6; +const specialAccounts = 7;   async function writeAccounts() { for (let i = 0; i < specialAccounts; i++) { @@ -47,6 +47,9 @@ } if (name == "l2owner") { return specialAccount(5); } + if (name == "auctioneer") { + return specialAccount(6); + } if (name.startsWith("user_")) { return new ethers.Wallet( ethers.utils.sha256(ethers.utils.toUtf8Bytes(name)) @@ -85,7 +88,8 @@ }   export const namedAccountHelpString = "Valid account names:\n" + - " funnel | sequencer | validator | l2owner - known keys used by l2\n" + + " funnel | sequencer | validator | l2owner\n" + + " | auctioneer - known keys used by l2\n" + " l3owner | l3sequencer - known keys used by l3\n" + " user_[Alphanumeric] - key will be generated from username\n" + " threaduser_[Alphanumeric] - same as user_[Alphanumeric]_thread_[thread-id]\n" +
diff --git OffchainLabs/nitro-testnode/scripts/consts.ts Layr-Labs/nitro-testnode/scripts/consts.ts index ff322260f06c876bf197efba229c47683319425d..edfcedd6d91bf23401bdbb5eeb834c02905030e2 100644 --- OffchainLabs/nitro-testnode/scripts/consts.ts +++ Layr-Labs/nitro-testnode/scripts/consts.ts @@ -5,3 +5,5 @@ export const tokenbridgedatapath = "/tokenbridge-data"; // Not secure. Do not use for production purposes export const l1mnemonic = "indoor dish desk flag debris potato excuse depart ticket judge file exit"; + +export const ARB_OWNER = "0x0000000000000000000000000000000000000070"; \ No newline at end of file
diff --git OffchainLabs/nitro-testnode/scripts/ethcommands.ts Layr-Labs/nitro-testnode/scripts/ethcommands.ts index 82eeadbc417eb85b4c89b8e9febfa871328ed106..27984cb516dd53e7f66042dc0830103046ac447b 100644 --- OffchainLabs/nitro-testnode/scripts/ethcommands.ts +++ Layr-Labs/nitro-testnode/scripts/ethcommands.ts @@ -1,11 +1,15 @@ import { runStress } from "./stress"; -import { ContractFactory, ethers, Wallet } from "ethers"; +import { BigNumber, ContractFactory, ethers, Wallet } from "ethers"; import * as consts from "./consts"; import { namedAccount, namedAddress } from "./accounts"; import * as L1GatewayRouter from "@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/ethereum/gateway/L1GatewayRouter.sol/L1GatewayRouter.json"; -import * as ERC20PresetFixedSupplyArtifact from "@openzeppelin/contracts/build/contracts/ERC20PresetFixedSupply.json"; +import * as L1AtomicTokenBridgeCreator from "@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/ethereum/L1AtomicTokenBridgeCreator.sol/L1AtomicTokenBridgeCreator.json"; import * as ERC20 from "@openzeppelin/contracts/build/contracts/ERC20.json"; +import * as TestWETH9 from "@arbitrum/token-bridge-contracts/build/contracts/contracts/tokenbridge/test/TestWETH9.sol/TestWETH9.json"; import * as fs from "fs"; +import { ARB_OWNER } from "./consts"; +import * as TransparentUpgradeableProxy from "@openzeppelin/contracts/build/contracts/TransparentUpgradeableProxy.json" +import * as ExpressLaneAuctionContract from "@arbitrum/nitro-contracts/build/contracts/src/express-lane-auction/ExpressLaneAuction.sol/ExpressLaneAuction.json" const path = require("path");   async function sendTransaction(argv: any, threadId: number) { @@ -59,25 +63,49 @@ argv.provider = new ethers.providers.WebSocketProvider(parentChainUrl);   argv.to = "address_" + inboxAddr;   - /// approve inbox to use fee token + // snapshot balance before deposit + const childProvider = new ethers.providers.WebSocketProvider(chainUrl); + const bridger = namedAccount(argv.from, argv.threadId).connect(childProvider) + const bridgerBalanceBefore = await bridger.getBalance() + + // get token contract const bridgerParentChain = namedAccount(argv.from, argv.threadId).connect(argv.provider) const nativeTokenContract = new ethers.Contract(token, ERC20.abi, bridgerParentChain) - await nativeTokenContract.approve(inboxAddr, ethers.utils.parseEther(argv.amount)) + + // scale deposit amount + const decimals = await nativeTokenContract.decimals() + const depositAmount = BigNumber.from(argv.amount).mul(BigNumber.from('10').pow(decimals)) + + /// approve inbox to use fee token + await nativeTokenContract.approve(inboxAddr, depositAmount)   /// deposit fee token const iface = new ethers.utils.Interface(["function depositERC20(uint256 amount)"]) - argv.data = iface.encodeFunctionData("depositERC20", [ethers.utils.parseEther(argv.amount)]); + argv.data = iface.encodeFunctionData("depositERC20", [depositAmount]);   await runStress(argv, sendTransaction);   argv.provider.destroy(); if (argv.wait) { - const childProvider = new ethers.providers.WebSocketProvider(chainUrl); - const bridger = namedAccount(argv.from, argv.threadId).connect(childProvider) const sleep = (ms: number) => new Promise(r => setTimeout(r, ms)); + + // calculate amount being minted on child chain + let expectedMintedAmount = depositAmount + if(decimals < 18) { + // inflate up to 18 decimals + expectedMintedAmount = depositAmount.mul(BigNumber.from('10').pow(18 - decimals)) + } else if(decimals > 18) { + // deflate down to 18 decimals, rounding up + const quotient = BigNumber.from('10').pow(decimals - 18) + expectedMintedAmount = depositAmount.div(quotient) + if(expectedMintedAmount.mul(quotient).lt(depositAmount)) { + expectedMintedAmount = expectedMintedAmount.add(1) + } + } + while (true) { - const balance = await bridger.getBalance() - if (balance.gte(ethers.utils.parseEther(argv.amount))) { + const bridgerBalanceAfter = await bridger.getBalance() + if (bridgerBalanceAfter.sub(bridgerBalanceBefore).eq(expectedMintedAmount)) { return } await sleep(100) @@ -85,6 +113,77 @@ } } }   +async function deployERC20Contract(deployerWallet: Wallet, decimals: number): Promise<string> { + //// Bytecode below is generated from this simple ERC20 token contract which uses custom number of decimals + + // pragma solidity 0.8.16; + // + // import {ERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; + // + // contract TestToken is ERC20 { + // uint8 private immutable _decimals; + // + // constructor(uint8 decimals_, address mintTo) ERC20("testnode", "TN") { + // _decimals = decimals_; + // _mint(mintTo, 1_000_000_000 * 10 ** decimals_); + // } + // + // function decimals() public view virtual override returns (uint8) { + // return _decimals; + // } + // } + + const erc20TokenBytecode = "0x60a06040523480156200001157600080fd5b5060405162000d4938038062000d49833981016040819052620000349162000195565b60405180604001604052806008815260200167746573746e6f646560c01b815250604051806040016040528060028152602001612a2760f11b815250816003908162000081919062000288565b50600462000090828262000288565b50505060ff8216608052620000c281620000ac84600a62000469565b620000bc90633b9aca0062000481565b620000ca565b5050620004b9565b6001600160a01b038216620001255760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640160405180910390fd5b8060026000828254620001399190620004a3565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b505050565b60008060408385031215620001a957600080fd5b825160ff81168114620001bb57600080fd5b60208401519092506001600160a01b0381168114620001d957600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200020f57607f821691505b6020821081036200023057634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200019057600081815260208120601f850160051c810160208610156200025f5750805b601f850160051c820191505b8181101562000280578281556001016200026b565b505050505050565b81516001600160401b03811115620002a457620002a4620001e4565b620002bc81620002b58454620001fa565b8462000236565b602080601f831160018114620002f45760008415620002db5750858301515b600019600386901b1c1916600185901b17855562000280565b600085815260208120601f198616915b82811015620003255788860151825594840194600190910190840162000304565b5085821015620003445787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620003ab5781600019048211156200038f576200038f62000354565b808516156200039d57918102915b93841c93908002906200036f565b509250929050565b600082620003c45750600162000463565b81620003d35750600062000463565b8160018114620003ec5760028114620003f75762000417565b600191505062000463565b60ff8411156200040b576200040b62000354565b50506001821b62000463565b5060208310610133831016604e8410600b84101617156200043c575081810a62000463565b6200044883836200036a565b80600019048211156200045f576200045f62000354565b0290505b92915050565b60006200047a60ff841683620003b3565b9392505050565b60008160001904831182151516156200049e576200049e62000354565b500290565b8082018082111562000463576200046362000354565b608051610874620004d5600039600061011b01526108746000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80633950935111610071578063395093511461014557806370a082311461015857806395d89b4114610181578063a457c2d714610189578063a9059cbb1461019c578063dd62ed3e146101af57600080fd5b806306fdde03146100ae578063095ea7b3146100cc57806318160ddd146100ef57806323b872dd14610101578063313ce56714610114575b600080fd5b6100b66101c2565b6040516100c391906106be565b60405180910390f35b6100df6100da366004610728565b610254565b60405190151581526020016100c3565b6002545b6040519081526020016100c3565b6100df61010f366004610752565b61026e565b60405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020016100c3565b6100df610153366004610728565b610292565b6100f361016636600461078e565b6001600160a01b031660009081526020819052604090205490565b6100b66102b4565b6100df610197366004610728565b6102c3565b6100df6101aa366004610728565b610343565b6100f36101bd3660046107b0565b610351565b6060600380546101d1906107e3565b80601f01602080910402602001604051908101604052809291908181526020018280546101fd906107e3565b801561024a5780601f1061021f5761010080835404028352916020019161024a565b820191906000526020600020905b81548152906001019060200180831161022d57829003601f168201915b5050505050905090565b60003361026281858561037c565b60019150505b92915050565b60003361027c8582856104a0565b61028785858561051a565b506001949350505050565b6000336102628185856102a58383610351565b6102af919061081d565b61037c565b6060600480546101d1906107e3565b600033816102d18286610351565b9050838110156103365760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b610287828686840361037c565b60003361026281858561051a565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6001600160a01b0383166103de5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161032d565b6001600160a01b03821661043f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161032d565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006104ac8484610351565b9050600019811461051457818110156105075760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161032d565b610514848484840361037c565b50505050565b6001600160a01b03831661057e5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161032d565b6001600160a01b0382166105e05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161032d565b6001600160a01b038316600090815260208190526040902054818110156106585760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161032d565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610514565b600060208083528351808285015260005b818110156106eb578581018301518582016040015282016106cf565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461072357600080fd5b919050565b6000806040838503121561073b57600080fd5b6107448361070c565b946020939093013593505050565b60008060006060848603121561076757600080fd5b6107708461070c565b925061077e6020850161070c565b9150604084013590509250925092565b6000602082840312156107a057600080fd5b6107a98261070c565b9392505050565b600080604083850312156107c357600080fd5b6107cc8361070c565b91506107da6020840161070c565b90509250929050565b600181811c908216806107f757607f821691505b60208210810361081757634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561026857634e487b7160e01b600052601160045260246000fdfea2646970667358221220257f3d763bae7b8c0189ed676531d85a1046e0bea68722f67c2616d46f01c02964736f6c63430008100033"; + const abi = ["constructor(uint8 decimals_, address mintTo)"]; + const tokenFactory = new ContractFactory(abi, erc20TokenBytecode, deployerWallet); + const token = await tokenFactory.deploy(decimals, deployerWallet.address); + await token.deployTransaction.wait(); + + return token.address; +} + +async function deployFeeTokenPricerContract(deployerWallet: Wallet, exchangeRate: BigNumber): Promise<string> { + //// Bytecode below is generated from this simple FeeTokenPricer contract + + // pragma solidity ^0.8.16; + + // interface IFeeTokenPricer { + // /** + // * @notice Get the number of child chain's fee tokens per 1 parent chain's native token. Exchange rate must be + // * denominated in 18 decimals. + // * @dev For example, parent chain's native token is ETH, fee token is DAI. If price of 1ETH = 2000DAI, then function should return 2000*1e18. + // * If fee token is USDC instead and price of 1ETH = 2000USDC, function should still return 2000*1e18, no matter that USDC uses 6 decimals. + // */ + // function getExchangeRate() external returns (uint256); + // } + + // contract ConstantFeeTokenPricer is IFeeTokenPricer { + // uint256 immutable public constExchangeRate; + // constructor(uint256 _constExchangeRate) { + // constExchangeRate = _constExchangeRate; + // } + + // function getExchangeRate() external view returns (uint256) { + // return constExchangeRate; + // } + // } + + const feeTokenPricerBytecode = "0x60a0604052348015600e575f80fd5b506040516101c63803806101c68339818101604052810190602e9190606d565b8060808181525050506093565b5f80fd5b5f819050919050565b604f81603f565b81146058575f80fd5b50565b5f815190506067816048565b92915050565b5f60208284031215607f57607e603b565b5b5f608a84828501605b565b91505092915050565b6080516101166100b05f395f8181606a0152608f01526101165ff3fe6080604052348015600e575f80fd5b50600436106030575f3560e01c8063b8910a29146034578063e6aa216c14604e575b5f80fd5b603a6068565b6040516045919060c9565b60405180910390f35b6054608c565b604051605f919060c9565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b5f7f0000000000000000000000000000000000000000000000000000000000000000905090565b5f819050919050565b60c38160b3565b82525050565b5f60208201905060da5f83018460bc565b9291505056fea2646970667358221220ee17f22614d853ccf8b3f854137f68f06ff92f9f71ba8b811d78b1313eead0c564736f6c634300081a0033"; + const abi = ["constructor(uint256 exchangeRate)"]; + const feeTokenPricerFactory = new ContractFactory(abi, feeTokenPricerBytecode, deployerWallet); + const feeTokenPricer = await feeTokenPricerFactory.deploy(exchangeRate); + await feeTokenPricer.deployTransaction.wait(); + + return feeTokenPricer.address; +} + +async function deployWETHContract(deployerWallet: Wallet): Promise<string> { + const wethFactory = new ContractFactory(TestWETH9.abi, TestWETH9.bytecode, deployerWallet); + const weth = await wethFactory.deploy("Wrapped Ether", "WETH"); + await weth.deployTransaction.wait(); + + return weth.address; +}   export const bridgeFundsCommand = { command: "bridge-funds", @@ -184,56 +283,109 @@ await bridgeNativeToken(argv, argv.l2url, argv.l3url, inboxAddr, nativeTokenAddr) }, };   +export const transferL3ChainOwnershipCommand = { + command: "transfer-l3-chain-ownership", + describe: "transfer L3 chain ownership to upgrade executor", + builder: { + creator: { + string: true, + describe: "address of the token bridge creator", + }, + wait: { + boolean: true, + describe: "wait till ownership is transferred", + default: false, + }, + }, + handler: async (argv: any) => { + // get inbox address from config file + const deploydata = JSON.parse( + fs + .readFileSync(path.join(consts.configpath, "l3deployment.json")) + .toString() + ); + const inboxAddr = ethers.utils.hexlify(deploydata.inbox); + + // get L3 upgrade executor address from token bridge creator + const l2provider = new ethers.providers.WebSocketProvider(argv.l2url); + const tokenBridgeCreator = new ethers.Contract(argv.creator, L1AtomicTokenBridgeCreator.abi, l2provider); + const [,,,,,,,l3UpgradeExecutorAddress,] = await tokenBridgeCreator.inboxToL2Deployment(inboxAddr); + + // set TX params + argv.provider = new ethers.providers.WebSocketProvider(argv.l3url); + argv.to = "address_" + ARB_OWNER; + argv.from = "l3owner"; + argv.ethamount = "0"; + + // add L3 UpgradeExecutor to chain owners + const arbOwnerIface = new ethers.utils.Interface([ + "function addChainOwner(address newOwner) external", + "function removeChainOwner(address ownerToRemove) external" + ]) + argv.data = arbOwnerIface.encodeFunctionData("addChainOwner", [l3UpgradeExecutorAddress]); + await runStress(argv, sendTransaction); + + // remove L3 owner from chain owners + argv.data = arbOwnerIface.encodeFunctionData("removeChainOwner", [namedAccount("l3owner").address]); + await runStress(argv, sendTransaction); + + argv.provider.destroy(); + } +}; + export const createERC20Command = { command: "create-erc20", describe: "creates simple ERC20 on L2", builder: { deployer: { string: true, - describe: "account (see general help)" - }, - mintTo: { - string: true, describe: "account (see general help)", + demandOption: true }, bridgeable: { boolean: true, describe: "if true, deploy on L1 and bridge to L2", + }, + l1: { + boolean: true, + describe: "if true, deploy on L1 only", + }, + decimals: { + string: true, + describe: "number of decimals for token", + default: "18", }, }, handler: async (argv: any) => { console.log("create-erc20");   - if (argv.bridgeable) { - // deploy token on l1 and bridge to l2 + if (argv.bridgeable || argv.l1) { + + // deploy token on l1 + const l1provider = new ethers.providers.WebSocketProvider(argv.l1url); + const deployerWallet = namedAccount(argv.deployer).connect(l1provider); + + const tokenAddress = await deployERC20Contract(deployerWallet, argv.decimals); + const token = new ethers.Contract(tokenAddress, ERC20.abi, deployerWallet); + console.log("Contract deployed at L1 address:", token.address); + + if (!argv.bridgeable) return; + + // bridge to l2 + const l2provider = new ethers.providers.WebSocketProvider(argv.l2url); const l1l2tokenbridge = JSON.parse( fs .readFileSync(path.join(consts.tokenbridgedatapath, "l1l2_network.json")) .toString() );   - const l1provider = new ethers.providers.WebSocketProvider(argv.l1url); - const l2provider = new ethers.providers.WebSocketProvider(argv.l2url); - - const deployerWallet = new Wallet( - ethers.utils.sha256(ethers.utils.toUtf8Bytes(argv.deployer)), - l1provider - ); - - const tokenFactory = new ContractFactory( - ERC20PresetFixedSupplyArtifact.abi, - ERC20PresetFixedSupplyArtifact.bytecode, - deployerWallet - ); - const token = await tokenFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), deployerWallet.address); - await token.deployTransaction.wait(); - console.log("Contract deployed at L1 address:", token.address); - await (await token.functions.transfer(namedAccount(argv.mintTo).address, ethers.utils.parseEther("100000000"))).wait(); - const l1GatewayRouter = new ethers.Contract(l1l2tokenbridge.l2Network.tokenBridge.l1GatewayRouter, L1GatewayRouter.abi, deployerWallet); await (await token.functions.approve(l1l2tokenbridge.l2Network.tokenBridge.l1ERC20Gateway, ethers.constants.MaxUint256)).wait(); + const supply = await token.totalSupply(); + // transfer 90% of supply to l2 + const transferAmount = supply.mul(9).div(10); await (await l1GatewayRouter.functions.outboundTransfer( - token.address, namedAccount(argv.mintTo).address, ethers.utils.parseEther("100000000"), 100000000, 1000000000, "0x000000000000000000000000000000000000000000000000000fffffffffff0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", { + token.address, deployerWallet.address, transferAmount, 100000000, 1000000000, "0x000000000000000000000000000000000000000000000000000fffffffffff0000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000", { value: ethers.utils.parseEther("1"), } )).wait(); @@ -260,25 +412,113 @@ }   // no l1-l2 token bridge, deploy token on l2 directly argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + const deployerWallet = namedAccount(argv.deployer).connect(argv.provider); + const tokenAddress = await deployERC20Contract(deployerWallet, argv.decimals); + console.log("Contract deployed at address:", tokenAddress); + + argv.provider.destroy(); + }, +}; + +export const createFeeTokenPricerCommand = { + command: "create-fee-token-pricer", + describe: "creates Constant Fee Token Pricer on L2", + builder: { + deployer: { + string: true, + describe: "account (see general help)" + }, + }, + handler: async (argv: any) => { + console.log("create-fee-token-pricer"); + + argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); const deployerWallet = new Wallet( ethers.utils.sha256(ethers.utils.toUtf8Bytes(argv.deployer)), argv.provider ); + const feeTokenPricerAddress = await deployFeeTokenPricerContract(deployerWallet, BigNumber.from("15000000000000000000")); + console.log("Contract deployed at address:", feeTokenPricerAddress);   - const contractFactory = new ContractFactory( - ERC20PresetFixedSupplyArtifact.abi, - ERC20PresetFixedSupplyArtifact.bytecode, - deployerWallet - ); - const contract = await contractFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), namedAccount(argv.mintTo).address); + argv.provider.destroy(); + }, +}; + +export const deployExpressLaneAuctionContractCommand = { + command: "deploy-express-lane-auction", + describe: "Deploy the ExpressLaneAuction contract", + builder: { + "bidding-token": { + string: true, + describe: "bidding token address", + demandOption: true + }, + "auctioneer": { + string: true, + describe: "account name to set as auctioneer and admin on contract (default auctioneer)", + default: "auctioneer" + } + }, + handler: async (argv: any) => { + console.log("deploy ExpressLaneAuction contract"); + argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + const l2OwnerWallet = namedAccount("l2owner").connect(argv.provider) + const contractFactory = new ContractFactory(ExpressLaneAuctionContract.abi, ExpressLaneAuctionContract.bytecode, l2OwnerWallet) + + const contract = await contractFactory.deploy(); await contract.deployTransaction.wait(); + console.log("ExpressLaneAuction contract deployed at address:", contract.address);   - console.log("Contract deployed at address:", contract.address); + const auctioneerAddr = namedAddress(argv.auctioneer) + const initIface = new ethers.utils.Interface(["function initialize((address,address,address,(int64,uint64,uint64,uint64),uint256,address,address,address,address,address,address,address))"]) + const initData = initIface.encodeFunctionData("initialize", [[ + auctioneerAddr, //_auctioneer + argv.biddingToken, //_biddingToken + auctioneerAddr, //_beneficiary + [ + Math.round(Date.now() / 60000) * 60, // offsetTimestamp - most recent minute + 60, // roundDurationSeconds + 15, // auctionClosingSeconds + 15 // reserveSubmissionSeconds + ],// RoundTiminginfo + 1, // _minReservePrice + auctioneerAddr, //_auctioneerAdmin + auctioneerAddr, //_minReservePriceSetter, + auctioneerAddr, //_reservePriceSetter, + auctioneerAddr, //_reservePriceSetterAdmin, + auctioneerAddr, //_beneficiarySetter, + auctioneerAddr, //_roundTimingSetter, + auctioneerAddr //_masterAdmin + ]]); + + const proxyFactory = new ethers.ContractFactory(TransparentUpgradeableProxy.abi, TransparentUpgradeableProxy.bytecode, l2OwnerWallet) + const proxy = await proxyFactory.deploy(contract.address, namedAddress("l2owner"), initData) + await proxy.deployed() + console.log("Proxy(ExpressLaneAuction) contract deployed at address:", proxy.address);   argv.provider.destroy(); - }, + } };   +// Will revert if the keyset is already valid. +async function setValidKeyset(argv: any, upgradeExecutorAddr: string, sequencerInboxAddr: string, keyset: string){ + const innerIface = new ethers.utils.Interface(["function setValidKeyset(bytes)"]) + const innerData = innerIface.encodeFunctionData("setValidKeyset", [keyset]); + + // The Executor contract is the owner of the SequencerInbox so calls must be made + // through it. + const outerIface = new ethers.utils.Interface(["function executeCall(address,bytes)"]) + argv.data = outerIface.encodeFunctionData("executeCall", [sequencerInboxAddr, innerData]); + + argv.from = "l2owner"; + argv.to = "address_" + upgradeExecutorAddr + argv.ethamount = "0" + + await sendTransaction(argv, 0); + + argv.provider.destroy(); +} + export const transferERC20Command = { command: "transfer-erc20", describe: "transfers ERC20 token", @@ -299,19 +539,60 @@ to: { string: true, describe: "address (see general help)", }, + l1: { + boolean: true, + describe: "if true, transfer on L1", + }, }, handler: async (argv: any) => { console.log("transfer-erc20");   - argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + if (argv.l1) { + argv.provider = new ethers.providers.WebSocketProvider(argv.l1url); + } else { + argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + } const account = namedAccount(argv.from).connect(argv.provider); const tokenContract = new ethers.Contract(argv.token, ERC20.abi, account); - const decimals = await tokenContract.decimals(); - await(await tokenContract.transfer(namedAccount(argv.to).address, ethers.utils.parseUnits(argv.amount, decimals))).wait(); + const tokenDecimals = await tokenContract.decimals(); + const amountToTransfer = BigNumber.from(argv.amount).mul(BigNumber.from('10').pow(tokenDecimals)); + await(await tokenContract.transfer(namedAccount(argv.to).address, amountToTransfer)).wait(); argv.provider.destroy(); }, };   +export const createWETHCommand = { + command: "create-weth", + describe: "creates WETH on L1", + builder: { + deployer: { + string: true, + describe: "account (see general help)" + }, + deposit: { + number: true, + describe: "amount of weth to deposit", + default: 100, + } + }, + handler: async (argv: any) => { + console.log("create-weth"); + + const l1provider = new ethers.providers.WebSocketProvider(argv.l1url); + const deployerWallet = namedAccount(argv.deployer).connect(l1provider); + + const wethAddress = await deployWETHContract(deployerWallet); + const weth = new ethers.Contract(wethAddress, TestWETH9.abi, deployerWallet); + console.log("WETH deployed at L1 address:", weth.address); + + if (argv.deposit > 0) { + const amount = ethers.utils.parseEther(argv.deposit.toString()); + const depositTx = await deployerWallet.sendTransaction({ to: wethAddress, value: amount, data:"0xd0e30db0" }); // deposit() + await depositTx.wait(); + } + }, +}; + export const sendL1Command = { command: "send-l1", describe: "sends funds between l1 accounts", @@ -431,3 +712,43 @@ await rpcProvider.send(argv.method, argv.params) } } + +export const setValidKeysetCommand = { + command: "set-valid-keyset", + describe: "sets the anytrust keyset", + handler: async (argv: any) => { + argv.provider = new ethers.providers.WebSocketProvider(argv.l1url); + const deploydata = JSON.parse( + fs + .readFileSync(path.join(consts.configpath, "deployment.json")) + .toString() + ); + const sequencerInboxAddr = ethers.utils.hexlify(deploydata["sequencer-inbox"]); + const upgradeExecutorAddr = ethers.utils.hexlify(deploydata["upgrade-executor"]); + + const keyset = fs + .readFileSync(path.join(consts.configpath, "l2_das_keyset.hex")) + .toString() + + await setValidKeyset(argv, upgradeExecutorAddr, sequencerInboxAddr, keyset) + } +}; + +export const waitForSyncCommand = { + command: "wait-for-sync", + describe: "wait for rpc to sync", + builder: { + url: { string: true, describe: "url to send rpc call", default: "http://sequencer:8547"}, + }, + handler: async (argv: any) => { + const rpcProvider = new ethers.providers.JsonRpcProvider(argv.url) + let syncStatus; + do { + syncStatus = await rpcProvider.send("eth_syncing", []) + if (syncStatus !== false) { + // Wait for a short interval before checking again + await new Promise(resolve => setTimeout(resolve, 5000)) + } + } while (syncStatus !== false) + }, +};
diff --git OffchainLabs/nitro-testnode/scripts/package.json Layr-Labs/nitro-testnode/scripts/package.json index d1de3706eedd9186ace62b4a990c97ffd9455a4d..c2dc9db9b8d3974fcff410f72b873ef209ecea0a 100644 --- OffchainLabs/nitro-testnode/scripts/package.json +++ Layr-Labs/nitro-testnode/scripts/package.json @@ -6,6 +6,7 @@ "main": "index.js", "author": "Offchain Labs, Inc.", "license": "Apache-2.0", "dependencies": { + "@arbitrum/nitro-contracts": "^2.1.1", "@arbitrum/token-bridge-contracts": "1.2.0", "@node-redis/client": "^1.0.4", "@openzeppelin/contracts": "^4.9.3",
diff --git OffchainLabs/nitro-testnode/scripts/redis.ts Layr-Labs/nitro-testnode/scripts/redis.ts index 1d13c21d9f3036e5265ff2e0b90af3eeae1b1bfb..1282368a2b2e6c79624d6941cfddc22c0340f4a8 100644 --- OffchainLabs/nitro-testnode/scripts/redis.ts +++ Layr-Labs/nitro-testnode/scripts/redis.ts @@ -40,14 +40,14 @@ let prio_sequencers = "bcd"; let priostring = ""; if (priorities == 0) { - priostring = "ws://sequencer:8548"; + priostring = "http://sequencer:8547"; } if (priorities > prio_sequencers.length) { priorities = prio_sequencers.length; } for (let index = 0; index < priorities; index++) { const this_prio = - "ws://sequencer_" + prio_sequencers.charAt(index) + ":8548"; + "http://sequencer_" + prio_sequencers.charAt(index) + ":8547"; if (index != 0) { priostring = priostring + ","; }
diff --git OffchainLabs/nitro-testnode/tokenbridge/Dockerfile Layr-Labs/nitro-testnode/tokenbridge/Dockerfile index 3d8cbacb375a751ef2862509bfc4e222ade4ea4e..475a68a6d1fcfbf924aac48f851e94509c9700f9 100644 --- OffchainLabs/nitro-testnode/tokenbridge/Dockerfile +++ Layr-Labs/nitro-testnode/tokenbridge/Dockerfile @@ -1,10 +1,12 @@ -FROM node:16-bullseye-slim +FROM node:20-bookworm-slim +RUN apt-get update && \ + apt-get install -y git docker.io python3 make gcc g++ curl jq ARG TOKEN_BRIDGE_BRANCH=main -RUN apt-get update && \ - apt-get install -y git docker.io python3 build-essential WORKDIR /workspace -RUN git clone --no-checkout https://github.com/OffchainLabs/token-bridge-contracts.git ./ -RUN git checkout ${TOKEN_BRIDGE_BRANCH} -RUN yarn install +RUN git clone --no-checkout https://github.com/OffchainLabs/token-bridge-contracts.git ./ && \ + git checkout ${TOKEN_BRIDGE_BRANCH} && \ + rm -rf .git && \ + git init && git add . && git -c user.name="user" -c user.email="user@example.com" commit -m "Initial commit" +RUN yarn install && yarn cache clean RUN yarn build ENTRYPOINT ["yarn"]
diff --git OffchainLabs/nitro-testnode/grafana/dashboards/Throughput-testing.json Layr-Labs/nitro-testnode/grafana/dashboards/Throughput-testing.json new file mode 100644 index 0000000000000000000000000000000000000000..58d6fcb2d3ba8c13aa2132793fa34aec54f9464a --- /dev/null +++ Layr-Labs/nitro-testnode/grafana/dashboards/Throughput-testing.json @@ -0,0 +1,3906 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 26, + "panels": [ + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 0, + "y": 1 + }, + "id": 25, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "jit_wasm_memoryusage{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "WASM Memory Usage", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 9, + "y": 1 + }, + "id": 27, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_wasmModuleRoots_success{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "WASM Module Roots Endpoint Success", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 0, + "y": 10 + }, + "id": 30, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_validate_success{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Validate Endpoint", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 9, + "y": 10 + }, + "id": 33, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_validate_success_count{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Validate Success Count", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 15, + "y": 10 + }, + "id": 31, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_stylusArchs_success{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Validate Stylus Program Endpoint", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 9, + "y": 14 + }, + "id": 28, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_stylusArchs_success_count{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Stylus Archs Success Count", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 0, + "y": 19 + }, + "id": 29, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_latestWasmModuleRoot_success{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Latest WASM Root Endpoint", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 9, + "y": 19 + }, + "id": 34, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_latestWasmModuleRoot_success_count{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "wasmModuleRoots Success Count", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "scaleDistribution": { + "type": "linear" + } + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 9, + "x": 15, + "y": 19 + }, + "id": 32, + "options": { + "calculate": false, + "cellGap": 1, + "color": { + "exponent": 0.5, + "fill": "dark-orange", + "mode": "scheme", + "reverse": false, + "scale": "exponential", + "scheme": "Oranges", + "steps": 64 + }, + "exemplars": { + "color": "rgba(255,0,255,0.7)" + }, + "filterValues": { + "le": 1e-9 + }, + "legend": { + "show": true + }, + "rowsFrame": { + "layout": "auto" + }, + "tooltip": { + "mode": "single", + "showColorScale": false, + "yHistogram": false + }, + "yAxis": { + "axisPlacement": "left", + "reverse": false + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_room_success{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Validations Available (room) Endpoint", + "type": "heatmap" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 9, + "y": 24 + }, + "id": 35, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rpc_duration_validation_stylusArchs_success_count{instance=\"validation_node:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Stylus Archs Success Count", + "type": "gauge" + } + ], + "title": "Validation Server", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 9, + "panels": [], + "title": "Validator", + "type": "row" + }, + { + "datasource": { + "default": false, + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 39, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "editorMode": "builder", + "expr": "{service_name=\"nitro-testnode-validator-1\"}", + "queryType": "range", + "refId": "A" + } + ], + "title": "Logs", + "type": "logs" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 7, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "arb_validator_msg_count_current_batch{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "msg count cur batch", + "range": true, + "refId": "Validator Message Count", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_validator_validations_pending{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "validations pending", + "range": true, + "refId": "Validations Pending", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_validator_msg_count_validated{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "msg count validated", + "range": true, + "refId": "Validator Msg Count Validated", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "arb_validator_validations_valid{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "validations valid", + "range": true, + "refId": "Valid Validations", + "useBackend": false + } + ], + "title": "Validations", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "{__name__\"": { + "index": 0 + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "__name__*" + }, + "properties": [ + { + "id": "displayName" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 3, + "x": 12, + "y": 10 + }, + "id": 17, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_confirmed{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Confirmed", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_inblock{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Inblock", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_latest{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Latest", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "nominal SeqNum", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 9, + "x": 15, + "y": 10 + }, + "id": 19, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_queue_length{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Data Poster Queue", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 6, + "x": 0, + "y": 18 + }, + "id": 23, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_staker_action_success{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{__name__}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_staker_action_failure{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{__name__}}", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_staker_confirmed_node{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{__name__}}", + "range": true, + "refId": "C", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_staker_staked_node{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{__name__}}", + "range": true, + "refId": "D", + "useBackend": false + } + ], + "title": "Assertion Chain Staking", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 5, + "x": 6, + "y": 18 + }, + "id": 24, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_validator_recordingdb_size{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Recording DB Size", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 11, + "y": 18 + }, + "id": 41, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_gasrefunder_eth{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "ETH", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Gas Refunder ETH", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 5, + "x": 15, + "y": 18 + }, + "id": 45, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_queue_length{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Length", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_queue_weight{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Weight", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Data Poster Queue", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 4, + "x": 20, + "y": 18 + }, + "id": 44, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_finalized{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Finalized", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_softconfirmed{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Soft Confirmed", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_unconfirmed{instance=\"validator:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Unconfirmed", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "Data Poster", + "type": "stat" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 27 + }, + "id": 21, + "panels": [ + { + "datasource": { + "default": false, + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "gridPos": { + "h": 4, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 37, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "editorMode": "builder", + "expr": "{container=\"nitro-testnode-poster-1\"} |= ``", + "queryType": "range", + "refId": "A" + } + ], + "title": "Logs", + "type": "logs" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 0, + "y": 7 + }, + "id": 20, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_estimated_batch_backlog{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Estimated Batch Backlog", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 9, + "x": 7, + "y": 7 + }, + "id": 22, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_wallet_eth{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Wallet ETH", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 16, + "y": 7 + }, + "id": 40, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchPoster_action_da_success{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "DA Success", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchPoster_action_da_failure{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "DA Failures", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Data Availability Provider", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 4, + "x": 20, + "y": 7 + }, + "id": 43, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_finalized{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Finalized", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_softconfirmed{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Soft Confirmed", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_nonce_unconfirmed{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Nonce Unconfirmed", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "Data Poster", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 0, + "y": 15 + }, + "id": 42, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_l1gasprice{instance=\"poster:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "GWEI", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "L1 Gas Price", + "type": "timeseries" + } + ], + "title": "Batch Poster", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 13, + "panels": [ + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 4 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_block_basefee", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "L2 Base Fee", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 9, + "y": 4 + }, + "id": 14, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "right", + "showLegend": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_block_gasused", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Block Gas Used", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 16, + "y": 4 + }, + "id": 46, + "options": { + "legend": { + "calcs": [], + "displayMode": "hidden", + "placement": "right", + "showLegend": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_block_gasused", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Block Gas Used", + "type": "timeseries" + } + ], + "title": "Chain", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 29 + }, + "id": 16, + "panels": [], + "title": "EigenDA Proxy", + "type": "row" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 30 + }, + "id": 15, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "eigenda_proxy_http_server_requests_total{job=\"eigenda_proxy\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Proxy Requests Total", + "type": "timeseries" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 38 + }, + "id": 8, + "panels": [ + { + "datasource": { + "default": false, + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 38, + "options": { + "dedupStrategy": "none", + "enableLogDetails": true, + "prettifyLogMessage": false, + "showCommonLabels": false, + "showLabels": false, + "showTime": false, + "sortOrder": "Descending", + "wrapLogMessage": false + }, + "targets": [ + { + "datasource": { + "type": "loki", + "uid": "cdzn4gd8wly4gf" + }, + "editorMode": "builder", + "expr": "{container=\"nitro-testnode-sequencer-1\"} |= ``", + "queryType": "range", + "refId": "A" + } + ], + "title": "Logs", + "type": "logs" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 4, + "x": 0, + "y": 39 + }, + "id": 11, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_inbox_latest_batch{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "latest batch", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_inbox_latest_batch_message{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "latest batch msg", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "Inbox", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "{__name__\"": { + "index": 0 + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "__name__*" + }, + "properties": [ + { + "id": "displayName" + } + ] + } + ] + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 4, + "y": 39 + }, + "id": 2, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto" + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_confirmed{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Confirmed", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_inblock{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Inblock", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_latest{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Latest", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "nominal SeqNum", + "type": "gauge" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [ + { + "options": { + "{__name__\"": { + "index": 0 + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "__name__*" + }, + "properties": [ + { + "id": "displayName" + } + ] + } + ] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 39 + }, + "id": 47, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.2.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_confirmed{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Confirmed", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_inblock{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Inblock", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencenumber_latest{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "Latest", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "latest --> confirmed delta", + "transformations": [ + { + "id": "calculateField", + "options": { + "binary": { + "left": "Latest", + "operator": "-", + "right": "Confirmed" + }, + "mode": "binary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 44 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencer_backlog{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_sequencer_calldataunitsbacklog{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_estimated_batch_backlog{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "C", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_feed_backlog_bytes{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "D", + "useBackend": false + } + ], + "title": "backlog sizes", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 44 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_batchposter_estimated_batch_backlog", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "latest batch message", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Estimated Batch Backlog", + "type": "timeseries" + }, + { + "datasource": {}, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 52 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(rate(arb_sequencenumber_latest[$__rate_interval]))", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(rate(arb_sequencenumber_confirmed[$__rate_interval]))", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "B", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sum(rate(arb_sequencenumber_inblock[$__rate_interval]))", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "C", + "useBackend": false + } + ], + "title": "SeqNum rate", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 52 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(arb_sequencer_currentsurplus[$__rate_interval])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(arb_sequencer_expectedsurplus[$__rate_interval])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{label_name}}", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "sequencer surplus", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 60 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(arb_feed_backlog_bytes{instance=\"sequencer:6070\"}[$__rate_interval])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "backlog bytes rate", + "range": true, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(arb_feed_backlog_messages{instance=\"sequencer:6070\"}[$__rate_interval])", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "backlog message rate", + "range": true, + "refId": "B", + "useBackend": false + } + ], + "title": "feed", + "type": "timeseries" + }, + { + "datasource": { + "default": true, + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 60 + }, + "id": 18, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ddshms3dlineoe" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "arb_dataposter_queue_length{instance=\"sequencer:6070\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Data Poster Queue", + "type": "timeseries" + } + ], + "title": "Sequencer", + "type": "row" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Throughput testing", + "uid": "advlsdpd877y8a", + "version": 1, + "weekStart": "" +} \ No newline at end of file