Skip to content

Commit 4de400e

Browse files
committed
feat: add trueblocks image
1 parent 8500e61 commit 4de400e

9 files changed

Lines changed: 269 additions & 0 deletions

File tree

.github/actions/deploy/action.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ runs:
168168
source_git_commit_hash: ${{ steps.git_commit_hash.outputs.git_commit_hash }}
169169
source_git_commit_hash_full: ${{ steps.git_commit_hash_full.outputs.git_commit_hash_full }}
170170
GOPROXY: ${{ inputs.GOPROXY }}
171+
build_args: ${{ inputs.build_args }}
171172
build_method: ${{ inputs.build_method }}
172173
run: |
173174
${{ inputs.build_script }}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
name: Build trueblocks docker image
2+
run-name: "${{ inputs.repository }}@${{ inputs.ref }}${{ inputs.correlation_id && format(' [{0}]', inputs.correlation_id) || '' }}"
3+
4+
on:
5+
workflow_dispatch:
6+
inputs:
7+
repository:
8+
description: The source trueblocks-core repository to build from
9+
default: TrueBlocks/trueblocks-core
10+
type: string
11+
required: true
12+
ref:
13+
description: The branch, tag or SHA to checkout and build from
14+
default: v5.9.3
15+
type: string
16+
required: true
17+
docker_tag:
18+
description: Override target docker tag (defaults to the above source ref if left blank)
19+
type: string
20+
required: false
21+
build_args:
22+
description: Build arguments to pass to the Docker build
23+
default: ""
24+
type: string
25+
required: false
26+
correlation_id:
27+
description: Optional correlation ID passed through to the run name (used by integrations)
28+
type: string
29+
required: false
30+
31+
jobs:
32+
prepare:
33+
runs-on: ubuntu-latest
34+
outputs:
35+
platforms: ${{ steps.setup.outputs.platforms }}
36+
target_tag: ${{ steps.tag.outputs.docker_tag }}
37+
steps:
38+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
39+
- name: Prepare Matrix
40+
id: setup
41+
uses: ./.github/actions/prepare
42+
with:
43+
client: 'trueblocks'
44+
repository: ${{ inputs.repository }}
45+
ref: ${{ inputs.ref }}
46+
- name: Generate target tag
47+
id: tag
48+
uses: ./.github/actions/docker-tag
49+
with:
50+
input: ${{ inputs.docker_tag || inputs.ref }}
51+
repository: ${{ inputs.repository }}
52+
upstream_repository: TrueBlocks/trueblocks-core
53+
docker_tag: ${{ inputs.docker_tag }}
54+
deploy:
55+
needs:
56+
- prepare
57+
runs-on: ${{ matrix.runner }}
58+
continue-on-error: true
59+
strategy:
60+
matrix:
61+
include: ${{fromJson(needs.prepare.outputs.platforms)}}
62+
outputs:
63+
git_commit_hash: ${{ steps.set_output.outputs.git_commit_hash }}
64+
steps:
65+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
66+
- uses: ./.github/actions/install-deps
67+
with:
68+
repository: ${{ inputs.repository }}
69+
- uses: ./.github/actions/deploy
70+
id: deploy
71+
with:
72+
source_repository: ${{ inputs.repository }}
73+
source_ref: ${{ inputs.ref }}
74+
target_tag: ${{ needs.prepare.outputs.target_tag }}-${{ matrix.slug }}
75+
target_repository: ethpandaops/trueblocks
76+
target_dockerfile: ./trueblocks/Dockerfile
77+
build_script: ./trueblocks/build.sh
78+
platform: ${{ matrix.platform }}
79+
build_args: ${{ inputs.build_args }}
80+
81+
DOCKER_USERNAME: "${{ vars.DOCKER_USERNAME }}"
82+
DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}"
83+
MACOS_PASSWORD: "${{ secrets.MACOS_PASSWORD }}"
84+
GOPROXY: "${{ vars.GOPROXY }}"
85+
HARBOR_USERNAME: "${{ vars.HARBOR_USERNAME }}"
86+
HARBOR_PASSWORD: "${{ secrets.HARBOR_PASSWORD }}"
87+
harbor_registry: ${{ vars.HARBOR_REGISTRY }}
88+
89+
- name: Set job output
90+
id: set_output
91+
run: echo "git_commit_hash=${{ steps.deploy.outputs.git_commit_hash }}" >> $GITHUB_OUTPUT
92+
shell: bash
93+
manifest:
94+
needs:
95+
- prepare
96+
- deploy
97+
runs-on: ubuntu-latest
98+
steps:
99+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
100+
- uses: ./.github/actions/manifest
101+
with:
102+
source_repository: ${{ inputs.repository }}
103+
source_ref: ${{ inputs.ref }}
104+
target_tag: ${{ needs.prepare.outputs.target_tag }}
105+
target_repository: ethpandaops/trueblocks
106+
platforms: ${{ needs.prepare.outputs.platforms }}
107+
harbor_registry: ${{ vars.HARBOR_REGISTRY }}
108+
HARBOR_USERNAME: "${{ vars.HARBOR_USERNAME }}"
109+
HARBOR_PASSWORD: "${{ secrets.HARBOR_PASSWORD }}"
110+
git_commit_hash: ${{ needs.deploy.outputs.git_commit_hash }}
111+
DOCKER_USERNAME: "${{ vars.DOCKER_USERNAME }}"
112+
DOCKER_PASSWORD: "${{ secrets.DOCKER_PASSWORD }}"
113+
notify:
114+
name: Discord Notification
115+
runs-on: ubuntu-latest
116+
needs:
117+
- prepare
118+
- deploy
119+
- manifest
120+
if: failure()
121+
steps:
122+
- name: Notify
123+
uses: nobrayner/discord-webhook@1766a33bf571acdcc0678f00da4fb83aad01ebc7 # v1
124+
with:
125+
github-token: ${{ secrets.github_token }}
126+
discord-webhook: ${{ secrets.DISCORD_WEBHOOK }}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Run the *Build **tooling*** workflow;
3939
- [Build Syncoor](https://github.com/ethpandaops/eth-client-docker-image-builder/actions/workflows/build-push-syncoor.yml) [[source](https://github.com/ethpandaops/syncoor)]
4040
- [Build Slashoor](https://github.com/ethpandaops/eth-client-docker-image-builder/actions/workflows/build-push-slashoor.yml) [[source](https://github.com/ethpandaops/slashoor)]
4141
- [Build ere-server-zisk](https://github.com/ethpandaops/eth-client-docker-image-builder/actions/workflows/build-push-ere-server-zisk.yml) [[source](https://github.com/eth-act/ere)]
42+
- [Build TrueBlocks](https://github.com/ethpandaops/eth-client-docker-image-builder/actions/workflows/build-push-trueblocks.yml) [[source](https://github.com/TrueBlocks/trueblocks-core)]
4243

4344
## Adding a new image to build on schedule
4445

branches.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,8 @@ fuzztools:
234234
slashoor:
235235
branches:
236236
- master
237+
238+
trueblocks:
239+
branches:
240+
- main
241+
- v5.9.3

generate_config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
'ere-server-zisk': 'eth-act/ere',
4747
'zkboost': 'eth-act/zkboost',
4848
'fuzztools': 'protocol-security/fuzztools',
49+
'trueblocks': 'TrueBlocks/trueblocks-core',
4950
# Add more defaults as needed
5051
}
5152

platforms.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,6 @@ fuzztools:
131131
slashoor:
132132
- linux/amd64
133133
- linux/arm64
134+
trueblocks:
135+
- linux/amd64
136+
- linux/arm64

trueblocks/Dockerfile

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Builds chifra from trueblocks-core source.
2+
#
3+
# Invoked via ./trueblocks/build.sh, which stages ./entrypoint.sh into the
4+
# build context as .trueblocks-entrypoint.sh before running docker build.
5+
6+
FROM golang:1.25.1-bookworm AS builder
7+
8+
RUN apt-get update \
9+
&& apt-get install -y --no-install-recommends \
10+
ca-certificates \
11+
cmake \
12+
g++ \
13+
gcc \
14+
git \
15+
libcurl4-openssl-dev \
16+
make \
17+
python3 \
18+
&& rm -rf /var/lib/apt/lists/*
19+
20+
COPY . /src
21+
WORKDIR /src
22+
23+
RUN git submodule update --init --recursive
24+
RUN scripts/go-work-sync.sh
25+
RUN mkdir build && cd build && cmake ../src && make -j"$(nproc)"
26+
27+
# ---------------------------------------------------------------------------
28+
29+
FROM debian:bookworm-slim
30+
31+
RUN apt-get update \
32+
&& apt-get install -y --no-install-recommends \
33+
ca-certificates \
34+
curl \
35+
libcurl4 \
36+
&& rm -rf /var/lib/apt/lists/*
37+
38+
COPY --from=builder /src/bin/chifra /usr/local/bin/chifra
39+
40+
# Ship chifra's bundled per-chain configs (allocs.csv etc.) for known public
41+
# networks; without them chifra's IsNodeArchive can't validate against block 0.
42+
COPY --from=builder /src/src/other/install/per-chain /root/.local/share/trueblocks/config
43+
44+
COPY .trueblocks-entrypoint.sh /entrypoint.sh
45+
RUN chmod +x /entrypoint.sh
46+
47+
EXPOSE 8080
48+
ENTRYPOINT ["/entrypoint.sh"]

trueblocks/build.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash
2+
# Builds the ethpandaops/trueblocks image. Invoked by the deploy action with
3+
# ${target_dockerfile} pointing at ./trueblocks/Dockerfile and the trueblocks-core
4+
# source already checked out at ./source. We stage entrypoint.sh into the
5+
# source tree (so the Dockerfile's COPY can reach it from the build context)
6+
# then build & push the standard tags.
7+
set -euo pipefail
8+
9+
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
10+
cd "${SCRIPT_DIR}/../source"
11+
12+
cp "${SCRIPT_DIR}/entrypoint.sh" ./.trueblocks-entrypoint.sh
13+
14+
build_arg_flags=()
15+
while IFS= read -r arg; do
16+
[ -n "${arg}" ] && build_arg_flags+=(--build-arg "${arg}")
17+
done <<< "${build_args:-}"
18+
19+
docker build \
20+
"${build_arg_flags[@]}" \
21+
-t "${target_repository}:${target_tag}" \
22+
-t "${target_repository}:${target_tag}-${source_git_commit_hash}" \
23+
-f "../${target_dockerfile}" \
24+
.
25+
26+
docker push "${target_repository}:${target_tag}"
27+
docker push "${target_repository}:${target_tag}-${source_git_commit_hash}"

trueblocks/entrypoint.sh

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/bin/sh
2+
# Bootstrap entrypoint for the ethpandaops/trueblocks image.
3+
#
4+
# Inputs are read from env vars; the ethereum-package launcher sets them, and
5+
# users running the image standalone can too (`docker run -e TB_CHAIN=…`).
6+
set -u
7+
8+
CHAIN="${TB_CHAIN:-mainnet}"
9+
RPC_URL="${TB_RPC_URL:-}"
10+
PROBE_ADDR="${TB_PROBE_ADDR:-}"
11+
SCRAPE_SLEEP="${TB_SCRAPE_SLEEP:-3}"
12+
HTTP_PORT="${TB_HTTP_PORT:-8080}"
13+
CONFIG_STAGING="${TB_CONFIG_STAGING:-/tb-config}"
14+
15+
CONFIG_DIR=/root/.local/share/trueblocks
16+
CHAIN_DIR="$CONFIG_DIR/config/$CHAIN"
17+
18+
mkdir -p "$CHAIN_DIR"
19+
20+
if [ -f "$CONFIG_STAGING/trueBlocks.toml" ]; then
21+
cp "$CONFIG_STAGING/trueBlocks.toml" "$CONFIG_DIR/trueBlocks.toml"
22+
fi
23+
24+
# chifra's IsNodeArchive picks the largest prefund in <chain>/allocs.csv and
25+
# compares its balance to the RPC's balance at block 0; without a matching row
26+
# it refuses to scrape. For chains we don't ship a bundled allocs.csv for, the
27+
# caller passes TB_PROBE_ADDR and we write a self-consistent row at runtime.
28+
# (The zero address won't work — chifra's Address.Hex() short-circuits to
29+
# "0x0", which fails its own IsValidAddress length check.)
30+
if [ -n "$PROBE_ADDR" ] && [ -n "$RPC_URL" ] && [ ! -f "$CHAIN_DIR/allocs.csv" ]; then
31+
BAL=""
32+
for _ in $(seq 1 60); do
33+
BAL=$(curl -fsS -X POST -H 'Content-Type: application/json' \
34+
-d "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBalance\",\"params\":[\"$PROBE_ADDR\",\"0x0\"],\"id\":1}" \
35+
"$RPC_URL" 2>/dev/null \
36+
| sed -n 's/.*"result":"\([^"]*\)".*/\1/p')
37+
echo "$BAL" | grep -qE '^0x[0-9a-fA-F]+$' && break
38+
sleep 2
39+
done
40+
echo "$BAL" | grep -qE '^0x[0-9a-fA-F]+$' || {
41+
echo "trueblocks entrypoint: balance probe of $PROBE_ADDR at $RPC_URL failed" >&2
42+
exit 1
43+
}
44+
printf 'address,balance\n%s,%s\n' "$PROBE_ADDR" "$BAL" > "$CHAIN_DIR/allocs.csv"
45+
fi
46+
47+
# chifra scrape exits non-zero before block 1 has been mined (it reads the RPC
48+
# error as "node lacks tracing"). Retry forever so it catches up once the
49+
# chain starts producing blocks.
50+
(
51+
while true; do
52+
chifra scrape --sleep "$SCRAPE_SLEEP" 2>&1
53+
sleep 5
54+
done
55+
) &
56+
57+
exec chifra daemon --url ":$HTTP_PORT"

0 commit comments

Comments
 (0)