Skip to content

Commit aa74809

Browse files
randygrokclaudejulienrbrtdependabot[bot]chatton
authored
feat: attester system (#230)
* feat: implement network module attesters return to evolve Add BeginBlocker logic for IBC_ONLY sign mode, add epoch end validation for soft confirmed checkpoints, update network keeper with BlockSource dependency, and add new validator hasher attester for CometBFT compatibility. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * go back to a stable point where IBC works * feat: unify validator hashing for attester and sequencer modes Add flag for NetworkSoftConfirmation, this means the node works using the attester system. Now the validator hasher changes depending if we are using attester mode or not. * Comment the part related to the blockFilter. * now blocks end point returns same block id as the sequencer is signing * Add endpoints for creation of attestaions and to provide the data throught endpoints * updates, not achieved yet, connection fails * golden commit, system works * fix issue with go mod and updates on go header * refactor: rename NetworkSoftConfirmation to AttesterMode and update related logic * add integration attester e2e workflow * change name integration attester * remove temporary the main on integration test branch * update ev node verrsion * revert ev-node version * upgrade version for ev node * update the attester yml * update the way we execute gaia * start new approach * improve ignite check * add evolve and scaffold chain * build binaries image * try build images * move build images * update docker compose * include the local-da option * use only push * use push * change the event * bring back the attester test with docker compose * run local da * add creating of docker compose local da * include gaia into the equation * update the cache * remove option of cache * add step to run gmd * add caches when building gmd * fix cache ignite cli, it needs to be before * fix some env variables problems on the script * Add integration tests * Refactor Dockerfiles and integration test scripts to use updated paths and streamline build process * remove binaries * fix paths inside github actions * update the ev node for the attester * update go path bin * use absolute pathE * use debian for gm image * refactor: update Dockerfile to use go install for local-da and modify CI cache settings * refactor: update Dockerfile and docker-compose to build local-da from rollkit module * refactor: update Dockerfile and docker-compose to build local-da from rollkit module * refactor: update Dockerfile.attester to ensure local ev-abci replacement points to the copied path * refactor: update Dockerfile.gm to use golang:1.24-bookworm and debian:bookworm-slim * be a little wide on the apps used for the app * include the attester * Revert "include the attester" This reverts commit 6062cc2. * feat: add attester module with Dockerfile and initial implementation * feat: add attester module with Dockerfile and initial implementation * feat: align module replacements and fetch dependencies in attester Dockerfile * feat: align module replacements and fetch dependencies in attester Dockerfile * feat: align module replacements and fetch dependencies in attester Dockerfile * feat: comment out Docker image build step in integration test workflow * feat: simplify Dockerfile by removing build stage and update docker-compose for Ignite CLI * feat: simplify Dockerfile by removing build stage and update docker-compose for Ignite CLI * feat: enhance debugging and logging in integration tests and initialization scripts * feat: add Go and Git to runtime dependencies in Dockerfile for Ignite operations * feat: enhance initialization script to ensure 'evolve' app availability and fallback to 'gmd genesis init' * feat: enhance initialization script to ensure 'evolve' app availability and fallback to 'gmd genesis init' * feat: update initialization script to improve Ignite home setup and adjust fallback command * feat: update initialization script to set default minimum-gas-prices and enable API in app.toml * feat: enhance Dockerfile and init script for improved Ignite app setup and evolve integration * feat: update init script and Docker configuration for improved Gaia chain setup * feat: simplify command in Docker Compose for init-gaia.sh execution * feat: add app wiring patch for ev-abci network module in Dockerfile and script * feat: enhance patch-app-wiring.sh to insert network module block conditionally * feat: refactor integration_attester_test.yml to streamline Ignite CLI setup and Gmd binary management * feat: update patch-app-wiring.sh to improve module block insertion logic * feat: enhance patch-app-wiring.sh to ensure robust insertion of network module block * feat: enhance Dockerfile and patch-app-wiring.sh for improved debugging and verification of app wiring * feat: improve idempotence checks in patch-app-wiring.sh for network module insertion * feat: simplify verification logic in patch-app-wiring.sh for network module * feat: simplify verification logic in patch-app-wiring.sh for network module * feat: simplify verification logic in patch-app-wiring.sh for network module * feat: enhance patch-app-wiring.sh to ensure network module inclusion in named lists * feat: enhance patch-app-wiring.sh to ensure network module inclusion in named lists * feat: enhance patch-app-wiring.sh to ensure network module inclusion in named lists * feat: enhance patch-app-wiring.sh to ensure network module inclusion in named lists * feat: improve patch-app-wiring.sh to handle tab formatting and clean up leading characters * feat: add fallback insertion for network module in InitGenesis function * feat: add targeted fallback insertion for network module in InitGenesis function * feat: refactor network module verification in patch-app-wiring.sh for improved robustness * feat: refactor network module verification in patch-app-wiring.sh for improved robustness * feat: enhance app wiring for network module with improved validation and configuration * feat: enhance app wiring for network module with improved validation and configuration * feat: update integration attester test workflow triggers for streamlined execution * feat: enhance integration test logging for attester service to improve troubleshooting * feat: enhance integration test logging for attester service to improve troubleshooting * feat: set default fee amount for transaction builder in main.go * feat: update fee amount setting in transaction builder for improved precision * feat: update fee amount setting in transaction builder to use cosmossdk.io/math for improved precision * feat: update Dockerfile.test to include gmd binary from gm-chain image * feat: update Dockerfile.test to build gmd binary directly and adjust docker-compose dependencies * feat: update Dockerfile.test to use golang:1.24-bookworm and improve package installation * feat: update Dockerfile.test to use debian:bookworm-slim for improved compatibility * feat: add gaiad binary download to Dockerfile.test for architecture support * Delete the compose folder * feat: update Gaia version to v25.1.0 and add Attester Mode integration test workflow * feat: add Bech32 prefix configuration for account and validator addresses * feat: update transaction message structure to include authority and consensus addresses * feat: update transaction message structure to include authority and consensus addresses * feat: improve error handling and clean up code in transaction processing * Fix go lint * feat: remove unused transport flag from start.go * feat: remove redundant test cases for validator existence and bonding status * feat: rename Rollkit to Evolve in main application and update README * feat: remove residual file * feat: add README for Evolve Network Module (beta) * feat: add README for Evolve Network Module (beta) * feat: safeguard against nil AppGenesis in validator address retrieval * feat: add comprehensive README for IBC integration tests in Evolve Network * feat: test new ev-node version (#254) * build(deps): bump latest ev-node (#253) * build(deps): bump latest ev-node * bump node everywehre * build(deps): bump github.com/libp2p/go-libp2p-pubsub (#252) Bumps the minor-updates group with 1 update: [github.com/libp2p/go-libp2p-pubsub](https://github.com/libp2p/go-libp2p-pubsub). Updates `github.com/libp2p/go-libp2p-pubsub` from 0.14.3 to 0.15.0 - [Release notes](https://github.com/libp2p/go-libp2p-pubsub/releases) - [Commits](libp2p/go-libp2p-pubsub@v0.14.3...v0.15.0) --- updated-dependencies: - dependency-name: github.com/libp2p/go-libp2p-pubsub dependency-version: 0.15.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-updates ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * use new ev-node version --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: julienrbrt <julien@rbrt.fr> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat: migrate attesters integration tests to tastora (#263) * build(deps): bump evstack (#255) * build(deps): bump evstack * bump ev-node * feat: add integration tests for Gaia GM health and update dependencies * refactor: validate ev-node config (#256) * refactor: validate ev-node config * deps * test: update liveness test to use multiple nodes (syncing through DA) (#216) * wip: pinning to local tastora checkout * wip: DA layer working, but P2P not configured * wip: parsing p2p address correctly, test still failing * test passing when not using P2P * chore: refactor to use test suite * chore: wip test passing via da * chore: update to use evnode cli flag * chore: add helper fn to add follower node * chore: update workflow to run specific test * deleted file * deps: bump tastora version * refactor(adapter): extract block id creation * wip: custom dockerfile * Update ev-node version and refactor cometcompat to adapter - Bump github.com/evstack/ev-node to v1.0.0-beta.2.0.20250821181753-974aa15383de - Move cometcompat helpers to adapter package and update imports - Remove cometcompat package and related files - Add providers.go to adapter for signature and validator hash providers - Refactor usage across codebase to use adapter package functions * typo + issue * bump commit * chore: sync'd w julien branch * attempt * latest commit * fix height 1 blockid * updates * linting * [wip] * debug lines * debug lines * fix merge * updates * chore: bump to tastora v0.3.0 * fix flags * fix empty state * debug logs * update tastora * debug * fix app * ... * trial * dbgs * updates * updates --------- Co-authored-by: Julien Robert <julien@rbrt.fr> * feat: update dependencies and improve Gaia GM health tests * feat: add Dockerfile for GM app and update health test integration * chore: configure gm prefix and uid * temp commit for Cian * feat: update Dockerfile and health tests for Gaia GM integration * feat: add attester Dockerfile and integration tests for GM chain * chore: attester fixes * feat: update attester to use armored private key and change address prefix to celestia * feat: update integration tests for IBC transfers and adjust EVNODE_VERSION * wip: fixing test * remove claude generated settings * golden commit, it works with tastora * clean test * feat: update Dockerfile and integration tests for improved image building * feat: update integration test workflow to set up Go and build attester Docker images * feat: update integration test command to run specific test suite in Docker * feat: refine integration test command to target specific test case --------- Co-authored-by: julienrbrt <julien@rbrt.fr> Co-authored-by: Cian Hatton <github.qpeyb@simplelogin.fr> * feat: add attester mode integration test to CI pipeline * chore: update EVNODE_VERSION to v1.0.0-beta.5 in integration tests * refactor(tests): reorganize imports for clarity and consistency * feat: add build and pull steps for attester and GM Docker images in CI pipeline * chore: update EVNODE_VERSION to v1.0.0-beta.5 and remove unused network soft confirmation block filter code * chore: update CI to use ubuntu-latest for building attester images * chore: update CI to use ubuntu-latest for building attester images * chore: simply workflows (#264) * chore: simply workflows * chore: removed more * refactor(adapter): remove commented-out block commit event handling code --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: julienrbrt <julien@rbrt.fr> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cian Hatton <github.qpeyb@simplelogin.fr>
1 parent b4f142b commit aa74809

49 files changed

Lines changed: 7155 additions & 384 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/integration_test.yml

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,92 @@ concurrency:
1111
cancel-in-progress: true
1212

1313
jobs:
14+
build-gm-image:
15+
name: Build GM Image
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 30
18+
permissions:
19+
contents: read
20+
packages: write
21+
outputs:
22+
image_tag: ${{ steps.tag.outputs.tag }}
23+
env:
24+
IGNITE_VERSION: v29.3.1
25+
IGNITE_EVOLVE_APP_VERSION: main
26+
EVNODE_VERSION: v1.0.0-beta.7
27+
steps:
28+
- uses: actions/checkout@v5
29+
30+
- name: Set up Docker Buildx
31+
uses: docker/setup-buildx-action@v3
32+
33+
- name: Log in to GHCR
34+
uses: docker/login-action@v3
35+
with:
36+
registry: ghcr.io
37+
username: ${{ github.actor }}
38+
password: ${{ secrets.GITHUB_TOKEN }}
39+
40+
- name: Determine image tag
41+
id: tag
42+
run: |
43+
if [ "${{ github.event_name }}" = "pull_request" ]; then
44+
echo "tag=ghcr.io/evstack/evolve-gm:pr-${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
45+
else
46+
echo "tag=ghcr.io/evstack/evolve-gm:${{ github.sha }}" >> "$GITHUB_OUTPUT"
47+
fi
48+
49+
- name: Build and push GM image
50+
uses: docker/build-push-action@v6
51+
with:
52+
context: .
53+
file: tests/integration/docker/Dockerfile.gm
54+
push: true
55+
tags: ${{ steps.tag.outputs.tag }}
56+
build-args: |
57+
IGNITE_VERSION=${{ env.IGNITE_VERSION }}
58+
IGNITE_EVOLVE_APP_VERSION=${{ env.IGNITE_EVOLVE_APP_VERSION }}
59+
EVNODE_VERSION=${{ env.EVNODE_VERSION }}
60+
61+
build-attester-image:
62+
name: Build Attester Image
63+
runs-on: ubuntu-latest
64+
timeout-minutes: 30
65+
permissions:
66+
contents: read
67+
packages: write
68+
outputs:
69+
image_tag: ${{ steps.tag.outputs.tag }}
70+
steps:
71+
- uses: actions/checkout@v5
72+
73+
- name: Set up Docker Buildx
74+
uses: docker/setup-buildx-action@v3
75+
76+
- name: Log in to GHCR
77+
uses: docker/login-action@v3
78+
with:
79+
registry: ghcr.io
80+
username: ${{ github.actor }}
81+
password: ${{ secrets.GITHUB_TOKEN }}
82+
83+
- name: Determine image tag
84+
id: tag
85+
run: |
86+
if [ "${{ github.event_name }}" = "pull_request" ]; then
87+
echo "tag=ghcr.io/evstack/attester:pr-${{ github.event.pull_request.number }}" >> "$GITHUB_OUTPUT"
88+
else
89+
echo "tag=ghcr.io/evstack/attester:${{ github.sha }}" >> "$GITHUB_OUTPUT"
90+
fi
91+
92+
- name: Build and push Attester image
93+
uses: docker/build-push-action@v6
94+
with:
95+
context: .
96+
file: tests/integration/docker/Dockerfile.attester
97+
push: true
98+
tags: ${{ steps.tag.outputs.tag }}
99+
14100
liveness-tastora:
15101
name: Test with EV-ABCI Chain (Tastora)
16102
runs-on: ubuntu-latest
@@ -276,6 +362,9 @@ jobs:
276362

277363
- name: Download gm Binary and gmd Home Directory
278364
uses: actions/download-artifact@v4 # keep v4.
365+
with:
366+
name: gmd
367+
path: gmd
279368

280369
- name: Download Gaia Binary
281370
run: |
@@ -478,3 +567,53 @@ jobs:
478567
if [[ -n "${HERMES_PID}" ]]; then
479568
kill -9 $HERMES_PID || true
480569
fi
570+
571+
attester-integration:
572+
needs: [build-gm-image, build-attester-image]
573+
name: Attester Mode Integration Test
574+
runs-on: ubuntu-latest
575+
timeout-minutes: 30
576+
env:
577+
DO_NOT_TRACK: true
578+
EVNODE_VERSION: "v1.0.0-beta.7"
579+
EVNODE_DA_VERSION: "v1.0.0-beta.1"
580+
IGNITE_VERSION: "v29.3.1"
581+
IGNITE_EVOLVE_APP_VERSION: "main"
582+
GAIA_VERSION: "v25.1.0"
583+
EVOLVE_IMAGE_REPO: "evabci/gm"
584+
EVOLVE_IMAGE_TAG: "local"
585+
586+
steps:
587+
- uses: actions/checkout@v5
588+
with:
589+
fetch-depth: 0
590+
591+
- name: Set up Go
592+
uses: actions/setup-go@v5
593+
with:
594+
go-version-file: go.mod
595+
596+
- name: Log in to GHCR
597+
uses: docker/login-action@v3
598+
with:
599+
registry: ghcr.io
600+
username: ${{ github.actor }}
601+
password: ${{ secrets.GITHUB_TOKEN }}
602+
603+
- name: Pull GM image from GHCR
604+
run: |
605+
docker pull ${{ needs.build-gm-image.outputs.image_tag }}
606+
docker tag ${{ needs.build-gm-image.outputs.image_tag }} evabci/gm:local
607+
608+
- name: Pull Attester image from GHCR
609+
run: |
610+
docker pull ${{ needs.build-attester-image.outputs.image_tag }}
611+
docker tag ${{ needs.build-attester-image.outputs.image_tag }} evabci/attester:local
612+
613+
- name: Run attester integration test
614+
working-directory: tests/integration
615+
env:
616+
GOTOOLCHAIN: auto
617+
VERBOSE: "true"
618+
run: |
619+
go test -v -run 'TestDockerIntegrationTestSuite/TestAttesterSystem' -count=1

Makefile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ pkgs := $(shell go list ./...)
44
run := .
55
count := 1
66

7+
IGNITE_VERSION ?= v29.3.1
8+
IGNITE_EVOLVE_APP_VERSION ?= main
9+
EVNODE_VERSION ?= v1.0.0-beta.5
10+
711
## help: Show this help message
812
help: Makefile
913
@echo " Choose a command run in "$(PROJECTNAME)":"
@@ -77,3 +81,22 @@ proto-gen:
7781
@rm -r modules/github.com
7882

7983
.PHONY: proto-gen
84+
85+
86+
## build-attester-docker-images: Build Docker images for the GM chain and attester integration tests
87+
build-attester-docker-images:
88+
@echo "--> Building GM integration Docker image"
89+
@docker build \
90+
-f tests/integration/docker/Dockerfile.gm \
91+
--build-arg IGNITE_VERSION=$(IGNITE_VERSION) \
92+
--build-arg IGNITE_EVOLVE_APP_VERSION=$(IGNITE_EVOLVE_APP_VERSION) \
93+
--build-arg EVNODE_VERSION=$(EVNODE_VERSION) \
94+
-t evabci/gm:local \
95+
.
96+
@echo "--> Building attester integration Docker image"
97+
@docker build \
98+
-f tests/integration/docker/Dockerfile.attester \
99+
-t evabci/attester:local \
100+
.
101+
102+
.PHONY: build-attester-docker-images

attester/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/attester

attester/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Evolve Attester (beta)
2+
3+
> Early, simplified attester mode. Work in progress – expect breaking changes and incomplete feature coverage.
4+
5+
This command-line helper joins the attester set of an Evolve-based chain and streams attestations for new blocks. It is the first public beta of the attester workflow and intentionally omits a number of production-hardening features (automatic key management, batching, robust persistence, etc.). The goal is to unblock experimentation on top of the upcoming attester mode.
6+
7+
## What it does
8+
9+
- Configures the Cosmos SDK Bech32 prefixes required by the target chain.
10+
- Derives an operator account key from a mnemonic and loads the validator consensus key from the local `priv_validator_key.json`.
11+
- Submits a `MsgJoinAttesterSet` transaction so the validator's consensus key is registered as an attester.
12+
- Polls the node's RPC (`/status` and `/block`) to detect new heights and rebuilds the Evolve header and original `BlockID` for each block.
13+
- Signs a precommit-style vote with the consensus key and wraps it in `MsgAttest` transactions paid for by the operator account.
14+
- Retries failed submissions a few times and keeps catching up when the attester falls behind.
15+
16+
## Prerequisites
17+
18+
- An Evolve node exposing RPC on `tcp://HOST:PORT` and REST API on `http://HOST:PORT`.
19+
- Access to the validator home directory so the attester can read `config/priv_validator_key.json` and `data/priv_validator_state.json`.
20+
- A funded Cosmos SDK account mnemonic that will cover the attestation fees.
21+
- The chain ID and Bech32 prefixes used by your deployment.
22+
23+
## Running the attester
24+
25+
Build with Go 1.22+:
26+
27+
```bash
28+
cd attester
29+
go build -o attester
30+
```
31+
32+
Run it against your node (adjust the sample values):
33+
34+
```bash
35+
./attester \
36+
--chain-id evmallus-1 \
37+
--node tcp://localhost:26657 \
38+
--api-addr http://localhost:1317 \
39+
--home /path/to/validator/home \
40+
--mnemonic "word1 word2 … word24" \
41+
--verbose
42+
```
43+
44+
### Important flags
45+
46+
- `--home` – validator home directory containing the CometBFT private validator files.
47+
- `--mnemonic` – Cosmos SDK mnemonic for the operator account that pays fees.
48+
- `--bech32-account-prefix` and friends – override if your chain does not use the defaults (`gm`, `gmvaloper`, etc.).
49+
- `--node` / `--api-addr` – RPC and REST endpoints used for account queries and block data.
50+
51+
## Operational notes
52+
53+
- The attester assumes the node accepts `MsgAttest` at every height. Current networks only process attestations at checkpoint heights (multiples of the epoch length); out-of-window submissions will be rejected with code 18 (`invalid request`).
54+
- Sequence numbers are cached in memory. Restarting the process while transactions are pending can still produce sequence mismatches.
55+
- HTTP polling currently drives block detection. There is no WebSocket subscription or backoff logic yet, so running it against remote nodes may require proxying/caching to avoid throttling.
56+
- Logging is verbose by default to aid debugging. Remove `--verbose` once the setup is stable.
57+
58+
## Limitations and future work
59+
60+
- No automatic key rotation or secure storage – mnemonic and consensus keys must be provided manually.
61+
- No persistence of attestation state across restarts beyond what the chain tracks.
62+
- Lacks production monitoring hooks, metrics, and alerting.
63+
- Error handling focuses on known happy paths; unexpected RPC responses will cause retries or exits.
64+
65+
Feedback is welcome. Please treat this module as beta software and be prepared for rapid iteration as the attester mode matures.

0 commit comments

Comments
 (0)