-
Notifications
You must be signed in to change notification settings - Fork 454
feat(link): custom light client - POC #1391
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
Draft
dhfang
wants to merge
17
commits into
main
Choose a base branch
from
feat/custom-light-client-cli
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
5168833
expose a public proof generator registry for custom light clients
dhfang 63ad7e7
feat(link): support custom light clients in compiled CLI
dhfang f393056
feat(link): add remote light client proof of concept
dhfang 8a59a76
test(e2e): relay with a remote custom light client
dhfang cf2c898
refactor(link): simplify custom prover factories
dhfang 2b51b5c
refactor(link): rename proof generator API to prover
dhfang 55da9de
refactor(link): colocate prover factory types
dhfang e3a8db8
refactor(link): remove internal prover alias
dhfang 9c886cd
docs(link): tighten custom prover comments
dhfang d6a1e43
test(e2e): remove redundant custom prover fixture
dhfang ba4319c
refactor(link): name custom prover factories explicitly
dhfang 6526cd4
test(e2e): simplify remote prover setup
dhfang 913ad65
refactor(link): use prover terminology in remote client
dhfang 2780159
chore(e2e): remove cometbft replace comment
dhfang d916511
docs(link): restore block header comment
dhfang 80ac2ea
fix(link): document proof kind constants
dhfang 6bf4b15
test(e2e): add remote prover to test matrix
dhfang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "os" | ||
|
|
||
| "github.com/cosmos/ibc/link/cli" | ||
| "github.com/cosmos/ibc/link/lightclient" | ||
| "github.com/cosmos/ibc/link/lightclient/remotepoc" | ||
| ) | ||
|
|
||
| func main() { | ||
| registry := lightclient.NewRegistry() | ||
| if err := registry.Register(remotepoc.Factory{}); err != nil { | ||
| panic(err) | ||
| } | ||
|
|
||
| root := cli.NewRootCmd(cli.Options{ | ||
| Relayer: cli.RelayerOptions{ProverFactories: registry}, | ||
| }) | ||
| os.Exit(cli.Execute(root)) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,132 @@ | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package e2e_test | ||
|
|
||
| import ( | ||
| "context" | ||
| "math/big" | ||
| "net" | ||
| "net/http" | ||
| "os" | ||
| "os/exec" | ||
| "path/filepath" | ||
| "strconv" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/stretchr/testify/require" | ||
|
|
||
| "github.com/cosmos/ibc/e2e/internal/e2etest" | ||
| "github.com/cosmos/ibc/e2e/internal/harness/environment" | ||
| "github.com/cosmos/ibc/e2e/internal/harness/ibclink" | ||
| relayerv2 "github.com/cosmos/ibc/link/api/v2/relayer" | ||
| "github.com/cosmos/ibc/link/lightclient/remotepoc" | ||
| ) | ||
|
|
||
| // TestRemoteAttestationLightClientRelaysPacket relays through a remote prover. | ||
| func TestRemoteAttestationLightClientRelaysPacket(t *testing.T) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E2E POC |
||
| // Build the downstream CLI that registers the remote prover factory. | ||
| t.Setenv("IBC_BIN", buildCustomIBC(t)) | ||
| ctx := t.Context() | ||
|
|
||
| listener, err := net.Listen("tcp", "127.0.0.1:0") | ||
| require.NoError(t, err) | ||
|
|
||
| spec, runtime := attestedMesh(e2etest.EVMChains( | ||
| t, e2etest.EVMRequirements{}, e2etest.ChainA, e2etest.ChainB, | ||
| )) | ||
| env := e2etest.Start(t, spec, runtime) | ||
| sender := e2etest.NewSigner(t) | ||
| route := e2etest.ManualAtoB(e2etest.ChainA, e2etest.ChainB) | ||
| var serviceConfig ibclink.RelayerConfig | ||
| // Keep the attestation config for the proof service, but configure the | ||
| // relayer to obtain those proofs from that service over HTTP. | ||
| driver, deployment := e2etest.DeployWithRelayerConfig( | ||
| t, | ||
| env, | ||
| sender, | ||
| e2etest.NewSigner(t), | ||
| func(cfg *ibclink.RelayerConfig) { | ||
| require.NotEmpty(t, cfg.Connections) | ||
| serviceConfig = cloneRelayerConfig(*cfg) | ||
| cfg.Connections[0].ClientAType = remotepoc.Type | ||
| cfg.Connections[0].ClientAParams = map[string]any{"url": "http://" + listener.Addr().String()} | ||
| }, | ||
| route, | ||
| ) | ||
| // Serve the built-in attestation prover behind the remote prover protocol. | ||
| serveAttestationProver(t, listener, env, serviceConfig) | ||
|
|
||
| // Relay a real packet through the custom-compiled CLI and remote prover. | ||
| relayer := e2etest.StartRelayer(t, driver, env) | ||
| transfer, err := e2etest.NewTransfer(t, env, deployment, sender, route).Send( | ||
| ctx, e2etest.TransferRequest{Amount: big.NewInt(1_234_000)}, | ||
| ) | ||
| require.NoError(t, err) | ||
| require.NoError(t, e2etest.RelayAll(ctx, relayer, transfer.PacketTx())) | ||
| _, err = e2etest.AwaitState( | ||
| ctx, relayer, transfer.PacketTx(), relayerv2.PacketState_PACKET_STATE_SUCCEEDED, | ||
| ) | ||
| require.NoError(t, err) | ||
| require.NoError(t, transfer.VerifyDelivered(ctx)) | ||
| } | ||
|
|
||
| func serveAttestationProver( | ||
| t *testing.T, | ||
| listener net.Listener, | ||
| env *environment.Environment, | ||
| cfg ibclink.RelayerConfig, | ||
| ) { | ||
| t.Helper() | ||
| useEnvironmentRPCs(t, env, &cfg) | ||
| configPath := filepath.Join(t.TempDir(), "attestation-proof-service.yaml") | ||
| require.NoError(t, ibclink.WriteRelayerConfig(configPath, cfg)) | ||
|
|
||
| client := cfg.Connections[0] | ||
| server, err := remotepoc.NewAttestationHandler(t.Context(), configPath, client.ChainA, client.ClientA) | ||
| require.NoError(t, err) | ||
| errs := make(chan error, 1) | ||
| go func() { errs <- server.Serve(listener) }() | ||
| t.Cleanup(func() { | ||
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
| defer cancel() | ||
| require.NoError(t, server.Shutdown(ctx)) | ||
| require.ErrorIs(t, <-errs, http.ErrServerClosed) | ||
| }) | ||
| } | ||
|
|
||
| func cloneRelayerConfig(cfg ibclink.RelayerConfig) ibclink.RelayerConfig { | ||
| cfg.Chains = append([]ibclink.RelayerChain(nil), cfg.Chains...) | ||
| cfg.Connections = append([]ibclink.RelayerConnection(nil), cfg.Connections...) | ||
| cfg.Attestors = append([]ibclink.RelayerAttestor(nil), cfg.Attestors...) | ||
| return cfg | ||
| } | ||
|
|
||
| func useEnvironmentRPCs( | ||
| t *testing.T, env *environment.Environment, cfg *ibclink.RelayerConfig, | ||
| ) { | ||
| t.Helper() | ||
| for i := range cfg.Chains { | ||
| for _, id := range env.Chains() { | ||
| chain, err := env.Chain(id) | ||
| require.NoError(t, err) | ||
| if strconv.FormatUint(chain.EVMChainID(), 10) == cfg.Chains[i].ChainID { | ||
| cfg.Chains[i].RPC = chain.RPCURL() | ||
| break | ||
| } | ||
| } | ||
| require.NotContains(t, cfg.Chains[i].RPC, "${") | ||
| } | ||
| } | ||
|
|
||
| func buildCustomIBC(t *testing.T) string { | ||
| t.Helper() | ||
|
|
||
| binary := filepath.Join(t.TempDir(), "ibc") | ||
| cmd := exec.CommandContext(t.Context(), "go", "build", "-o", binary, "./cmd/custom-ibc") | ||
| cmd.Env = append(os.Environ(), "GOCACHE="+filepath.Join(t.TempDir(), "go-cache")) | ||
| output, err := cmd.CombinedOutput() | ||
| require.NoError(t, err, "build custom ibc binary:\n%s", output) | ||
|
|
||
| return binary | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 is an example of how a consumer would construct the binary to compile their custom proving logic into the CLI.