mukan-ibc/e2e/relayer/relayer.go
Mukan Erkin Törük 6852832fe8
Some checks failed
CodeQL / Analyze (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Deploy to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled
Buf-Push / push (push) Has been cancelled
initial: sovereign Mukan Network fork
2026-05-11 03:18:28 +03:00

179 lines
5.7 KiB
Go

package relayer
import (
"context"
"errors"
"fmt"
"testing"
"github.com/cosmos/interchaintest/v10"
"github.com/cosmos/interchaintest/v10/ibc"
"github.com/cosmos/interchaintest/v10/relayer"
"github.com/cosmos/interchaintest/v10/relayer/hermes"
mobycli "github.com/moby/moby/client"
"github.com/pelletier/go-toml"
"go.uber.org/zap"
)
const (
Rly = "rly"
Hermes = "hermes"
HermesRelayerRepository = "ghcr.io/informalsystems/hermes"
hermesRelayerUser = "2000:2000"
RlyRelayerRepository = "ghcr.io/cosmos/relayer"
rlyRelayerUser = "100:1000"
// relativeHermesConfigFilePath is the path to the hermes config file relative to the home directory within the container.
relativeHermesConfigFilePath = ".hermes/config.toml"
)
// Config holds configuration values for the relayer used in the tests.
type Config struct {
// Tag is the tag used for the relayer image.
Tag string `yaml:"tag"`
// ID specifies the type of relayer that this is.
ID string `yaml:"id"`
// Image is the image that should be used for the relayer.
Image string `yaml:"image"`
}
// New returns an implementation of ibc.Relayer depending on the provided RelayerType.
func New(t *testing.T, cfg Config, logger *zap.Logger, dockerClient *mobycli.Client, network string) ibc.Relayer {
t.Helper()
switch cfg.ID {
case Rly:
return newCosmosRelayer(t, cfg.Tag, logger, dockerClient, network, cfg.Image)
case Hermes:
return newHermesRelayer(t, cfg.Tag, logger, dockerClient, network, cfg.Image)
default:
panic(fmt.Errorf("unknown relayer specified: %s", cfg.ID))
}
}
// ApplyPacketFilter applies a packet filter to the hermes config file, which specifies a complete set of channels
// to watch for packets.
func ApplyPacketFilter(ctx context.Context, t *testing.T, r ibc.Relayer, chainID string, channels []ibc.ChannelOutput) error {
t.Helper()
h, ok := r.(*hermes.Relayer)
if !ok {
t.Logf("relayer %T does not support packet filtering, or it has not been implemented yet.", r)
return nil
}
return modifyHermesConfigFile(ctx, h, func(config map[string]any) error {
chains, ok := config["chains"].([]map[string]any)
if !ok {
return errors.New("failed to get chains from hermes config")
}
var chain map[string]any
for _, c := range chains {
if c["id"] == chainID {
chain = c
break
}
}
if chain == nil {
return fmt.Errorf("failed to find chain with id %s", chainID)
}
var channelEndpoints [][]string
for _, c := range channels {
channelEndpoints = append(channelEndpoints, []string{c.PortID, c.ChannelID})
}
// [chains.packet_filter]
// # policy = 'allow'
// # list = [
// # ['ica*', '*'],
// # ['transfer', 'channel-0'],
// # ]
// TODO(chatton): explicitly enable watching of ICA channels
// this will ensure the ICA tests pass, but this will need to be modified to make sure
// ICA tests will succeed in parallel.
channelEndpoints = append(channelEndpoints, []string{"ica*", "*"})
// we explicitly override the full list, this allows this function to provide a complete set of channels to watch.
chain["packet_filter"] = map[string]any{
"policy": "allow",
"list": channelEndpoints,
}
return nil
})
}
// modifyHermesConfigFile reads the hermes config file, applies a modification function and returns an error if any.
func modifyHermesConfigFile(ctx context.Context, h *hermes.Relayer, modificationFn func(map[string]any) error) error {
bz, err := h.ReadFileFromHomeDir(ctx, relativeHermesConfigFilePath)
if err != nil {
return fmt.Errorf("failed to read hermes config file: %w", err)
}
var config map[string]any
if err := toml.Unmarshal(bz, &config); err != nil {
return errors.New("failed to unmarshal hermes config bytes")
}
if modificationFn != nil {
if err := modificationFn(config); err != nil {
return fmt.Errorf("failed to modify hermes config: %w", err)
}
}
bz, err = toml.Marshal(config)
if err != nil {
return errors.New("failed to marshal hermes config bytes")
}
return h.WriteFileToHomeDir(ctx, relativeHermesConfigFilePath, bz)
}
// newCosmosRelayer returns an instance of the go relayer.
// Options are used to allow for relayer version selection and specifying the default processing option.
func newCosmosRelayer(t *testing.T, tag string, logger *zap.Logger, dockerClient *mobycli.Client, network, relayerImage string) ibc.Relayer {
t.Helper()
customImageOption := relayer.CustomDockerImage(relayerImage, tag, rlyRelayerUser)
relayerProcessingOption := relayer.StartupFlags("-p", "events") // relayer processes via events
relayerFactory := interchaintest.NewBuiltinRelayerFactory(ibc.CosmosRly, logger, customImageOption, relayerProcessingOption)
return relayerFactory.Build(
t, dockerClient, network,
)
}
// newHermesRelayer returns an instance of the hermes relayer.
func newHermesRelayer(t *testing.T, tag string, logger *zap.Logger, dockerClient *mobycli.Client, network, relayerImage string) ibc.Relayer {
t.Helper()
customImageOption := relayer.CustomDockerImage(relayerImage, tag, hermesRelayerUser)
relayerFactory := interchaintest.NewBuiltinRelayerFactory(ibc.Hermes, logger, customImageOption)
return relayerFactory.Build(
t, dockerClient, network,
)
}
// Map is a mapping from test names to a relayer set for that test.
type Map map[string]map[ibc.Wallet]bool
// AddRelayer adds the given relayer to the relayer set for the given test name.
func (r Map) AddRelayer(testName string, ibcrelayer ibc.Wallet) {
if _, ok := r[testName]; !ok {
r[testName] = make(map[ibc.Wallet]bool)
}
r[testName][ibcrelayer] = true
}
// ContainsRelayer returns true if the given relayer is in the relayer set for the given test name.
func (r Map) ContainsRelayer(testName string, wallet ibc.Wallet) bool {
if relayerSet, ok := r[testName]; ok {
return relayerSet[wallet]
}
return false
}