The current ArbOS version used on Arbitrum One and Arbitrum Nova is ArbOS 40, corresponding to the Arbitrum Nitro consensus-v40 git tag.
To audit the code difference from ArbOS 40 to ArbOS 51, you could simply generate a full nitro diff with git diff consensus-v40 consensus-v51 (and also generate a diff of the go-ethereum submodule mentioned in that nitro diff). However, that includes a lot of code that isn’t part of the WASM module root. To filter down to just the replay binary which defines the state transition function, you can start by generating a list of files in the nitro and go-ethereum repositories included by the replay binary in either ArbOS 40 or ArbOS 51 with bash:
#!/usr/bin/env bash
set -e
mkdir -p ~/tmp # this script uses ~/tmp as scratch space and output
workspace="$HOME/tmp/nitro-diff-workspace"
consensus_old="consensus-v40"
consensus_new="consensus-v51"
mkdir -p ${workspace}/${consensus_old}
mkdir -p ${workspace}/${consensus_new}
cd ${workspace}/${consensus_old}
git clone --branch ${consensus_old} -j6 --recurse-submodules --single-branch <https://github.com/OffchainLabs/nitro.git>
cd nitro
make .make/solgen
go list -f "{{.Deps}}" ./cmd/replay | tr -d '[]' | sed 's/ /\\n/g' | grep 'github.com/offchainlabs/nitro/' | sed '[email protected]/offchainlabs/nitro/@@' | \\
while read dir; do
find "$dir" -type f -name '*.go' -maxdepth 1
done | grep -v '_test\\.go$' > ~/tmp/${consensus_old}-nitro-files.txt
go list -f "{{.Deps}}" ./cmd/replay | tr -d '[]' | sed 's/ /\\n/g' | grep 'github.com/ethereum/go-ethereum/' | sed '[email protected]/ethereum/go-ethereum/@go-ethereum/@' | \\
while read dir; do
find "$dir" -type f -name '*.go' -maxdepth 1
done | grep -v '_test\\.go$' > ~/tmp/${consensus_old}-geth-files.txt
cd ${workspace}/${consensus_new}
git clone --branch ${consensus_new} -j6 --recurse-submodules --single-branch <https://github.com/OffchainLabs/nitro.git>
cd nitro
make .make/solgen
go list -f "{{.Deps}}" ./cmd/replay | tr -d '[]' | sed 's/ /\\n/g' | grep 'github.com/offchainlabs/nitro/' | sed '[email protected]/offchainlabs/nitro/@@' | \\
while read dir; do
find "$dir" -type f -name '*.go' -maxdepth 1
done | grep -v '_test\\.go$' > ~/tmp/${consensus_new}-nitro-files.txt
go list -f "{{.Deps}}" ./cmd/replay | tr -d '[]' | sed 's/ /\\n/g' | grep 'github.com/ethereum/go-ethereum/' | sed '[email protected]/ethereum/go-ethereum/@go-ethereum/@' | \\
while read dir; do
find "$dir" -type f -name '*.go' -maxdepth 1
done | grep -v '_test\\.go$' > ~/tmp/${consensus_new}-geth-files.txt
sort -u ~/tmp/${consensus_old}-nitro-files.txt ~/tmp/${consensus_new}-nitro-files.txt > ~/tmp/replay-binary-nitro-dependencies.txt
sort -u ~/tmp/${consensus_old}-geth-files.txt ~/tmp/${consensus_new}-geth-files.txt | sed 's@^[./]*go-ethereum/@@' > ~/tmp/replay-binary-geth-dependencies.txt
Now, ~/tmp/replay-binary-dependencies.txt contains a list of dependencies of the replay binary that were present in ArbOS 40 or 51. To use that to generate a smaller diff of the nitro repository, you can run:
git diff consensus-v40 consensus-v51 -- cmd/replay $(cat ~/tmp/replay-binary-nitro-dependencies.txt) > ~/tmp/arbos51-nitro.diff
For the go-ethereum submodule, we have added tags for each of consensus-v40 and consensus-v51 to make it easy to address them in git diff commands. You can again use git diff and the files generated by the earlier script to generate a diff limited to code used by the replay binary:
# this should be run inside the go-ethereum submodule folder
git diff consensus-v40 consensus-v51 -- $(cat ~/tmp/replay-binary-geth-dependencies.txt) > ~/tmp/arbos51-geth.diff
This diff also includes the diff between upstream go-ethereum versions v1.15.5 and v1.16.4, as ArbOS 40 used the former and ArbOS 51 uses the latter. To filter out that difference, you can use this tool to find the intersection of two git diffs: Git diff intersection finder
We can use that to find the intersection of the diff of ArbOS 51’s go-ethereum against ArbOS 40’s go-ethereum and the diff of ArbOS 51’s go-etheruem against upstream go-ethereum v1.16.4:
# this should be run inside the go-ethereum submodule folder
git remote add upstream <https://github.com/ethereum/go-ethereum.git> && git fetch upstream
git diff consensus-v40 consensus-v51 -- $(cat ~/tmp/replay-binary-geth-dependencies.txt) > ~/tmp/arbos-40-vs-51-geth.diff
git diff v1.16.4 consensus-v51 -- $(cat ~/tmp/replay-binary-geth-dependencies.txt) > ~/tmp/arbos-51-vs-upstream-geth.diff
diff-intersection.py ~/tmp/arbos-40-vs-51-geth.diff ~/tmp/arbos-51-vs-upstream-geth.diff --ignore-files 'core/blockchain*.go' arbitrum_types/txoptions.go 'rawdb/**' 'rpc/**' > ~/tmp/arbos-51-geth-line-intersection.diff
The above command ignores files that are included by the replay binary but whose components are not used with these arguments: --ignore-files 'core/blockchain*.go' arbitrum_types/txoptions.go 'rawdb/**' 'rpc/**'. To also review those diffs, you can remove those arguments.
Note that by default, diff-intersection.py does a line based intersection. To instead do an intersection based on chunks in the diff, known as hunks in git terminology, you can add the --only-hunks flag.
diff-intersection.py --only-hunks ~/tmp/arbos-40-vs-51-geth.diff ~/tmp/arbos-51-vs-upstream-geth.diff --ignore-files 'core/blockchain*.go' arbitrum_types/txoptions.go 'rawdb/**' 'rpc/**' > ~/tmp/arbos-51-geth-hunk-intersection.diff