-
Notifications
You must be signed in to change notification settings - Fork 152
[M1] Add Otterscan & Sourcify integration to playground #4000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[M1] Add Otterscan & Sourcify integration to playground #4000
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
I have read the CLA Document and I hereby sign the CLA |
MartinquaXD
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you contribution! 🚀
Other than the small modification I had to apply, this worked like a charm on my first simple test. Will play a bit more with it over the holidays and do a full review.
playground/otterscan-entrypoint.sh
Outdated
| case "${SOURCIFY_MODE:-cloud}" in | ||
| local) | ||
| echo "Using LOCAL Sourcify as primary source" | ||
| cat > "$CONFIG_FILE" << 'EOF' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to remove the ' to enable variable expansion. With 'EOF' this command literally wrote ${ERIGON_URL} into the file instead of http://127.0.0.1:8545.
| cat > "$CONFIG_FILE" << 'EOF' | |
| cat > "$CONFIG_FILE" << EOF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Fixed
playground/otterscan-entrypoint.sh
Outdated
| ;; | ||
| cloud|*) | ||
| echo "Using CLOUD Sourcify as primary source" | ||
| cat > "$CONFIG_FILE" << 'EOF' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here.
| cat > "$CONFIG_FILE" << 'EOF' | |
| cat > "$CONFIG_FILE" << EOF |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ Fixed
|
This pull request has been marked as stale because it has been inactive a while. Please update this pull request or it will be automatically closed. |
jmg-duarte
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran docker compose -f docker-compose.non-interactive.yml up -d and it failed "upping" the sourcify service with a series of errors related to (seemingly) the database migrations
sourcify-1 | === Sourcify Server Starting ===
sourcify-1 | Waiting for database...
sourcify-1 | Database is ready!
sourcify-1 | Running database migrations...
sourcify-1 | runtime: lfstack.push invalid packing: node=0xffffb431d800 cnt=0x1 packed=0xffffb431d8000001 -> node=0xffffffffb431d800
sourcify-1 | fatal error: lfstack.push
I'm running Podman Compose on an M4 Pro, MacOS Sequoia 15.6
|
|
||
| # Sourcify - Contract verification service | ||
| sourcify-db: | ||
| image: postgres:15-alpine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're using postgres-16, I wonder if we can use the same image here to avoid downloading two postgres images
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point for image optimization! I've updated both compose files to use postgres:16 for the sourcify-db service to match the main db service.
✅ Fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sourcify DB is failing to get up, I'm guessing it's targeting the same port as the main DB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't actually a port conflict - sourcify-db doesn't expose any external ports (only the main db exposes 5432:5432).
The error is a PostgreSQL version mismatch that happens when containers aren't rebuilt after pulling changes.
Solution - reset volumes and rebuild:
docker compose -f docker-compose.non-interactive.yml down --remove-orphans --volumes
docker compose -f docker-compose.non-interactive.yml up --build
I confirmed this fixes the issue locally - sourcify-db comes up healthy after the rebuild.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've ran these, they worked (nice find on the volumes, I cleaned my env but forgot them!)
The sourcify image is still not cooperating (bunch of panics like the one below):
sourcify-1 | goroutine 37 gp=0xc000458700 m=nil [chan receive]:
sourcify-1 | runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/proc.go:424 +0xce fp=0xc0001b1f18 sp=0xc0001b1ef8 pc=0x47096e
sourcify-1 | runtime.chanrecv(0xc0000da540, 0x0, 0x1)
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/chan.go:639 +0x41c fp=0xc0001b1f90 sp=0xc0001b1f18 pc=0x40b87c
sourcify-1 | runtime.chanrecv1(0x0?, 0x0?)
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/chan.go:489 +0x12 fp=0xc0001b1fb8 sp=0xc0001b1f90 pc=0x40b432
sourcify-1 | runtime.unique_runtime_registerUniqueMapCleanup.func1(...)
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/mgc.go:1732
sourcify-1 | runtime.unique_runtime_registerUniqueMapCleanup.gowrap1()
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/mgc.go:1735 +0x2f fp=0xc0001b1fe0 sp=0xc0001b1fb8 pc=0x41edcf
sourcify-1 | runtime.goexit({})
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0001b1fe8 sp=0xc0001b1fe0 pc=0x478b61
sourcify-1 | created by unique.runtime_registerUniqueMapCleanup in goroutine 1
sourcify-1 | /home/runner/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.23.0.linux-amd64/src/runtime/mgc.go:1730 +0x96
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My docker versions are the following:
- Docker: 27.2.1
- Docker Compose: v2.40.3-desktop.1
What versions are you using? Also have you tried running the playground in the main branch? meaning, without our changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jmg-duarte were you able test this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies for the delay. I find it weird that you can run this as is, the playground driver.toml actually has an issue.
And I still can't run sourcify/otterscan on my Mac, I was able to run this on my Linux machine (x86) though which hints me that the go images are not being correctly built for ARM
Maybe docker is able to emulate or cross build correctly but not everyone can be expected to run docker (as you see, I dont, and I've met others running lima, etc)
Would be nice to have this working with alternative container runtimes too, to avoid "it works on my machine"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @jmg-duarte, I've pushed a fix that should help with the ARM architecture issues.
What changed:
The Sourcify Dockerfile was hardcoding the dbmate-linux-amd64 binary, which doesn't work natively on ARM machines. I've updated it to:
- Auto-detect the host architecture
- Map to the correct dbmate binary (supports amd64, arm64, i386, armhf)
- Fail fast with a clear error if the architecture is unsupported
- Verify the binary works during build
Please try building again with a clean slate:
docker compose -f docker-compose.non-interactive.yml down --remove-orphans --volumes
docker compose -f docker-compose.non-interactive.yml up --build
A couple of questions:
- Were you able to run the playground on main branch (without this PR's changes)? That would help us isolate whether this is a pre-existing issue or something introduced in this PR.
- Did you try running Otterscan with SOURCIFY_MODE=cloud (pointing to the cloud Sourcify instead of local)? If so, did that work?
- You mentioned there's an issue with driver.toml - could you elaborate on what's broken there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update, it works now (on Podman)! The issue was clearly something to do with emulation and possibly cross building.
The driver issue is due to the driver.toml missing the tx-gas-limit field at the top of the file, like the example.toml — this is not related to the PR, I just found it curious
Details
2026-01-19T11:32:33.117Z ERROR observe::tracing: thread 'main' panicked at /src/crates/driver/src/infra/config/file/load.rs:36:13:
failed to parse TOML config at "/driver.toml": Error {
inner: Error {
inner: TomlError {
message: "missing field `tx-gas-limit`",
raw: Some(
"[[solver]]\nname = \"baseline\" # Arbitrary name given to this solver, must be unique\nendpoint = \"http://baseline\"\nabsolute-slippage = \"40000000000000000\" # Denominated in wei, optional\nrelative-slippage = \"0.1\" # Percentage in the [0, 1] range\naccount = \"0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6\" # Known test private key\n\n[submission]\ngas-price-cap = \"1000000000000\"\n\n[[submission.mempool]]\nmempool = \"public\"\n\n[liquidity]\nbase-tokens = [\n \"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2\", # WETH\n \"0x6B175474E89094C44Da98b954EedeAC495271d0F\", # DAI\n \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\", # USDC\n \"0xdAC17F958D2ee523a2206206994597C13D831ec7\", # USDT\n \"0xc00e94Cb662C3520282E6f5717214004A7f26888\", # COMP\n \"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2\", # MKR\n \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\", # WBTC\n \"0x6810e776880C02933D47DB1b9fc05908e5386b96\", # GNO\n]\n\n[[liquidity.uniswap-v2]] # Uniswap V2 configuration\npreset = \"uniswap-v2\"\n",
),
keys: [],
span: Some(
0..0,
),
},
},
}
- Fix heredoc EOF quoting to enable variable expansion in otterscan-entrypoint.sh - Update Node.js from v22 to v24 (current LTS) in Dockerfile.sourcify - Update Sourcify repo to argotorg/sourcify with explicit master branch - Align sourcify-db postgres version to 16 (matching main db service)
@augustocollerone does it actually work for you? The refreshing mechanism was super slow when I was running it on docker, so much so I didn't even tried running. I'll try it now! |
yes it takes really long, like 10 minutes but it works for me! |
|
That is a fair point regarding container runtime compatibility. It would certainly improve the developer experience for those not using Docker directly. However, I believe this falls outside the scope of the current grant, which was defined as integrating Otterscan into the existing Docker Compose setup. Broader runtime compatibility would affect the entire playground infrastructure, not merely the Otterscan integration. Perhaps something to consider for a future improvement or separate proposal. For now, I would suggest we evaluate this PR against the agreed Milestone 1 deliverables. I have tested this PR and can confirm it functions in accordance with the guidance provided. The implementation satisfies Milestone 1 as defined in the grant proposal. |
The dbmate binary download was hardcoded to amd64, which breaks builds on ARM64 machines (Apple Silicon) when using alternative container runtimes like Podman or lima that don't have automatic x86 emulation. Changes: - Detect host architecture using dpkg --print-architecture - Map dpkg naming to dbmate naming (i386→386, armhf→arm) - Add clear error message for unsupported architectures - Verify binary works with dbmate --version after download Supports: amd64, arm64, i386, armhf
b53c542 to
775f11a
Compare
Summary
This PR delivers Milestone 1: Otterscan Integration of the CoW Grants Program RFP: CoW Protocol Playground Block Explorer Integration proposal by CoBuilders.
Integrates Otterscan block explorer with Sourcify contract verification into the CoW Protocol Playground, enabling developers to browse transactions and view verified contract source code locally.
Milestone 1 Deliverables
Otterscan Integration
Contract Verification Setup
SOURCIFY_MODEenv var)Success Criteria
http://localhost:8003http://localhost:5555Commits
872d4dbd6e322b3c11ff26e8acb68519ffa98fa7ecff75c1ff7e8ff50660cb8f92810aChanges
New Files
Dockerfile.sourcifyDockerfile.otterscansourcify-entrypoint.shotterscan-entrypoint.shSOURCIFY_MODEsourcify-chains.jsonModified Files
docker-compose.fork.ymldocker-compose.non-interactive.yml.env.exampleSOURCIFY_MODEconfiguration variableREADME.mdDockerfileArchitecture
Configuration Options
Sourcify Mode
The
SOURCIFY_MODEenvironment variable controls which Sourcify source Otterscan uses:cloud(default)localAfter changing, recreate the Otterscan container:
Contract Verification
Using Foundry:
Using Sourcify API:
Testing
Start the playground:
Verify services are healthy:
Test cloud mode (default): View any well-known contract in Otterscan - source code should be visible
Test local mode:
SOURCIFY_MODE=localin.envNext Milestones
Submitted by CoBuilders as part of the CoW Grants Program