Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
0a5cba7
add relayer config
dhfang Jul 10, 2026
56048f1
test(link): add E2E harness foundations
gjermundgaraba Jul 11, 2026
0949773
test(link): add E2E harness runtime
gjermundgaraba Jul 10, 2026
c4f9613
test(link): add EVM stub relayer
gjermundgaraba Jul 10, 2026
4a294dd
test(link): add EVM E2E suites and repository wiring
gjermundgaraba Jul 10, 2026
28174df
derive chain type from evm block and nest rpc
dhfang Jul 13, 2026
393250e
validate chain references in cross validation
dhfang Jul 13, 2026
29b14a0
validate evm fields only for evm chains
dhfang Jul 13, 2026
aac200c
add relayer store
dhfang Jul 12, 2026
d449da6
Merge remote-tracking branch 'origin/development' into feat/relayer-s…
dhfang Jul 13, 2026
b53c402
split store migrations per table
dhfang Jul 13, 2026
09e69eb
accept a create packet input in the store
dhfang Jul 13, 2026
dbeba36
remove unused status text column
dhfang Jul 13, 2026
f2006be
add relayer grpc server
dhfang Jul 13, 2026
4f56881
remove header fetch comment
dhfang Jul 13, 2026
c8aa8d6
clarify store interface comment
dhfang Jul 13, 2026
4360f68
simplify packet state comment
dhfang Jul 13, 2026
c8dee2d
log relay and status handler calls
dhfang Jul 13, 2026
35fd337
reword tx hash casing comment
dhfang Jul 13, 2026
8ed6c28
trim status rpc comment
dhfang Jul 13, 2026
554584e
restore goconst lint exception in keys
dhfang Jul 13, 2026
938c006
simplify chains client comment
dhfang Jul 13, 2026
76bbd7a
shorten evm client test name
dhfang Jul 13, 2026
3c5e9be
error on unsupported chain type in client manager
dhfang Jul 13, 2026
7d36014
reword store interface comment
dhfang Jul 13, 2026
079a394
log relay and status calls in the service
dhfang Jul 13, 2026
bc1e55e
move call logs back to the handlers
dhfang Jul 13, 2026
c4f858f
document unknown client expectation in relay test
dhfang Jul 13, 2026
ccecece
treat missing chain client as internal and cover header errors
dhfang Jul 13, 2026
9d4c4b5
ffs
gjermundgaraba Jul 14, 2026
709022f
Merge remote-tracking branch 'origin/development' into feat/relayer-s…
dhfang Jul 14, 2026
fa8c245
just keep on ffs
gjermundgaraba Jul 14, 2026
e019e81
test: move e2e infrastructure to repository root
gjermundgaraba Jul 14, 2026
3fee216
Merge remote-tracking branch 'origin/development' into gjermund/e2e-arch
gjermundgaraba Jul 14, 2026
9143869
refactor(e2e): simplify harness resource tracking
gjermundgaraba Jul 14, 2026
a37aa38
Merge pr-1272 (relayer grpc service) into gjermund/full-pupp
gjermundgaraba Jul 14, 2026
b791c75
feat(link): attestation encoding library + EVM chain client extensions
gjermundgaraba Jul 14, 2026
eef2f30
feat(store): packet lifecycle transitions, tx-submission tracking, re…
gjermundgaraba Jul 14, 2026
2c121be
feat(attestor): full ADR-010 attestation service
gjermundgaraba Jul 14, 2026
aa37a5f
feat(cli): structured config validation and sysexits
gjermundgaraba Jul 14, 2026
dc3aa0f
feat(relay): attestor aggregation ProofGenerator
gjermundgaraba Jul 14, 2026
9309d42
fix: address sol review findings on relay registration and signing
gjermundgaraba Jul 14, 2026
8434bc6
feat(relay): packet lifecycle engine
gjermundgaraba Jul 14, 2026
4b8d468
feat(relayer): wire relay engine into ibc relayer run
gjermundgaraba Jul 14, 2026
e22f989
feat(relayer): daemon wire surface for ibc relayer run
gjermundgaraba Jul 14, 2026
ab5e20d
feat(e2e): truthful Relayer resource in the harness
gjermundgaraba Jul 14, 2026
f20381b
fix(e2e): managed attestor emits chains + evm attestation config
gjermundgaraba Jul 14, 2026
012c941
feat(e2e): truthful IFT transfer suite over the real relayer
gjermundgaraba Jul 14, 2026
b0f166a
fix(e2e): stub tables collide with real-binary migrations in shared s…
gjermundgaraba Jul 14, 2026
c137d6c
chore(e2e): fix pre-existing harness lint issues
gjermundgaraba Jul 14, 2026
983217d
fix: address second-round review findings (safety + correctness)
gjermundgaraba Jul 14, 2026
1d39a40
refactor: deslop cleanup pass
gjermundgaraba Jul 14, 2026
72af3d6
refactor(e2e): adopt typed ecosystem dependencies
gjermundgaraba Jul 14, 2026
ade7e8f
refactor(e2e): simplify harness tests and readiness
gjermundgaraba Jul 14, 2026
f9b54a1
refactor(e2e): simplify harness and isolate stub storage
gjermundgaraba Jul 14, 2026
e2d62bb
feat(link): harden relayer/attestor core, add observability and tx ou…
gjermundgaraba Jul 14, 2026
b62ad91
feat(cli): one-step ibc deploy/connect commands
gjermundgaraba Jul 14, 2026
b9e9d90
feat(e2e): dual-mode relayer, lane-aware protocol suite, Besu coverage
gjermundgaraba Jul 14, 2026
71e48c6
feat(link): close review findings, add operator surface
gjermundgaraba Jul 14, 2026
13d5cb6
feat(e2e): truthful lifecycle and resilience matrix for the real relayer
gjermundgaraba Jul 14, 2026
9147eb3
refactor e2e harness and keyfile handling
gjermundgaraba Jul 14, 2026
3e23459
Move e2e stub implementation into Link
gjermundgaraba Jul 14, 2026
fcf11f1
test(e2e): flatten acceptance suite
gjermundgaraba Jul 14, 2026
667ce3f
refactor(e2e): remove nested harness internal tree
gjermundgaraba Jul 15, 2026
f4931fd
refactor: remove e2e transition scaffolding
gjermundgaraba Jul 15, 2026
81f2777
refactor(e2e): consolidate traffic helpers
gjermundgaraba Jul 15, 2026
6ff0994
Merge remote-tracking branch 'origin/development' into gjermund/e2e-arch
gjermundgaraba Jul 15, 2026
d28be8e
cleanly
gjermundgaraba Jul 15, 2026
5e085b4
feat(e2e): retire the stub lane; the real binary carries all coverage
gjermundgaraba Jul 15, 2026
00bee3e
fix(e2e): preserve Besu workspace ownership
gjermundgaraba Jul 15, 2026
9c0dbcd
Merge origin/gjermund/e2e-arch into gjermund/full-pupp
gjermundgaraba Jul 15, 2026
778a7c5
fix: survive hung RPC endpoints after the pause-based node faults
gjermundgaraba Jul 15, 2026
6519d75
im not here, i promise - this was just uncomitted from yesterday
gjermundgaraba Jul 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .docs/ADR-009-Port-Proof-API-Attestor-to-Go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
Here is the result of "view" for the Page with URL https://app.notion.com/p/3898c17818cb8030bcece5a4d3b55849 as of 2026-06-24T16:37:44.507Z:
<page url="https://app.notion.com/p/3898c17818cb8030bcece5a4d3b55849">
<ancestor-path>
<parent-page url="https://app.notion.com/p/3828c17818cb807fb5fce4b93c1a415a" title="ADRs (Architecture Decision Records)"/>
<ancestor-2-page url="https://app.notion.com/p/3828c17818cb80998a62d040b2acb5cd" title="Engineering"/>
<ancestor-3-page url="https://app.notion.com/p/3378c17818cb808cbbd2cebe4de9bac3" title="Foundations Team Hub"/>
</ancestor-path>
<properties>
{"title":"ADR-009 Port Proof API + Attestor to Go"}
</properties>
<content>
<empty-block/>
## ADR-009: Port Proof API + Attestor to Go (vs keep Rust binary)
**Status:** `Proposed`
**Date:** 2026-06-23
**Deciders:** <mention-user url="user://773fef25-cd11-48a6-a5f3-bb95667f7c6c"/> <mention-user url="user://15dd872b-594c-810d-aeea-00025475a498"/> <mention-user url="user://2e1d872b-594c-814c-8191-000286abd10c"/>
---
### Context
We need to decide whether we should port the relevant V1 functionality of the rust Proof API + `ibc-attestor` binary into Go or whether IBC Link should execute parts of it in a rust subprocess.
A PoC exists that runs the Rust attestor under a Go host (via `go-plugin`) to explore how usable it is, whether we can achieve our goals of a unified YAML config surface and whether it meets our operational needs. It does not materially change the underlying reality that we are still shipping and executing a Rust binary.
### PoC
[GitHub - cosmos/ibc-attestor at go-plugin-poc](https://github.com/cosmos/ibc-attestor/tree/go-plugin-poc)
The PoC runs the rust ibc attestor as a go-plugin under a Go host and then fetches an attestation from the attestor, verifies logs are surfaced on the host, scrapes metrics, and intentionally kills and restarts the attestor subprocess.
**Configuration Surface**
The PoC demonstrates how we can still achieve the goals of providing a unified yaml configuration file for the ibc-link binary. The host program in the PoC takes the given yaml config and writes the attestor config values to a temp toml file in the form the attestor binary expects. The spawned attestor subprocess references the temp <span color="purple_bg">toml config file.</span> The temporary file may present some friction in read-only deployment environments.
**Logging**
The PoC demonstrates that attestor logs are surfaced in the host process. Considerations here are:
- that go-plugin relies on stdout to perform a handshake between between the plugin and host and so the attestor routes all application logs to stderr in plugin mode.
- go-plugin relies on hclog for logging, so there would be a bit of additional work to make logs consistent if the host relies on a different logging library.
**Standalone Attestor Considerations**
One of the primary value props of go-plugin is the negotiation of a private connection between the plugin and the host. This benefit is moot when the attestor is run standalone as the attestor needs to bind on a fixed port that external traffic can be routed to.
**Attestor Binary**
The host process needs a reference to the attestor rust binary. The PoC assumes the attestor binary is in the same directory as the attestor binary. This is a detail we can hide in any containerized release artifact, but it still doesn’t change the underlying fact that we are shipping a rust binary in addition to the ibc-link binary.
**Attestor Code Additions**
Non-go plugins requires a bit more overhead to integrate than go plugins. The PoC adds \~150 LoC that:
- Adds a plugin mode
- Serves a grpc health service that go-plugin requires every gRPC plugin to serve
- Routes logs to stderr in plugin mode
- Binds to a free port
- Performs the plugin handshake with the host over stdout that announces what port it’s running on.
**Metrics**
The host process and subprocess will have different metrics registries which are scraped from different endpoints. Work would need to be done if wanting to provide a unified metrics endpoint.
**Takeaways**
- It’s pretty simple to run the attestor as a plugin and it serves our needs with some rough edges.
- It’s not some huge unlock. We can do something similar with standard libraries and some lightweight subprocess management logic. Given that running the attestor as sub-process alongside the relayer should only be used in PoC or testing environments, we have no need for some of the production oriented functionality that go-plugin provides like AutoMTLS, plugin host connection privacy, version negotation.
- Obvious but single binary is an illusion. There is still a rust binary that we must compile into any artifact we release and we will have toolchains for both rust and go. Local testing using the ibc-link binary will also rely on the attestor rust binary being compiled and we should provide make commands that handle this.
### Options Considered
### Option A: Run Rust logic in subprocess
- **Pros:**
- Minimal engineering investment
- Reuses audited code
- **Cons:**
- Still requires compiling and distributing a Rust artifact
- go-plugin adds constraints (stdout handshake, log routing to stderr, disjoint metrics registries, dependency on `hclog`)
- Increases debugging complexity
- Config surface must be bridged (YAML → temp TOML) and kept in sync
- Operational integration remains more complex than a native implementation.
- Requires both rust and go toolchain
### Option B: Port the relevant V1 Proof API + attestor logic to Go
- **Pros:**
- Aligns mission-critical code with Go (our preferred language)
- Eliminates Rust binary distribution and cross-language integration glue
- Simplifies debugging/ops
- Likely easiest to do now while scope is constrained
- Can use cosmos/kms signing libraries in attestor
- **Cons:**
- Higher upfront cost
- Must re-establish correctness, test coverage
- Requires internal audit of attestor
- Risk of regressions during port
### Decision
<span discussion-urls="discussion://3898c178-18cb-8030-bcec-e5a4d3b55849/3898c178-18cb-80cd-8b3d-f27c63fe57ae/3898c178-18cb-80c0-b6cf-001c815e32f4">We should port the relevant parts of the Proof API and the attestor to Go for V1.</span>
Primary justification: The V1 scope is limited (excluding Cosmos- and Solana-specific logic), and it will never be easier to do than it is now. Our previous discussion around language uncovered compelling reasons why we would want mission critical code to be in golang and I think if we don’t port it now it is unlikely to happen. The longer the rust logic is used in production the worse the tradeoff becomes as we will be trading production-tested code reviewed under the bug bounty program for brand new code.
Rough sizing estimate: Proof API port in \< 1.5 fte weeks; attestor port in \< 3 fte weeks.
Fallback: I don’t expect the port to be difficult, but if we run into unanticipated issues we can always fallback to the more minimal effort rust as subprocess route.
### Scope of Port
Proof-Api
- \~1.5k LoC
Aggregator (attestor fan-out / quorum)
- [mod.rs](http://mod.rs)
- [quorum.rs](http://quorum.rs)
- [attestor_](https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/aggregator/attestor_data.rs)[data.rs](https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/aggregator/attestor_data.rs)
- [config.rs](http://config.rs)
Attested EVM proof building<br>[https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/eth_attested.rs](https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/eth_attested.rs) <br>[https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/attestor.rs](https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/attestor.rs) <br>[https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/eth_eureka.rs](https://github.com/cosmos/solidity-ibc-eureka/blob/main/packages/proof-api/lib/src/utils/eth_eureka.rs)
Attestor
We are relying on everything except the cosmos and solana related logic in the V1. The complexity is concentrated in the files below with the rest of the service being pretty standard grpc service plumbing, configuration, and signer logic which we will be relying on cosmos/kms for. \~1.4k LoC total for the files below<br><br>[https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/rpc/attestor.rs](https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/rpc/attestor.rs) <br>[https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/attestation.rs](https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/attestation.rs) <br>[https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/attestation_payload.rs](https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/attestation_payload.rs) <br>[https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/adapter/evm.rs](https://github.com/cosmos/ibc-attestor/blob/main/apps/ibc-attestor/src/adapter/evm.rs)
### Tradeoffs Accepted
- We accept short-term delivery risk and increased testing/review work in exchange for a cleaner long-term architecture and lower operational complexity.
- We accept losing some immediate benefit of upstream Rust maturity in favor of consolidating language/runtime for mission-critical services.
### Consequences
- Engineering work: implement Go equivalents for the V1-required Proof API + attestor components; add compatibility tests against current behavior; audit.
---
*Links: *
[GitHub - cosmos/ibc-attestor at go-plugin-poc](https://github.com/cosmos/ibc-attestor/tree/go-plugin-poc)
---
<empty-block/>
</content>
</page>
Loading