Skip to content
This repository was archived by the owner on Apr 10, 2026. It is now read-only.

Commit be7e027

Browse files
authored
Use in process Relayer for race detection (#996)
* clone maps before passing to pathprocessor * Add local relayer implementation to help catch race conditions in CI * use existing relayerfactory * Isolate mutex to totalFees * handle feedback * fix fatalf format
1 parent 2c2c6a7 commit be7e027

13 files changed

Lines changed: 122 additions & 50 deletions

File tree

.github/workflows/ibctest.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
${{ runner.os }}-go-
2828
2929
- name: ibctest
30-
run: make ibctest-docker-events
30+
run: make ibctest-events
3131
legacy:
3232
runs-on: self-hosted
3333
steps:
@@ -48,7 +48,7 @@ jobs:
4848
${{ runner.os }}-go-
4949
5050
- name: ibctest
51-
run: make ibctest-docker-legacy
51+
run: make ibctest-legacy
5252
multiple-paths:
5353
runs-on: self-hosted
5454
steps:
@@ -69,4 +69,4 @@ jobs:
6969
${{ runner.os }}-go-
7070
7171
- name: ibctest
72-
run: make ibctest-docker-multiple
72+
run: make ibctest-multiple

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ ibctest-docker-events:
7878
ibctest-docker-legacy:
7979
cd ibctest && go test -race -v -run TestRelayerDockerLegacyProcessor .
8080

81-
ibctest-docker-multiple:
81+
ibctest-events:
82+
cd ibctest && go test -race -v -run TestRelayerEventProcessor .
83+
84+
ibctest-legacy:
85+
cd ibctest && go test -race -v -run TestRelayerLegacyProcessor .
86+
87+
ibctest-multiple:
8288
cd ibctest && go test -race -v -run TestRelayerMultiplePathsSingleProcess .
8389

8490
coverage:

cmd/config.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ $ %s cfg i`, appName, defaultHome, appName)),
153153
memo, _ := cmd.Flags().GetString(flagMemo)
154154

155155
// And write the default config to that location...
156-
if _, err = f.Write(defaultConfig(memo)); err != nil {
156+
if _, err = f.Write(defaultConfigYAML(memo)); err != nil {
157157
return err
158158
}
159159

@@ -432,12 +432,16 @@ func (c Config) MustYAML() []byte {
432432
return out
433433
}
434434

435-
func defaultConfig(memo string) []byte {
436-
return Config{
435+
func defaultConfigYAML(memo string) []byte {
436+
return DefaultConfig(memo).MustYAML()
437+
}
438+
439+
func DefaultConfig(memo string) *Config {
440+
return &Config{
437441
Global: newDefaultGlobalConfig(memo),
438-
Chains: relayer.Chains{},
439-
Paths: relayer.Paths{},
440-
}.MustYAML()
442+
Chains: make(relayer.Chains),
443+
Paths: make(relayer.Paths),
444+
}
441445
}
442446

443447
// GlobalConfig describes any global relayer settings

cmd/start.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
"github.com/cosmos/relayer/v2/internal/relaydebug"
2828
"github.com/cosmos/relayer/v2/relayer"
29+
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
2930
"github.com/cosmos/relayer/v2/relayer/processor"
3031
"github.com/spf13/cobra"
3132
"go.uber.org/zap"
@@ -96,6 +97,11 @@ $ %s start demo-path2 --max-tx-size 10`, appName, appName, appName)),
9697
log.Info("Debug server listening", zap.String("addr", debugAddr))
9798
relaydebug.StartDebugServer(cmd.Context(), log, ln)
9899
prometheusMetrics = processor.NewPrometheusMetrics()
100+
for _, chain := range chains {
101+
if ccp, ok := chain.ChainProvider.(*cosmos.CosmosProvider); ok {
102+
ccp.SetMetrics(prometheusMetrics)
103+
}
104+
}
99105
}
100106

101107
processorType, err := cmd.Flags().GetString(flagProcessor)

ibctest/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/cosmos/relayer/v2 v2.0.0
99
github.com/docker/docker v20.10.17+incompatible
1010
github.com/moby/moby v20.10.17+incompatible
11-
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220916051004-abcda680ee7d
11+
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220919160614-77d0523e3378
1212
github.com/stretchr/testify v1.8.0
1313
go.uber.org/zap v1.22.0
1414
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29

ibctest/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,8 @@ github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220916035922-bf1eb3ad8c6e h1
14741474
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220916035922-bf1eb3ad8c6e/go.mod h1:C284t8FhFrldr1BfQHDLsAMMzAWczTgeruePi7M6TmA=
14751475
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220916051004-abcda680ee7d h1:9f67V5dmwBcbQGZ7z5jmhjxPGkcGUJ6wmwHvXBgzK04=
14761476
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220916051004-abcda680ee7d/go.mod h1:C284t8FhFrldr1BfQHDLsAMMzAWczTgeruePi7M6TmA=
1477+
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220919160614-77d0523e3378 h1:xlSrlegNKmohCgDUdsXsCU2NZkQbl+/DNOjTcG5eVII=
1478+
github.com/strangelove-ventures/ibctest/v5 v5.0.0-20220919160614-77d0523e3378/go.mod h1:C284t8FhFrldr1BfQHDLsAMMzAWczTgeruePi7M6TmA=
14771479
github.com/strangelove-ventures/lens v0.5.2-0.20220822201013-1e7ffd450f20 h1:nYM1gFMJHbV3aYdiNCCS5jfBe/uMkORHwg8DSWZ5MRA=
14781480
github.com/strangelove-ventures/lens v0.5.2-0.20220822201013-1e7ffd450f20/go.mod h1:qrmVarKca7XLvuTEkR9jO50FrOprxQxukbmB7fpVrVo=
14791481
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=

ibctest/ibc_test.go

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
relayeribctest "github.com/cosmos/relayer/v2/ibctest"
8+
"github.com/cosmos/relayer/v2/relayer"
89
ibctest "github.com/strangelove-ventures/ibctest/v5"
910
"github.com/strangelove-ventures/ibctest/v5/conformance"
1011
"github.com/strangelove-ventures/ibctest/v5/ibc"
@@ -41,12 +42,11 @@ func TestRelayerInProcess(t *testing.T) {
4142
ibctestConformance(t, relayeribctest.RelayerFactory{})
4243
}
4344

44-
// TestRelayerDocker runs the ibctest conformance tests against
45+
// TestRelayerDockerEventProcessor runs the ibctest conformance tests against
4546
// the current state of this relayer implementation built in docker.
4647
// Relayer runs using the event processor.
4748
func TestRelayerDockerEventProcessor(t *testing.T) {
4849
t.Parallel()
49-
relayeribctest.BuildRelayerImage(t)
5050

5151
rf := ibctest.NewBuiltinRelayerFactory(
5252
ibc.CosmosRly,
@@ -59,7 +59,7 @@ func TestRelayerDockerEventProcessor(t *testing.T) {
5959
ibctestConformance(t, rf)
6060
}
6161

62-
// TestRelayerDocker runs the ibctest conformance tests against
62+
// TestRelayerDockerLegacyProcessor runs the ibctest conformance tests against
6363
// the current state of this relayer implementation built in docker.
6464
// Relayer runs using the legacy processor.
6565
func TestRelayerDockerLegacyProcessor(t *testing.T) {
@@ -76,3 +76,26 @@ func TestRelayerDockerLegacyProcessor(t *testing.T) {
7676

7777
ibctestConformance(t, rf)
7878
}
79+
80+
// TestRelayerEventProcessor runs the ibctest conformance tests against
81+
// the local relayer code. This is helpful for detecting race conditions.
82+
// Relayer runs using the event processor.
83+
func TestRelayerEventProcessor(t *testing.T) {
84+
t.Parallel()
85+
86+
ibctestConformance(t, relayeribctest.NewRelayerFactory(relayeribctest.RelayerConfig{
87+
Processor: relayer.ProcessorEvents,
88+
InitialBlockHistory: 100,
89+
}))
90+
}
91+
92+
// TestRelayerLegacyProcessor runs the ibctest conformance tests against
93+
// the local relayer code. This is helpful for detecting race conditions.
94+
// Relayer runs using the legacy processor.
95+
func TestRelayerLegacyProcessor(t *testing.T) {
96+
t.Parallel()
97+
98+
ibctestConformance(t, relayeribctest.NewRelayerFactory(relayeribctest.RelayerConfig{
99+
Processor: relayer.ProcessorLegacy,
100+
}))
101+
}

ibctest/relay_many_test.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
ibctest "github.com/strangelove-ventures/ibctest/v5"
1010
"github.com/strangelove-ventures/ibctest/v5/chain/cosmos"
1111
"github.com/strangelove-ventures/ibctest/v5/ibc"
12-
ibctestrelayer "github.com/strangelove-ventures/ibctest/v5/relayer"
1312
"github.com/strangelove-ventures/ibctest/v5/test"
1413
"github.com/strangelove-ventures/ibctest/v5/testreporter"
1514
"github.com/stretchr/testify/require"
@@ -21,15 +20,7 @@ import (
2120
// from the same process using the go relayer. A single
2221
// CosmosChainProcessor (gaia) will feed data to two PathProcessors (gaia-osmosis and gaia-juno).
2322
func TestRelayerMultiplePathsSingleProcess(t *testing.T) {
24-
relayeribctest.BuildRelayerImage(t)
25-
26-
client, network := ibctest.DockerSetup(t)
27-
r := ibctest.NewBuiltinRelayerFactory(
28-
ibc.CosmosRly,
29-
zaptest.NewLogger(t),
30-
ibctestrelayer.CustomDockerImage(relayeribctest.RelayerImageName, "latest", "100:1000"),
31-
ibctestrelayer.ImagePull(false),
32-
).Build(t, client, network)
23+
r := relayeribctest.NewRelayer(t, relayeribctest.RelayerConfig{})
3324

3425
rep := testreporter.NewNopReporter()
3526
eRep := rep.RelayerExecReporter(t)
@@ -84,6 +75,8 @@ func TestRelayerMultiplePathsSingleProcess(t *testing.T) {
8475
Path: pathGaiaJuno,
8576
})
8677

78+
client, network := ibctest.DockerSetup(t)
79+
8780
require.NoError(t, ic.Build(ctx, eRep, ibctest.InterchainBuildOptions{
8881
TestName: t.Name(),
8982
Client: client,

ibctest/relayer.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"strconv"
78
"strings"
89
"testing"
910

1011
"github.com/cosmos/cosmos-sdk/crypto/keyring"
1112
"github.com/cosmos/relayer/v2/cmd"
1213
"github.com/cosmos/relayer/v2/internal/relayertest"
14+
"github.com/cosmos/relayer/v2/relayer"
1315
"github.com/cosmos/relayer/v2/relayer/chains/cosmos"
1416
"github.com/strangelove-ventures/ibctest/v5/ibc"
1517
"go.uber.org/zap"
@@ -19,13 +21,33 @@ import (
1921
type Relayer struct {
2022
t *testing.T
2123

22-
home string
24+
config RelayerConfig
25+
home string
2326

2427
// Set during StartRelayer.
2528
errCh chan error
2629
cancel context.CancelFunc
2730
}
2831

32+
// Build returns a relayer interface
33+
func NewRelayer(
34+
t *testing.T,
35+
config RelayerConfig,
36+
) ibc.Relayer {
37+
r := &Relayer{
38+
t: t,
39+
home: t.TempDir(),
40+
config: config,
41+
}
42+
43+
res := r.sys().Run(zaptest.NewLogger(t), "config", "init", "--memo", config.Memo)
44+
if res.Err != nil {
45+
t.Fatalf("failed to rly config init: %v", res.Err)
46+
}
47+
48+
return r
49+
}
50+
2951
func (r *Relayer) sys() *relayertest.System {
3052
return &relayertest.System{HomeDir: r.home}
3153
}
@@ -47,10 +69,11 @@ func (r *Relayer) AddChainConfiguration(ctx context.Context, _ ibc.RelayerExecRe
4769
KeyringBackend: keyring.BackendTest,
4870
GasAdjustment: chainConfig.GasAdjustment,
4971
GasPrices: chainConfig.GasPrices,
50-
Debug: true,
51-
Timeout: "10s",
52-
OutputFormat: "json",
53-
SignModeStr: "direct",
72+
// MinGasAmount: chainConfig.MinGasAmount, // TODO
73+
Debug: true,
74+
Timeout: "10s",
75+
OutputFormat: "json",
76+
SignModeStr: "direct",
5477
},
5578
})
5679

@@ -197,12 +220,22 @@ func (r *Relayer) StartRelayer(ctx context.Context, _ ibc.RelayerExecReporter, p
197220
r.errCh = make(chan error, 1)
198221
ctx, r.cancel = context.WithCancel(ctx)
199222

200-
args := append([]string{"--processor=events"}, pathNames...)
223+
if r.config.Processor == "" {
224+
r.config.Processor = relayer.ProcessorEvents
225+
}
226+
args := append([]string{
227+
"--processor", r.config.Processor,
228+
"--block-history", strconv.FormatUint(r.config.InitialBlockHistory, 10),
229+
}, pathNames...)
230+
201231
go r.start(ctx, args...)
202232
return nil
203233
}
204234

205235
func (r *Relayer) StopRelayer(ctx context.Context, _ ibc.RelayerExecReporter) error {
236+
if r.cancel == nil {
237+
return nil
238+
}
206239
r.cancel()
207240
err := <-r.errCh
208241

ibctest/relayer_factory.go

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
package ibctest
22

33
import (
4-
"fmt"
54
"testing"
65

76
"github.com/docker/docker/client"
87
"github.com/strangelove-ventures/ibctest/v5/ibc"
98
"github.com/strangelove-ventures/ibctest/v5/label"
109
ibctestrelayer "github.com/strangelove-ventures/ibctest/v5/relayer"
11-
"go.uber.org/zap/zaptest"
1210
)
1311

1412
// RelayerFactory implements the ibctest RelayerFactory interface.
15-
type RelayerFactory struct{}
13+
type RelayerFactory struct {
14+
config RelayerConfig
15+
}
16+
17+
// LocalRelayerConfig defines parameters for customizing a LocalRelayer.
18+
type RelayerConfig struct {
19+
Processor string
20+
Memo string
21+
InitialBlockHistory uint64
22+
}
23+
24+
func NewRelayerFactory(config RelayerConfig) RelayerFactory {
25+
return RelayerFactory{
26+
config: config,
27+
}
28+
}
1629

1730
// Build returns a relayer interface
18-
func (RelayerFactory) Build(
31+
func (rf RelayerFactory) Build(
1932
t *testing.T,
2033
_ *client.Client,
2134
networkID string,
2235
) ibc.Relayer {
23-
r := &Relayer{
24-
t: t,
25-
home: t.TempDir(),
26-
}
27-
28-
res := r.sys().Run(zaptest.NewLogger(t), "config", "init")
29-
if res.Err != nil {
30-
panic(fmt.Errorf("failed to rly config init: %w", res.Err))
31-
}
32-
33-
return r
36+
return NewRelayer(t, rf.config)
3437
}
3538

3639
func (RelayerFactory) Capabilities() map[ibctestrelayer.Capability]bool {

0 commit comments

Comments
 (0)