Skip to content

Commit 286666b

Browse files
docs(chains): wave 5 deep research — Arbitrum / Optimism / zkSync / Linea (4 EVM L2 DIFF-ONLY)
延续 P1-2 28 链 method-level 调研。本 wave 实施护栏 2 (复用链 diff-only), 4 链 zh+en 合计 ~2000 行(对比 wave 1-4 重写式 ~3000 行/3 链,效率提升 40%+)。 ## 调研产出 | 链 | zh 行 | en 行 | call | rollup 类型 | 关键发现 | |---|---|---|---|---|---| | 15-arbitrum | 256 | 256 | 12 | Optimistic | **arb_* namespace 已废弃**(Nitro 移到 NodeInterface 0xC8 precompile);真 L2 字段 gasUsedForL1/l1BlockNumber(非 OP 的 l1Fee/l1GasUsed) | | 16-optimism | 226 | 226 | 9 | Optimistic | 官方 RPC 现跑 op-reth v2.2.0(非 op-geth);**6/6 OP method 公链 allowlist 拦截**(-32601 not whitelisted);EIP-4844 blob mode 实证 | | 17-zksync-era | 205 | 214 | 17 | ZK Type 4 | zks_* 全可用(7 实证);**native AA 烟枪**(eth_estimateFee from=0x0 拒);三相 finality (commit→prove→execute Δ ≈ 4.5h) | | 18-linea | 269 | 272 | 7 | ZK Type 2 | linea_estimateGas 返 {gasLimit,baseFeePerGas,priorityFeePerGas} 3 字段;**linea_getProof Sparse Merkle Tree (Mimc) 与 eth_getProof Keccak-MPT 完全不同形状**;仅 3 个 linea_* public method | ## H8 实证证据(每链,共 45 次 curl 主网 2026-05-23) **Arbitrum** (arb1.arbitrum.io + publicnode): - chainId 0xa4b1 (42161) ✓ / Nitro v3.10.1-rc.2 客户端 ✓ - block time 8 块/2s ≈ 250ms ✓ - **arb_getCurrentBlock + arb_findBatchContainingBlock 全 -32601 method not exist** → context arb_* 假设错,修正 - **l1Fee=null on Arbitrum** → context 给的 l1Fee/l1FeeScalar 是 OP-Stack 字段,Arbitrum 实际是 gasUsedForL1=0x149 + l1BlockNumber + miner=固定 sequencer 地址(ASCII "...sequencer") **Optimism** (mainnet.optimism.io): - chainId 0xa (10) ✓ / **op-reth v2.2.0 客户端**(非历史的 op-geth) ✓ - baseFeePerGas 389 wei(L1 6 数量级以下)/ blobGasUsed 2.7M(post-Ecotone EIP-4844 实证) - rollup_gasPrices/optimism_outputAtBlock/optimism_syncStatus/optimism_rollupConfig/optimism_version/rollup_getInfo **全部 -32601 "rpc method is not whitelisted"** → 公链 allowlist 明确,L2 method 仅自部署/付费可见 **zkSync Era** (mainnet.era.zksync.io): - chainId 0x144 (324) ✓ / zks_L1BatchNumber 0x7cd85 = 511877 ✓ - zks_L1ChainId 0x1(settles to Mainnet)/ zks_getMainContract 0x32400084c286cf3e17e7b677ea9583e60a000324 DiamondProxy - zks_getBridgeContracts 7 字段 / zks_getBlockDetails 三相 finality 真实时间戳(批次 60100000 commit→execute Δ ≈ 4.5h) - **eth_estimateFee from=0x0 拒**"can't start a transaction from a non-account" → native AA 直接烟枪 - eth_getTransactionReceipt 额外字段 l1BatchNumber/l1BatchTxIndex/l2ToL1Logs/log-level l1BatchNumber/blockTimestamp 全实证 **Linea** (rpc.linea.build): - chainId 0xe708 (59144) ✓ / Geth/v1.17.3-stable-117e067f linea-geth follower - linea_estimateGas 3 字段 {gasLimit, baseFeePerGas, priorityFeePerGas} - linea_getProof Sparse Merkle Tree (Mimc) leafIndex / eth_getProof Keccak-MPT 兼容 shim(L2→L1 withdrawal **不能用**) - linea_getTransactionExclusionStatusV1 → null(sequencer censorship check 入口存在) - 仅 3 个 public linea_* method(6 个枚举其他 method 全部 -32601 验证) - **L1 batch/finalize state 不通过 L2 RPC 暴露** → 必须 eth_call L1 ZkEvmV2 合约(与 zkSync zks_L1BatchNumber 便利 RPC 鲜明对比) ## DSL ASK 增量收敛(本 wave) **Arbitrum** — 0 新增,**修正 wave 5 context**: - exclude arb_* method(全废弃,不入 method list) - exclude l1Fee/l1FeeScalar/l1GasUsed/l1GasPrice(非 Arbitrum 字段) - include passive(parser 忽略):block.l1BlockNumber, receipt.gasUsedForL1, receipt.l1BlockNumber **Optimism** — 4 ASK 1. 引入声明式 `l2:` 子树(全可选) 2. optional_methods 语义(wave5 = skip+INFO,wave6 = strict) 3. **OP Superchain 复用策略**:Base/Mantle/Worldchain/Zora/Mode 是否合并为一个 OP-superchain 共享页 + per-chain 5-curl 微调研?(推荐 yes,~80% 工作量降低) 4. client family metadata 字段(op-reth vs op-geth) **zkSync** — 2 ASK 1. **ASK-Z1**:`rollup_type` 枚举 {l1, optimistic, zk, validium, sovereign} + `settlement_chain_id` + `l1_main_contract`(三相 finality vs 二相 finality 真实分支) 2. **ASK-Z2**:EIP-712 type-113 paymasterParams 处理 → 推荐嵌套 `transaction.extensions[zksync_paymaster]`(不提到顶层) **Linea + wave 5 累计** — 3 关键决策 1. **ASK-L1**:linea_estimateGas 作主 fee oracle + eth_estimateGas fallback + inflate_pct: 10 2. **ASK-W5-A**(wave 5 共识):rollup_type 枚举从 zkSync 单链 ASK 扩为 4 链共识 + 加 `zk_evm_type: 2|4` 子字段(Type 2 vs Type 4 影响 benchmark 合约复用) 3. **ASK-W5-B**(wave 5 共识 — 反提议):**不要**把 L1 batch monitor 提到 EVM 公共子层 → 3/4 链需 L1 contract call(Arb precompile / OP L2OutputOracle / Linea ZkEvmV2),只 zkSync 给 RPC → **"interface common, impl private"**:DSL 只声明 `l1_batch_monitor.enabled` + `poll_interval_s`,各 adapter 实现 get_l1_settled_block() 自身 ## 累计 DSL ASK 状态(wave 1+2+3+4+5 = 16 链) 新增字段(wave 5): - **rollup_type** enum {l1, optimistic, zk, validium, sovereign} - **zk_evm_type** {2, 4} 子字段(Type 2 = Linea/Scroll bytecode-equivalent,Type 4 = zkSync 部分等价) - **settlement_chain_id** + **l1_main_contract** - **l1_batch_monitor.{enabled, poll_interval_s}**(接口共有,实现私有) - **transaction.extensions[paymaster]** (zkSync EIP-712 type-113 嵌套,不提顶层) - **optional_methods 语义**(skip vs strict) - **client_family** metadata(op-reth vs op-geth) - **OP Superchain 微调研模式**(待 wave 6/7 用类似模式做 Cosmos 生态 / BTC fork) ## Adapter 决策 - ArbitrumAdapter:**不新建**,EthereumAdapter 100% 复用 + 内部 chain_type 分支 block_range=2000-4000 - OptimismAdapter:**不新建**,EthereumAdapter 100% 复用(公链拿不到 OP method 也不影响 benchmark) - ZkSyncAdapter:**新建**(zks_* 必须 + native AA + 三相 finality 三独有) - LineaAdapter:**不新建**,EthereumAdapter 复用 + linea_estimateGas 可选启用(配置而非 adapter) ## 累计进度 - 6 链 (wave 1+2):Bitcoin / Aptos / Cosmos / Cardano / Polkadot / NEAR ✅ commit 6897ecc - 3 链 (wave 3):Tron / Algorand / Tezos ✅ commit d7b39f1 - 3 链 (wave 4):Avalanche-C / Avalanche-X / Hedera ✅ commit 372e98c - 4 链 (wave 5):Arbitrum / Optimism / zkSync Era / Linea ✅ 本 commit - **累计 16 链调研完成 + 1 P2-DESIGN 设计稿(28 链总目标的 57%)** ## 护栏触发记录(① + 4 护栏) **护栏 1 commit-per-wave**:本 commit 触发 ✅ **护栏 2 复用链 diff-only**:wave 5 4 链平均 252 行(对比 wave 1-4 平均 460 行,**降 45%**)✅ **护栏 3 fail-fast**:无 timeout(最长 zkSync 215s)✅ **护栏 4 决策反转检测**: - Arbitrum"arb_* 废弃" 反转 **context 假设** 不反转已 commit wave 决策 ✅ - ASK-W5-B 反提议(L1 batch monitor **不**提公共子层)是 wave 5 阶段新发现,不反转 wave 1-4 ✅ - rollup_type 枚举从 zkSync 单链 ASK 扩到 wave 5 4 链共识 ✅ ## 关键自审(诚实标注 — 需 user 关注) Arbitrum 主动发现 "arb_* namespace 已废弃" 后,我意识到 wave 1-4 调研可能也存在 "基于过时假设"的可能(尤其 EVM 链 Avalanche-C / Polkadot-EVM 子集)。 **未堵 wave 5 推进,但记录**:P2-DESIGN-v2 阶段建议对所有 EVM 链做一次反向校验 (每链 2 curl 验证 method 列表的存活性)。 ## 已知未实证项(透明标注) **Arbitrum**:NodeInterface findBatchContainingBlock selector reverted ⚠️ **Optimism**:receipt L1 fields 仅从 OP Specs 文档,未 curl receipt 实证(user 拒 follow-up call) **zkSync**:paymaster 真实 tx 未抓(找不到合适样本 tx) **Linea**:linea_getProof L2→L1 withdrawal 完整流程未跑(需要真实 withdrawal tx) ## 老测保护 无代码改动,纯文档新增。 Refs: P1-2 (28 链调研), P2-DESIGN-v2 (DSL spec)
1 parent 372e98c commit 286666b

8 files changed

Lines changed: 1924 additions & 0 deletions

File tree

docs/en/chains/15-arbitrum.md

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# 15-arbitrum Research (Arbitrum One)
2+
3+
> **DIFF-ONLY mode** (Wave5 guardrail 2): this chain is 100% EVM-compatible (Nitro = go-ethereum fork). The 8 core `eth_*` methods are already empirically validated 5 times across Ethereum/Polygon/BSC/Avalanche-C — **not re-stated here**. Only L2-specific diffs are covered.
4+
> H8 evidence: 8 live curl probes + `arb_*` namespace liveness check + `l1Fee` / `gasUsedForL1` receipt field measurement + Optimistic Rollup finality model.
5+
> Any claim not 100% empirically validated is marked with ⚠️.
6+
7+
---
8+
9+
## Meta
10+
11+
| Field | Value |
12+
|---|---|
13+
| Chain (CN) | Arbitrum One |
14+
| Chain (EN) | Arbitrum One |
15+
| ID | 15 |
16+
| Mainnet ChainID | `0xa4b1` = **42161** (measured) |
17+
| Testnet | `421614` (Arbitrum Sepolia) — out of scope |
18+
| Rollup type | **Optimistic Rollup** (fraud-proof, 7-day challenge window) |
19+
| Research date | 2026-05-23 |
20+
| Researcher | Hermes Agent |
21+
| Status | 🟢 Complete (8 curls + arb_* liveness + l1Fee/gasUsedForL1 field measurement + finality model analysis) |
22+
23+
---
24+
25+
## 1. Sources
26+
27+
| Type | URL | Date | Note |
28+
|---|---|---|---|
29+
| Official dev portal | https://docs.arbitrum.io/ | 2026-05-23 | Arbitrum docs main entry — ⚠️ no DOM verification (cited only) |
30+
| Nitro client | https://github.com/OffchainLabs/nitro | 2026-05-23 | Arbitrum Nitro node (go-ethereum fork + WASM fraud prover) — ⚠️ no DOM verification |
31+
| RPC reference | https://docs.arbitrum.io/build-decentralized-apps/arbitrum-vs-ethereum/rpc-methods | 2026-05-23 | Official "Differences from Ethereum JSON-RPC" |
32+
| NodeInterface precompile | https://docs.arbitrum.io/build-decentralized-apps/nodeinterface/reference | 2026-05-23 | `0x00…00c8` precompile (replaces legacy `arb_*` namespace) |
33+
| Explorer | https://arbiscan.io/ | 2026-05-23 | Mainnet explorer |
34+
| Public RPC (official) | https://arb1.arbitrum.io/rpc | 2026-05-23 | **H8 measured: `eth_chainId``0xa4b1`, `web3_clientVersion``nitro/v3.10.1-rc.2-d7f07be`** |
35+
| Public RPC (Publicnode) | https://arbitrum-one-rpc.publicnode.com | 2026-05-23 | **H8 measured: `web3_clientVersion``nitro/v75e084e-modified`** |
36+
| Public RPC (LlamaRPC) | https://arbitrum.llamarpc.com | 2026-05-23 | Backup — ⚠️ not probed (budget) |
37+
38+
---
39+
40+
## 2. L1↔L2 Relationship (Optimistic Rollup topology)
41+
42+
| Role | Entity | Note |
43+
|---|---|---|
44+
| **Settlement layer (L1)** | Ethereum Mainnet | All L2 state roots periodically posted to L1 |
45+
| **Sequencer** | Single point — Offchain Labs operated | Centralised ordering, sub-second blocks, user txs go through sequencer first |
46+
| **Batch poster** | Offchain Labs operated | Compresses L2 batches and posts to L1 calldata / blobs (post EIP-4844) |
47+
| **Validator / Challenger** | Whitelisted (permissioned) → permissionless BoLD in progress (⚠️ timeline not verified) | Can raise fraud proofs |
48+
| **Fraud-proof window** | **7 days** (challenge window) | An L2 block is "truly final" only after L1 batch confirm + 7 days no challenge |
49+
50+
**Sequencer address fingerprint** (measured): block `miner` field is always `0xa4b000000000000000000073657175656e636572` (trailing ASCII = "sequencer") — Arbitrum's fixed sequencer signing address, **not a PoW miner nor PoS validator**. EthereumAdapter parsing `miner` is not broken (only the semantics differ).
51+
52+
---
53+
54+
## 3. Public RPC
55+
56+
| Endpoint | Auth | Rate limit | Note |
57+
|---|---|---|---|
58+
| https://arb1.arbitrum.io/rpc | None | Not published (⚠️ not stress-tested) | **H8 alive**; new blocks returned in real time (no observable cache) |
59+
| https://arbitrum-one-rpc.publicnode.com | None | publicnode generic (⚠️ not measured) | **H8 alive** |
60+
| https://arbitrum.llamarpc.com | None | LlamaRPC free tier | ⚠️ not probed |
61+
62+
**curl evidence** (required to prove RPC liveness):
63+
64+
```bash
65+
# T1: chainId
66+
curl -s -X POST https://arb1.arbitrum.io/rpc \
67+
-H "Content-Type: application/json" \
68+
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId"}'
69+
# Measured (2026-05-23):
70+
# {"jsonrpc":"2.0","id":1,"result":"0xa4b1"} ← 0xa4b1 = 42161 ✅
71+
72+
# T2: web3_clientVersion
73+
curl -s -X POST https://arb1.arbitrum.io/rpc \
74+
-H "Content-Type: application/json" \
75+
-d '{"jsonrpc":"2.0","id":1,"method":"web3_clientVersion"}'
76+
# {"jsonrpc":"2.0","id":1,"result":"nitro/v3.10.1-rc.2-d7f07be/linux-amd64/go1.25.10"}
77+
# ↑ Nitro = Arbitrum node client (go-ethereum fork)
78+
79+
# T3: blockNumber × 2 (block-time measurement)
80+
# t=0: result = "0x1bc58e17" = 466,358,807
81+
# t=2s: result = "0x1bc58e1f" = 466,358,815
82+
# Δ block = 8 / Δt = 2s → ~250 ms/block ✅ (matches official ~250ms claim)
83+
```
84+
85+
---
86+
87+
## 4. ChainID / Finality / Gas Diff Table (vs Ethereum L1)
88+
89+
| Dimension | Ethereum L1 | **Arbitrum One** | DSL impact |
90+
|---|---|---|---|
91+
| ChainID | 1 | **42161** (measured) | chain_id override |
92+
| Block time | ~12 s (PoS slot) | **~250 ms** (measured 8 blk / 2 s) | mock-mode block-advance cadence needs tuning |
93+
| L2 instant finality | N/A | **~250 ms** (sequencer "soft" confirm) | "soft" ≠ settlement final |
94+
| L1 settlement | ~12.8 min justified / ~25 min finalized | **batch posted ~10 min** (batch-poster cadence dependent — ⚠️ doc-cited, not end-to-end measured) | "final" is two-stage: soft + L1 settlement |
95+
| Fraud-proof window | N/A | **7 days** (theoretical "absolute" finality) | benchmarks cannot wait 7 days; use L1 settlement as "practical final" |
96+
| Consensus | Gasper (PoS) | **Sequencer ordering + L1 settlement** (no BFT consensus) | block.miner = fixed sequencer address |
97+
| Gas model | EIP-1559 | **EIP-1559 + L1 data fee surcharge** | see §5 receipt diff |
98+
| `eth_gasPrice` measured | a few gwei | `0x131e880`**20 Mwei = 0.02 gwei** (L2 typical) | same method, 100× lower magnitude |
99+
| `eth_maxPriorityFeePerGas` measured | 1-2 gwei | **`0x0`** (Arbitrum tip is 0) | same method, different value |
100+
| `eth_syncing` | Standard | **❌ not exposed** (measured `-32601 method not exist`) | health check switches to `eth_blockNumber` vs wall-clock |
101+
| `eth_getLogs` range limit | 1000-2000 blocks (publicnode) | ⚠️ exact limit not probed (budget) | assume ≤1000 blocks conservatively |
102+
103+
**Key clarification: Arbitrum "finality" is a 3-layer model**
104+
105+
1. **Soft (sequencer) finality** ≈ 250 ms — what users see "confirmed" in wallets/dapps
106+
2. **L1 settlement** ≈ 10 min — batch poster commits to L1, batch enters L1 state
107+
3. **Absolute finality** ≈ 7 days — fraud-proof window expires, theoretically irreversible
108+
109+
**Benchmark implication**: this framework's `blockNumber`-class latency tests use soft finality (250 ms); if Phase 2.x adds "L1 finality" semantics, an independent L1-batch-posting latency measurement is needed. **No `finality_layer` field needed in DSL today** (exceeds single-RPC measurement scope).
110+
111+
---
112+
113+
## 5. L2-specific method evidence (core — `arb_*` liveness)
114+
115+
### 5.1 `arb_*` namespace liveness results
116+
117+
| Method | Official RPC (`arb1.arbitrum.io/rpc`) | Publicnode | Conclusion |
118+
|---|---|---|---|
119+
| `arb_getCurrentBlock` |`-32601 method not exist` |`-32601 method not exist` | **unavailable** |
120+
| `arb_findBatchContainingBlock` |`-32601 method not exist` | ⚠️ not probed (budget) | **unavailable** |
121+
| `arb_getBlock` | ❌ (inferred from liveness pattern; not separately called) | ⚠️ | unavailable |
122+
123+
**Key finding**: **Arbitrum Nitro has deprecated the `arb_*` JSON-RPC namespace**. The `arb_getBlock / arb_getTransactionReceipt / arb_findBatchContainingBlock` mentioned in the context all return `-32601` on both public endpoints probed. Since the Nitro era (2022-08+), the L2-aware data path moved to:
124+
125+
- **NodeInterface precompile** (address `0x00000000000000000000000000000000000000c8`) invoked via `eth_call`
126+
- **Extra fields are appended directly to `eth_getBlockByNumber` / `eth_getTransactionReceipt` responses** (see §5.2)
127+
128+
Measured NodeInterface `findBatchContainingBlock(uint64)` (selector `0x81f1adaf`):
129+
130+
```bash
131+
curl -s -X POST https://arb1.arbitrum.io/rpc \
132+
-H "Content-Type: application/json" \
133+
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{
134+
"to":"0x00000000000000000000000000000000000000c8",
135+
"data":"0x81f1adaf000000000000000000000000000000000000000000000000000000001bc58e00"
136+
},"latest"]}'
137+
# Measured: {"error":{"code":-32000,"message":"execution reverted"}}
138+
```
139+
140+
⚠️ The selector came from third-party material without cross-verification; the revert may be wrong-selector or that block is past the batch-history window. **Bottom line**: NodeInterface probing needs the precise ABI (this benchmark framework does not need to call it — knowing it exists is enough).
141+
142+
### 5.2 `eth_getBlockByNumber` extra fields (Arbitrum-specific)
143+
144+
Measured `eth_getBlockByNumber("latest", false)` response (excerpt):
145+
146+
```json
147+
{
148+
"baseFeePerGas": "0x1380ad0",
149+
"extraData": "0xd298aa699c9518a46a41ac479571cfb408e6aa3e4171ef58e305ff7d762a0946",
150+
"gasLimit": "0x4000000000000",
151+
"hash": "0xf215d2f3cdb2be4aad204aff5cc7e5839c11af38540b7b4790d996f5b1ddadf0",
152+
"l1BlockNumber": "0x17fe926", ← Arbitrum-specific: corresponding L1 block height
153+
"miner": "0xa4b000000000000000000073657175656e636572", ← fixed sequencer address
154+
"mixHash": "0x0000000000027a1100000000017fe92600000000000000330000000000000000"
155+
}
156+
```
157+
158+
| Field | Present on Ethereum? | Meaning |
159+
|---|---|---|
160+
| `l1BlockNumber` || L1 block height referenced by this L2 block |
161+
| `miner` = fixed sequencer addr | ✅ (semantics: PoS proposer) | Arbitrum semantics: sequencer signing address |
162+
| `gasLimit` = `0x4000000000000` | ✅ (drastically different magnitude) | Arbitrum ~1.1×10^15 (effectively unbounded), Ethereum ~30M |
163+
164+
**DSL impact**: when EthereumAdapter parses blocks, extra fields are ignored (default JSON-parser behavior). `l1BlockNumber` **does not break any of the 8 existing methods**.
165+
166+
### 5.3 `eth_getTransactionReceipt` extra fields (l1Fee vs gasUsedForL1)
167+
168+
Measured a real user tx (type=0x2 EIP-1559) receipt:
169+
170+
```json
171+
{
172+
"gasUsed": "0xeffa",
173+
"effectiveGasPrice": "0x1315410",
174+
"gasUsedForL1": "0x149", ← Arbitrum-specific (measured non-zero)
175+
"l1BlockNumber": "0x17fe927", ← Arbitrum-specific (measured)
176+
"l1Fee": null, ← Optimism/OP-Stack field; null on Arbitrum
177+
"l1FeeScalar": null, ← ditto, null
178+
"l1GasUsed": null, ← ditto, null
179+
"l1GasPrice": null, ← ditto, null
180+
"type": "0x2"
181+
}
182+
```
183+
184+
**Key clarification (context correction)**:
185+
186+
| Context claim | Measured result | True owner |
187+
|---|---|---|
188+
| `l1Fee` field |**Arbitrum returns null** | **OP-Stack chains (Optimism / Base)**, not Arbitrum |
189+
| `l1FeeScalar` | ❌ Arbitrum null | OP-Stack |
190+
| `gasUsedForL1` | ✅ Arbitrum has value (`0x149`) | **Arbitrum Nitro-specific** |
191+
| `l1BlockNumber` (in receipt) | ✅ Arbitrum has value | **Arbitrum Nitro-specific** |
192+
193+
**Arbitrum's real L1 data-fee computation**: `l1Cost = gasUsedForL1 × effectiveGasPrice` (already rolled into `effectiveGasPrice` billing, **no standalone `l1Fee` field**). OP-Stack is the one that breaks out L1 fee as a `l1Fee` field.
194+
195+
**This is a mild context-doc inaccuracy; this research corrects it via direct measurement**.
196+
197+
### 5.4 Real-payload evidence
198+
199+
| Item | Measurement |
200+
|---|---|
201+
| USDC `balanceOf(0xC0fFee…4979)` | `eth_call` to `0xaf88d065e77c8cC2239327C5EDb3A432268e5831``0x00…00` (Vitalik has no USDC on Arbitrum, **0 is a correct response, not an error**) ✅ |
202+
| `net_version` | `"42161"` (matches chainId) ✅ |
203+
| Real user-tx receipt | see §5.3, full fields returned ✅ |
204+
205+
---
206+
207+
## 6. DSL decision (required — 0-new-field prediction validation)
208+
209+
- [x] **100% reuse EthereumAdapter** (recommended — Nitro = go-ethereum fork, 8 methods 1:1)
210+
- [x] **Only `chain_id=42161` + `rpc_endpoint=arb1.arbitrum.io/rpc` (or publicnode) needed**
211+
- [x] **0 new DSL fields** (prediction validated)
212+
- [x] `arb_*` namespace **must not** be added to method list (deprecated, not exposed on public RPCs)
213+
- [ ] (Optional) `block_range` tuning: Arbitrum ~250 ms blocks; Ethereum default `block_range=100` covers only 25 s; for EOA tx-scan scenarios use `block_range=2000-4000`. **Implemented via `chain_type` inline dispatch (same pattern as Avalanche). Not a new field.**
214+
- [ ] (Optional) `finality_layer` field: if Phase 2.x measures L1-settlement latency, it **exceeds single-RPC measurement scope**; not introduced by this research
215+
216+
**Rationale (brief)**:
217+
218+
Arbitrum Nitro client measured version `nitro/v3.10.1-rc.2`, core is a go-ethereum fork plus Stylus (WASM) subsystem. All 8 `eth_*` methods this framework needs work 1:1 (6 measured directly: chainId / blockNumber / getBlockByNumber / gasPrice / call / getTransactionReceipt; the remaining getBalance / getLogs inferred from EVM behavior). `eth_syncing` not exposed is a common public-RPC pattern (Ethereum publicnode often disables it too); fall back to blockNumber vs wall-clock comparison. The Arbitrum-extra fields on block / receipt (`l1BlockNumber`, `gasUsedForL1`) are supersets — **default JSON parsers ignore extra fields, no adapter breakage**. DSL diff is strictly `chain_id=42161` + `rpc_endpoint=arb1.arbitrum.io/rpc`, two lines.
219+
220+
The `arb_*` namespace has been deprecated since Nitro (this research measured `-32601` on both public endpoints); the `arb_getBlock / arb_getTransactionReceipt` mentioned in context no longer work; true L2-aware data (L1 batch membership, L1 confirmations) migrated to the `0xc8` NodeInterface precompile, which this benchmark does not need to call. **Not in DSL.**
221+
222+
---
223+
224+
## 7. H8 evidence (8-curl summary)
225+
226+
| # | Endpoint | Method | Result | Reference |
227+
|---|---|---|---|---|
228+
| T1 | arb1.arbitrum.io | `eth_chainId` | `0xa4b1` = 42161 ✅ | §3 |
229+
| T2 | arb1.arbitrum.io | `web3_clientVersion` | `nitro/v3.10.1-rc.2-d7f07be`| §3 |
230+
| T3 | arb1.arbitrum.io | `eth_blockNumber` ×2 | 8 blocks / 2s → 250 ms/block ✅ | §3 §4 |
231+
| T4 | arb1.arbitrum.io | `eth_gasPrice` | `0x131e880` ≈ 0.02 gwei ✅ | §4 |
232+
| T5 | arb1.arbitrum.io | `arb_getCurrentBlock` | `-32601` not exist ❌ (key finding) | §5.1 |
233+
| T6 | arb1.arbitrum.io | `eth_getBlockByNumber("latest")` | contains `l1BlockNumber`, sequencer miner ✅ | §5.2 |
234+
| T7 | arb1.arbitrum.io | `eth_getTransactionReceipt` | contains `gasUsedForL1=0x149`, `l1Fee=null` (context correction) ✅ | §5.3 |
235+
| T8 | publicnode | `eth_chainId` + `web3_clientVersion` | `0xa4b1` + `nitro/v75e084e-modified`| §3 |
236+
| (T9 USDC `balanceOf` + T10 `net_version` + T11 `eth_maxPriorityFeePerGas` are supplementary, see §4 §5.4) | | | | |
237+
238+
**Total: 11 real RPC calls** (exceeds H8 requirement of 8). All methods verified live, no cache, no mock.
239+
240+
---
241+
242+
## Open Questions
243+
244+
- [ ] BoLD permissionless-validator upgrade timeline (challenge → permissionless) — affects "finality" trust assumption, ⚠️ not verified
245+
- [ ] L1 batch-posting precise cadence (~10 min is the doc value; Phase 2.x large-scale tests should cross-verify)
246+
- [ ] Real `eth_getLogs` block-range upper limit on public RPCs (not probed in this pass — budget)
247+
- [ ] Full NodeInterface `0xc8` ABI cross-verification (only one selector tried, reverted)
248+
- [ ] Whether Stylus (WASM) contract receipts have additional fields (sample tx was EVM contract)
249+
250+
---
251+
252+
## Changelog
253+
254+
| Date | Author | Change |
255+
|---|---|---|
256+
| 2026-05-23 | Hermes Agent | Initial: Wave5 batch 1 — Arbitrum One DIFF-ONLY research, 11 curl evidence, corrected context's `l1Fee` field attribution (actually OP-Stack, not Arbitrum), `arb_*` namespace measured as deprecated |

0 commit comments

Comments
 (0)