diff --git a/CHANGELOG.md b/CHANGELOG.md index 45ac5b99b0b..e49e6375939 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ - [#7408](https://github.com/ChainSafe/forest/pull/7408): Impl `Forest.IndexBackfill`, `Forest.IndexBackfillStatus` and `Forest.IndexBackfillCancel` RPC methods and the `forest-cli index backfill` command to back-fill the chain index (Ethereum mappings, events, block blooms) through the running daemon, so the node no longer needs to be stopped. An interrupted or cancelled run can be resumed with `--resume`. +- [#7270](https://github.com/ChainSafe/forest/issues/7270): Include `scripts/tests/ribasushi-rpc-checks` that tests Forest against the external Ribasushi dataset + ### Changed ### Removed diff --git a/scripts/tests/ribasushi-rpc-checks/docker-compose.yaml b/scripts/tests/ribasushi-rpc-checks/docker-compose.yaml new file mode 100644 index 00000000000..b20d18c27b3 --- /dev/null +++ b/scripts/tests/ribasushi-rpc-checks/docker-compose.yaml @@ -0,0 +1,82 @@ +name: rpc-checks + +# docker compose up --build --abort-on-container-exit --exit-code-from rpc-checks + +x-env: &env + CHAIN: ${CHAIN:-calibnet} + DAYS_AGO: ${DAYS_AGO:-2} + EPOCHS: ${EPOCHS:-1000} + +services: + snapshot: + image: alpine:3.24 + environment: *env + volumes: + - ./snapshots:/snapshots + entrypoint: ["/bin/sh", "-euc"] + command: + - | + apk add --no-cache curl jq >/dev/null + + # validates DAYS_AGO and EPOCHS + case "$$DAYS_AGO" in ''|*[!0-9]*) echo "DAYS_AGO must be a non-negative integer: '$$DAYS_AGO'"; exit 1;; esac + case "$$EPOCHS" in ''|*[!0-9]*) echo "EPOCHS must be a non-negative integer: '$$EPOCHS'"; exit 1;; esac + [ "$$EPOCHS" -ge 1 ] || { echo "EPOCHS must be at least 1"; exit 1; } + + day=$$(date -u -d "@$$(( $$(date -u +%s) - DAYS_AGO * 86400 ))" +%F) + url=$$(curl -sSf --connect-timeout 10 --retry 3 \ + "https://forest-archive.chainsafe.dev/list/$$CHAIN/latest-v2?format=json" | + jq -r --arg d "$$day" '[.items[].url | select(contains("_"+$$d+"_"))] | first') + [ "$$url" != null ] || { echo "no $$CHAIN snapshot for $$day"; exit 1; } + + file=$$(basename "$$url") + head=$$(echo "$$file" | sed 's/.*_height_\([0-9]*\)\..*/\1/') + case "$$head" in ''|*[!0-9]*) echo "could not parse a height from '$$file'"; exit 1;; esac + [ "$$EPOCHS" -le "$$head" ] || { echo "EPOCHS ($$EPOCHS) exceeds head ($$head)"; exit 1; } + + # only downloads if the snapshot is not present + [ -f "/snapshots/$$file" ] || + curl -sSfL --connect-timeout 10 --retry 3 -o "/snapshots/$$file" "$$url" + + # define env vars used later on the next services + printf 'SNAPSHOT=%s\nSTART=%s\nEND=%s\nBACKFILL=%s\n' \ + "$$file" "$$((head - EPOCHS))" "$$((head - 1))" "$$((EPOCHS + 1))" > /snapshots/env + cat /snapshots/env + + # The RPC port opens only after the backfill finishes, so "healthy" means ready. + forest: + image: ghcr.io/chainsafe/forest:latest + depends_on: + snapshot: + condition: service_completed_successfully + environment: *env + volumes: + - ./snapshots:/snapshots:ro + ports: + - "2345:2345" + entrypoint: ["/bin/sh", "-euc"] + command: + - | + . /snapshots/env + exec forest-tool api serve "/snapshots/$$SNAPSHOT" --chain "$$CHAIN" \ + --port 2345 --height 0 --index-backfill-epochs "$$BACKFILL" + healthcheck: + test: ["CMD", "forest-cli", "chain", "head"] + interval: 15s + timeout: 10s + retries: 480 + + rpc-checks: + image: ghcr.io/chainsafe/forest-rpc-checks:latest + depends_on: + forest: + condition: service_healthy + environment: + FOREST_RPC_URL: forest:2345/rpc/v1 + volumes: + - ./snapshots:/snapshots:ro + entrypoint: ["/bin/sh", "-euc"] + command: + - | + . /snapshots/env + exec bundle exec ruby check_rpc.rb "$$START" "$$END"