Skip to content
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

perf(cw-relayer): improvements #68

Merged
merged 14 commits into from
Apr 5, 2023
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ test-unit-contract:
compile-contract:
cosmwasm/scripts/build_artifacts.sh

start-relayer:
cd cw-relayer && ${MAKE} start

test-e2e:
@echo "Running e2e tests"
${MAKE} compile-contract
Expand Down
41 changes: 39 additions & 2 deletions cw-relayer/cmd/cw-relayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ func cwRelayerCmdHandler(cmd *cobra.Command, args []string) error {
return fmt.Errorf("failed to parse Event timeout: %w", err)
}

maxTickTimeout, err := time.ParseDuration(cfg.MaxTickTimeout)
if err != nil {
return fmt.Errorf("failed to parse Event timeout: %w", err)
}

queryTimeout, err := time.ParseDuration(cfg.QueryTimeout)
if err != nil {
return fmt.Errorf("failed to parse Query timeout: %w", err)
}

resolveDuration, err := time.ParseDuration(cfg.ResolveDuration)
if err != nil {
return fmt.Errorf("failed to parse Resolve Duration: %w", err)
Expand All @@ -127,6 +137,7 @@ func cwRelayerCmdHandler(cmd *cobra.Command, args []string) error {
cfg.Keyring.Dir,
keyringPass,
cfg.RPC.TMRPCEndpoint,
cfg.RPC.QueryEndpoint,
rpcTimeout,
cfg.Account.Address,
cfg.Account.AccPrefix,
Expand All @@ -138,12 +149,38 @@ func cwRelayerCmdHandler(cmd *cobra.Command, args []string) error {
}

// subscribe to new block heights
blockEvent, err := relayerclient.NewBlockHeightSubscription(ctx, cfg.EventRPC, eventTimeout, cfg.TickEventType, logger)
tick, err := relayerclient.NewBlockHeightSubscription(
ctx,
cfg.EventRPCS,
eventTimeout,
maxTickTimeout,
cfg.TickEventType,
logger,
cfg.Restart.SkipError,
cfg.MaxRetries,
)
if err != nil {
return err
}

newRelayer := relayer.New(logger, client, cfg.ContractAddress, cfg.TimeoutHeight, cfg.MissedThreshold, cfg.QueryRPC, blockEvent.Tick, cfg.MedianDuration, resolveDuration, cfg.RequestID, cfg.MedianRequestID)
newRelayer := relayer.New(
logger,
client,
cfg.ContractAddress,
cfg.TimeoutHeight,
cfg.MissedThreshold,
cfg.MaxRetries,
cfg.MedianDuration,
resolveDuration,
queryTimeout,
cfg.RequestID,
cfg.MedianRequestID,
cfg.DeviationRequestID,
relayer.AutoRestartConfig{AutoRestart: cfg.Restart.AutoID, Denom: cfg.Restart.Denom, SkipError: cfg.Restart.SkipError},
tick.Tick,
cfg.QueryRPCS,
)

g.Go(func() error {
// start the process that queries the prices on Ojo & submits them on Wasmd
return startPriceRelayer(ctx, logger, newRelayer)
Expand Down
35 changes: 28 additions & 7 deletions cw-relayer/config.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,44 @@
### gas adjustment - multiplier for the expected amount of gas
contract_address = "wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d"
# query rpc for prices
query_rpc = "api.devnet-n0.ojo-devnet.node.ojo.network:9090"

# relayer changes rpcs (event and query) in the order specified in config
# query rpcs for prices
query_rpcs = ["api.devnet-n0.ojo-devnet.node.ojo.network:9090","api.devnet-n1.ojo-devnet.node.ojo.network:9090","api.devnet-n2.ojo-devnet.node.ojo.network:9090"]
# event rpc to subscribe for new block and set fx rate event
event_rpc = "https://rpc.devnet-n0.ojo-devnet.node.ojo.network:443"
event_rpcs = ["https://rpc.devnet-n0.ojo-devnet.node.ojo.network:443","https://rpc.devnet-n2.ojo-devnet.node.ojo.network:443"]
# event type string to check when new blocks are produced
event_type = "ojo.oracle.v1.EventSetFxRate"

event_timeout = "1000ms"

# max duration between ticks (to trigger a event rpc change)
max_tick_timeout = "500s"
query_timeout = "3000ms"

# max query retries to fetch exchange rates or connect to event rpc at startup
max_retries = 1

# gas adjustment - multiplier for the expected amount of gas
gas_adjustment = 1.5
timeout_height = 10
gas_prices = "0.2stake"
# set median duration to 0 to disable posting medians
median_duration = 0
median_duration = 1
# resolve duration is the estimated delay between price updates on the contract
resolve_duration = "1000ms"
missed_threshold = 2
#default median data and ref request id at start/restart

# default median data and ref request id at start/restart
median_request_id = 0
request_id = 0
deviation_request_id = 0

# restart config
[restart]
# fetches request, median and deviation id for denom and set it as default in case of a restart
auto_id = true
denom = "ATOM"
# sets request, median and deviation id to id's mentioned in config, shuts down the relayer otherwise
skip_error = true

### account & chain-id for the wasmd relayer account
[account]
Expand All @@ -32,5 +52,6 @@ dir = "./"

### rpc endpoint for the wasm Chain
[rpc]
rpc_timeout = "100ms"
rpc_timeout = "2000ms"
query_endpoint = "0.0.0.0:9090"
tmrpc_endpoint = "http://localhost:26657"
53 changes: 39 additions & 14 deletions cw-relayer/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ const (
defaultProviderTimeout = 100 * time.Millisecond
defaultQueryRPC = "0.0.0.0:9091"
defaultTimeoutHeight = 5
defaultEventTimeout = 1 * time.Minute
defaultTimeout = 1 * time.Minute
defaultResolveDuration = 2 * time.Second
defaultRetries = 1
defaultTickEventType = "ojo.oracle.v1.EventSetFxRate"
)

Expand All @@ -28,17 +29,22 @@ var (
type (
// Config defines all necessary cw-relayer configuration parameters.
Config struct {
Account Account `mapstructure:"account" validate:"required,gt=0,dive,required"`
Keyring Keyring `mapstructure:"keyring" validate:"required,gt=0,dive,required"`
RPC RPC `mapstructure:"rpc" validate:"required,gt=0,dive,required"`
Account Account `mapstructure:"account" validate:"required,gt=0,dive,required"`
Keyring Keyring `mapstructure:"keyring" validate:"required,gt=0,dive,required"`
RPC RPC `mapstructure:"rpc" validate:"required,gt=0,dive,required"`
Restart RestartConfig `mapstructure:"restart" validate:"required"`

ProviderTimeout string `mapstructure:"provider_timeout"`
ContractAddress string `mapstructure:"contract_address"`
TimeoutHeight int64 `mapsturture:"timeout_height"`
EventTimeout string `mapstrucutre:"event_timeout"`
TimeoutHeight int64 `mapstructure:"timeout_height"`
EventTimeout string `mapstructure:"event_timeout"`
MaxTickTimeout string `mapstructure:"max_tick_timeout"`
QueryTimeout string `mapstructure:"query_timeout"`
MaxRetries int64 `mapstructure:"max_retries"`

MedianRequestID uint64 `mapstructure:"median_request_id"`
RequestID uint64 `mapstructure:"request_id"`
MedianRequestID uint64 `mapstructure:"median_request_id"`
RequestID uint64 `mapstructure:"request_id"`
DeviationRequestID uint64 `mapstructure:"deviation_request_id"`

// force relay prices and reset epoch time in contracts if err in broadcasting tx
MissedThreshold int64 `mapstructure:"missed_threshold"`
Expand All @@ -49,9 +55,9 @@ type (
GasPrices string `mapstructure:"gas_prices" validate:"required"`

// query rpc for ojo node
QueryRPC string `mapstructure:"query_rpc"`
EventRPC string `mapstructure:"event_rpc"`
TickEventType string `mapstructure:"event_type"`
QueryRPCS []string `mapstructure:"query_rpcs" validate:"required"`
EventRPCS []string `mapstructure:"event_rpcs" validate:"required"`
TickEventType string `mapstructure:"event_type"`
}

// Account defines account related configuration that is related to the Client
Expand All @@ -68,10 +74,17 @@ type (
Dir string `mapstructure:"dir" validate:"required"`
}

RestartConfig struct {
AutoID bool `mapstructure:"auto_id"`
Denom string `mapstructure:"denom"`
SkipError bool `mapstructure:"skip_error"`
}

// RPC defines RPC configuration of both the wasmd chain and Tendermint nodes.
RPC struct {
TMRPCEndpoint string `mapstructure:"tmrpc_endpoint" validate:"required"`
RPCTimeout string `mapstructure:"rpc_timeout" validate:"required"`
QueryEndpoint string `mapstructure:"query_endpoint" validate:"required"`
}
)

Expand Down Expand Up @@ -104,8 +117,8 @@ func ParseConfig(configPath string) (Config, error) {
cfg.ProviderTimeout = defaultProviderTimeout.String()
}

if len(cfg.QueryRPC) == 0 {
cfg.QueryRPC = defaultQueryRPC
if len(cfg.QueryRPCS) == 0 {
cfg.QueryRPCS = []string{defaultQueryRPC}
}

if len(cfg.ContractAddress) == 0 {
Expand All @@ -117,7 +130,15 @@ func ParseConfig(configPath string) (Config, error) {
}

if len(cfg.EventTimeout) == 0 {
cfg.EventTimeout = defaultEventTimeout.String()
cfg.EventTimeout = defaultTimeout.String()
}

if len(cfg.MaxTickTimeout) == 0 {
cfg.MaxTickTimeout = defaultTimeout.String()
}

if len(cfg.QueryTimeout) == 0 {
cfg.QueryTimeout = defaultTimeout.String()
}

if len(cfg.ResolveDuration) == 0 {
Expand All @@ -128,5 +149,9 @@ func ParseConfig(configPath string) (Config, error) {
cfg.TickEventType = defaultTickEventType
}

if cfg.MaxRetries == 0 {
cfg.MaxRetries = defaultRetries
}

return cfg, cfg.Validate()
}
3 changes: 3 additions & 0 deletions cw-relayer/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func TestParseConfig_Valid(t *testing.T) {
gas_adjustment = 1.5
contract_address = "wasm14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9s0phg4d"
gas_prices = "0.00025stake"
query_rpcs = ["http://localhost:26657"]
event_rpcs = ["http://localhost:26657"]

[account]
address = "wasm15nejfgcaanqpw25ru4arvfd0fwy6j8clccvwx4"
Expand All @@ -69,6 +71,7 @@ dir = "/Users/username/.wasm"

[rpc]
tmrpc_endpoint = "http://localhost:26657"
query_endpoint = "localhost:9090"
rpc_timeout = "100ms"
`)
_, err = tmpFile.Write(content)
Expand Down
28 changes: 14 additions & 14 deletions cw-relayer/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ require (
require (
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
4d63.com/gochecknoglobals v0.2.1 // indirect
cloud.google.com/go v0.107.0 // indirect
cloud.google.com/go/compute v1.15.1 // indirect
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/compute v1.18.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.8.0 // indirect
cloud.google.com/go/storage v1.27.0 // indirect
cloud.google.com/go/iam v0.12.0 // indirect
cloud.google.com/go/storage v1.28.1 // indirect
cosmossdk.io/errors v1.0.0-beta.7 // indirect
cosmossdk.io/math v1.0.0-beta.6 // indirect
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
Expand Down Expand Up @@ -126,7 +126,7 @@ require (
github.com/gogo/protobuf v1.3.3 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
Expand All @@ -143,7 +143,7 @@ require (
github.com/google/orderedcode v0.0.1 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.1 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
Expand Down Expand Up @@ -294,17 +294,17 @@ require (
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.6.0 // indirect
golang.org/x/oauth2 v0.4.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.107.0 // indirect
google.golang.org/api v0.110.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
honnef.co/go/tools v0.4.2 // indirect
Expand Down
Loading