diff --git a/protocol/Dockerfile b/protocol/Dockerfile index e72464440c..5989fa37f2 100644 --- a/protocol/Dockerfile +++ b/protocol/Dockerfile @@ -1,6 +1,6 @@ # NB: This is a digest for a multi-arch manifest list, you will want to get this by running # `docker buildx imagetools inspect golang:1.21-alpine` -ARG GOLANG_1_21_ALPINE_DIGEST="926f7f7e1ab8509b4e91d5ec6d5916ebb45155b0c8920291ba9f361d65385806" +ARG GOLANG_1_22_ALPINE_DIGEST="8e96e6cff6a388c2f70f5f662b64120941fcd7d4b89d62fec87520323a316bd9" # This Dockerfile is a stateless build of the `dydxprotocold` binary as a Docker container. # It does not include any configuration, state, or genesis information. @@ -9,7 +9,7 @@ ARG GOLANG_1_21_ALPINE_DIGEST="926f7f7e1ab8509b4e91d5ec6d5916ebb45155b0c8920291b # Builder # -------------------------------------------------------- -FROM golang@sha256:${GOLANG_1_21_ALPINE_DIGEST} as builder +FROM golang@sha256:${GOLANG_1_22_ALPINE_DIGEST} as builder ARG VERSION ARG COMMIT @@ -41,15 +41,24 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ -o /dydxprotocol/build/ \ ./... +# Build the oracle binary +WORKDIR / +RUN git clone https://github.com/skip-mev/slinky.git +WORKDIR /slinky +RUN make build + # -------------------------------------------------------- # Runner # -------------------------------------------------------- -FROM golang@sha256:${GOLANG_1_21_ALPINE_DIGEST} +FROM golang@sha256:${GOLANG_1_22_ALPINE_DIGEST} RUN apk add --no-cache bash COPY --from=builder /dydxprotocol/build/dydxprotocold /bin/dydxprotocold +COPY --from=builder /slinky/build/oracle /bin/slinky +COPY --from=builder /slinky/config/local/oracle.json /etc/oracle.json +COPY --from=builder /slinky/config/local/market.json /etc/market.json ENV HOME /dydxprotocol WORKDIR $HOME diff --git a/protocol/app/app.go b/protocol/app/app.go index 1527c783fe..c2a926017b 100644 --- a/protocol/app/app.go +++ b/protocol/app/app.go @@ -123,6 +123,7 @@ import ( bridgedaemontypes "github.com/dydxprotocol/v4-chain/protocol/daemons/server/types/bridge" liquidationtypes "github.com/dydxprotocol/v4-chain/protocol/daemons/server/types/liquidations" pricefeedtypes "github.com/dydxprotocol/v4-chain/protocol/daemons/server/types/pricefeed" + slinkyclient "github.com/dydxprotocol/v4-chain/protocol/daemons/slinky/client" daemontypes "github.com/dydxprotocol/v4-chain/protocol/daemons/types" // Modules @@ -198,6 +199,11 @@ import ( "github.com/dydxprotocol/v4-chain/protocol/indexer" "github.com/dydxprotocol/v4-chain/protocol/indexer/indexer_manager" "github.com/dydxprotocol/v4-chain/protocol/indexer/msgsender" + + // Slinky + oracleconfig "github.com/skip-mev/slinky/oracle/config" + oracleclient "github.com/skip-mev/slinky/service/clients/oracle" + servicemetrics "github.com/skip-mev/slinky/service/metrics" ) var ( @@ -312,6 +318,9 @@ type App struct { BridgeClient *bridgeclient.Client DaemonHealthMonitor *daemonservertypes.HealthMonitor + + // Slinky + SlinkyClient *slinkyclient.Client } // assertAppPreconditions assert invariants required for an application to start. @@ -420,6 +429,9 @@ func New( if app.Server != nil { app.Server.Stop() } + if app.SlinkyClient != nil { + app.SlinkyClient.Stop() + } return nil }, ) @@ -751,25 +763,38 @@ func New( }() } - // Non-validating full-nodes have no need to run the price daemon. - if !appFlags.NonValidatingFullNode && daemonFlags.Price.Enabled { - exchangeQueryConfig := configs.ReadExchangeQueryConfigFile(homePath) - // Start pricefeed client for sending prices for the pricefeed server to consume. These prices - // are retrieved via third-party APIs like Binance and then are encoded in-memory and - // periodically sent via gRPC to a shared socket with the server. - app.PriceFeedClient = pricefeedclient.StartNewClient( - // The client will use `context.Background` so that it can have a different context from - // the main application. - context.Background(), - daemonFlags, - appFlags, - logger, - &daemontypes.GrpcClientImpl{}, - exchangeQueryConfig, - constants.StaticExchangeDetails, - &pricefeedclient.SubTaskRunnerImpl{}, - ) - app.RegisterDaemonWithHealthMonitor(app.PriceFeedClient, maxDaemonUnhealthyDuration) + // Non-validating full-nodes have no need to run the oracle. + if !appFlags.NonValidatingFullNode { + if daemonFlags.Price.Enabled { + exchangeQueryConfig := configs.ReadExchangeQueryConfigFile(homePath) + // Start pricefeed client for sending prices for the pricefeed server to consume. These prices + // are retrieved via third-party APIs like Binance and then are encoded in-memory and + // periodically sent via gRPC to a shared socket with the server. + app.PriceFeedClient = pricefeedclient.StartNewClient( + // The client will use `context.Background` so that it can have a different context from + // the main application. + context.Background(), + daemonFlags, + appFlags, + logger, + &daemontypes.GrpcClientImpl{}, + exchangeQueryConfig, + constants.StaticExchangeDetails, + &pricefeedclient.SubTaskRunnerImpl{}, + ) + app.RegisterDaemonWithHealthMonitor(app.PriceFeedClient, maxDaemonUnhealthyDuration) + } + if daemonFlags.Slinky.Enabled { + app.SlinkyClient = slinkyclient.StartNewClient( + context.Background(), + app.initSlinkySidecarClient(appOpts), + &daemontypes.GrpcClientImpl{}, + daemonFlags, + appFlags, + logger, + ) + } + } // Start Bridge Daemon. @@ -1387,6 +1412,28 @@ func New( return app } +func (app *App) initSlinkySidecarClient(appOpts servertypes.AppOptions) oracleclient.OracleClient { + // Slinky setup + cfg, err := oracleconfig.ReadConfigFromAppOpts(appOpts) + if err != nil { + panic(err) + } + oracleMetrics, err := servicemetrics.NewMetricsFromConfig(cfg, app.ChainID()) + if err != nil { + panic(err) + } + // Create the oracle service. + slinkyClient, err := oracleclient.NewClientFromConfig( + cfg, + app.Logger().With("client", "oracle"), + oracleMetrics, + ) + if err != nil { + panic(err) + } + return slinkyClient +} + // RegisterDaemonWithHealthMonitor registers a daemon service with the update monitor, which will commence monitoring // the health of the daemon. If the daemon does not register, the method will panic. func (app *App) RegisterDaemonWithHealthMonitor( diff --git a/protocol/cmd/dydxprotocold/cmd/config.go b/protocol/cmd/dydxprotocold/cmd/config.go index edd45e52b0..173c8e3995 100644 --- a/protocol/cmd/dydxprotocold/cmd/config.go +++ b/protocol/cmd/dydxprotocold/cmd/config.go @@ -7,6 +7,7 @@ import ( serverconfig "github.com/cosmos/cosmos-sdk/server/config" assettypes "github.com/dydxprotocol/v4-chain/protocol/x/assets/types" clobtypes "github.com/dydxprotocol/v4-chain/protocol/x/clob/types" + oracleconfig "github.com/skip-mev/slinky/oracle/config" ) const ( @@ -25,6 +26,7 @@ const ( // DydxAppConfig specifies dYdX app specific config. type DydxAppConfig struct { serverconfig.Config + Oracle oracleconfig.AppConfig `mapstructure:"oracle"` } // TODO(DEC-1718): Audit tendermint and app config parameters for mainnet. @@ -52,6 +54,13 @@ func initAppConfig() (string, *DydxAppConfig) { appConfig := DydxAppConfig{ Config: *srvCfg, + Oracle: oracleconfig.AppConfig{ + Enabled: true, + OracleAddress: "localhost:8080", + ClientTimeout: time.Second * 2, + MetricsEnabled: false, + PrometheusServerAddress: "", + }, } // Enable telemetry. @@ -65,7 +74,7 @@ func initAppConfig() (string, *DydxAppConfig) { // GRPC. appConfig.GRPC.Address = "0.0.0.0:9090" - appTemplate := serverconfig.DefaultConfigTemplate + appTemplate := serverconfig.DefaultConfigTemplate + oracleconfig.DefaultConfigTemplate return appTemplate, &appConfig } diff --git a/protocol/daemons/flags/flags.go b/protocol/daemons/flags/flags.go index 3bae6c44e6..4f06ab7e43 100644 --- a/protocol/daemons/flags/flags.go +++ b/protocol/daemons/flags/flags.go @@ -23,6 +23,8 @@ const ( FlagLiquidationDaemonEnabled = "liquidation-daemon-enabled" FlagLiquidationDaemonLoopDelayMs = "liquidation-daemon-loop-delay-ms" FlagLiquidationDaemonQueryPageLimit = "liquidation-daemon-query-page-limit" + + FlagSlinkyDaemonEnabled = "slinky-daemon-enabled" ) // Shared flags contains configuration flags shared by all daemons. @@ -63,12 +65,18 @@ type PriceFlags struct { LoopDelayMs uint32 } +type SlinkyFlags struct { + // Enabled toggles the slinky daemon on or off. + Enabled bool +} + // DaemonFlags contains the collected configuration flags for all daemons. type DaemonFlags struct { Shared SharedFlags Bridge BridgeFlags Liquidation LiquidationFlags Price PriceFlags + Slinky SlinkyFlags } var defaultDaemonFlags *DaemonFlags @@ -96,6 +104,9 @@ func GetDefaultDaemonFlags() DaemonFlags { Enabled: true, LoopDelayMs: 3_000, }, + Slinky: SlinkyFlags{ + Enabled: false, + }, } } return *defaultDaemonFlags @@ -173,6 +184,13 @@ func AddDaemonFlagsToCmd( df.Price.LoopDelayMs, "Delay in milliseconds between sending price updates to the application.", ) + + // Slinky Daemon. + cmd.Flags().Bool( + FlagSlinkyDaemonEnabled, + df.Slinky.Enabled, + "Enable Slinky Daemon. Set to false for non-validator nodes.", + ) } // GetDaemonFlagValuesFromOptions gets all daemon flag values from the `AppOptions` struct. @@ -245,5 +263,12 @@ func GetDaemonFlagValuesFromOptions( } } + // Slinky Daemon. + if option := appOpts.Get(FlagSlinkyDaemonEnabled); option != nil { + if v, err := cast.ToBoolE(option); err == nil { + result.Slinky.Enabled = v + } + } + return result } diff --git a/protocol/daemons/slinky/client/client.go b/protocol/daemons/slinky/client/client.go new file mode 100644 index 0000000000..9376072202 --- /dev/null +++ b/protocol/daemons/slinky/client/client.go @@ -0,0 +1,158 @@ +package client + +import ( + "context" + "cosmossdk.io/errors" + "sync" + "time" + + "cosmossdk.io/log" + + oracleclient "github.com/skip-mev/slinky/service/clients/oracle" + + appflags "github.com/dydxprotocol/v4-chain/protocol/app/flags" + "github.com/dydxprotocol/v4-chain/protocol/daemons/flags" + daemontypes "github.com/dydxprotocol/v4-chain/protocol/daemons/types" + libtime "github.com/dydxprotocol/v4-chain/protocol/lib/time" +) + +// Ensure Client is HealthCheckable +var _ daemontypes.HealthCheckable = (*Client)(nil) + +// Client is the daemon implementation for pulling price data from the slinky sidecar. +type Client struct { + daemontypes.HealthCheckable + ctx context.Context + cf context.CancelFunc + marketPairFetcher *MarketPairFetcher + priceFetcher *PriceFetcher + wg sync.WaitGroup + logger log.Logger +} + +func newClient(ctx context.Context, logger log.Logger) *Client { + logger = logger.With(log.ModuleKey, SlinkyClientDaemonModuleName) + client := &Client{ + HealthCheckable: daemontypes.NewTimeBoundedHealthCheckable( + SlinkyClientDaemonModuleName, + &libtime.TimeProviderImpl{}, + logger, + ), + logger: logger, + } + client.ctx, client.cf = context.WithCancel(ctx) + return client +} + +// start creates the main goroutines of the Client. +func (c *Client) start( + slinky oracleclient.OracleClient, + grpcClient daemontypes.GrpcClient, + daemonFlags flags.DaemonFlags, + appFlags appflags.Flags, +) error { + // 1. Start the MarketPairFetcher + c.marketPairFetcher = NewMarketPairFetcher(c.logger) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + c.RunMarketPairFetcher(c.ctx, appFlags, grpcClient) + }() + // 2. Start the PriceFetcher + c.priceFetcher = NewPriceFetcher( + c.marketPairFetcher, + grpcClient, + daemonFlags.Shared.SocketAddress, + slinky, + c.logger, + ) + wg.Add(1) + go func() { + defer wg.Done() + c.RunPriceFetcher(c.ctx) + }() + return nil +} + +// RunPriceFetcher periodically calls the priceFetcher to grab prices from the slinky sidecar and +// push them to the pricefeed server. +func (c *Client) RunPriceFetcher(ctx context.Context) { + err := c.priceFetcher.Start(ctx) + if err != nil { + c.logger.Error("Error initializing PriceFetcher in slinky daemon: %w", err) + panic(err) + } + ticker := time.NewTicker(SlinkyPriceFetchDelay) + defer ticker.Stop() + for { + select { + case <-ticker.C: + err := c.priceFetcher.FetchPrices(ctx) + if err != nil { + c.logger.Error("Failed to run fetch prices for slinky daemon", "error", err) + c.ReportFailure(errors.Wrap(err, "failed to run PriceFetcher for slinky daemon")) + } else { + c.ReportSuccess() + } + case <-ctx.Done(): + return + } + } +} + +// Stop closes all connections and waits for goroutines to exit. +func (c *Client) Stop() { + c.cf() + c.priceFetcher.Stop() + c.marketPairFetcher.Stop() + c.wg.Wait() +} + +// RunMarketPairFetcher periodically calls the marketPairFetcher to cache mappings between +// currency pair and market param ID. +func (c *Client) RunMarketPairFetcher(ctx context.Context, appFlags appflags.Flags, grpcClient daemontypes.GrpcClient) { + err := c.marketPairFetcher.Start(ctx, appFlags, grpcClient) + if err != nil { + c.logger.Error("Error initializing MarketPairFetcher in slinky daemon: %w", err) + panic(err) + } + ticker := time.NewTicker(SlinkyMarketParamFetchDelay) + defer ticker.Stop() + for { + select { + case <-ticker.C: + err := c.marketPairFetcher.FetchIdMappings(ctx) + if err != nil { + c.logger.Error("Failed to run fetch id mappings for slinky daemon", "error", err) + c.ReportFailure(errors.Wrap(err, "failed to run FetchIdMappings for slinky daemon")) + } + c.ReportSuccess() + case <-ctx.Done(): + return + } + } +} + +// StartNewClient creates and runs a Client. +func StartNewClient( + ctx context.Context, + slinky oracleclient.OracleClient, + grpcClient daemontypes.GrpcClient, + daemonFlags flags.DaemonFlags, + appFlags appflags.Flags, + logger log.Logger, +) *Client { + logger.Info( + "Starting slinky daemon with flags", + "SlinkyFlags", daemonFlags.Slinky, + ) + + client := newClient(ctx, logger) + err := client.start(slinky, grpcClient, daemonFlags, appFlags) + if err != nil { + logger.Error("Error initializing slinky daemon: %w", err) + panic(err) + } + return client +} diff --git a/protocol/daemons/slinky/client/constants.go b/protocol/daemons/slinky/client/constants.go new file mode 100644 index 0000000000..347183a8d7 --- /dev/null +++ b/protocol/daemons/slinky/client/constants.go @@ -0,0 +1,18 @@ +package client + +import "time" + +var ( + // SlinkyPriceServerConnectionTimeout controls the timeout of establishing a grpc connection to the pricefeed server. + SlinkyPriceServerConnectionTimeout = time.Second * 5 + // SlinkyPriceFetchDelay controls the frequency at which we pull prices from slinky and push them to the pricefeed server. + SlinkyPriceFetchDelay = time.Second * 2 + // SlinkyMarketParamFetchDelay is the frequency at which we query the x/price module to refresh mappings from + // currency pair to x/price ID. + SlinkyMarketParamFetchDelay = time.Millisecond * 1900 +) + +const ( + // SlinkyClientDaemonModuleName is the module name used in logging. + SlinkyClientDaemonModuleName = "slinky-client-daemon" +) diff --git a/protocol/daemons/slinky/client/market_pair_fetcher.go b/protocol/daemons/slinky/client/market_pair_fetcher.go new file mode 100644 index 0000000000..51c65b0272 --- /dev/null +++ b/protocol/daemons/slinky/client/market_pair_fetcher.go @@ -0,0 +1,100 @@ +package client + +import ( + "context" + "cosmossdk.io/log" + "fmt" + appflags "github.com/dydxprotocol/v4-chain/protocol/app/flags" + daemontypes "github.com/dydxprotocol/v4-chain/protocol/daemons/types" + "github.com/dydxprotocol/v4-chain/protocol/lib/slinky" + pricetypes "github.com/dydxprotocol/v4-chain/protocol/x/prices/types" + oracletypes "github.com/skip-mev/slinky/x/oracle/types" + "google.golang.org/grpc" + "sync" +) + +// MarketPairFetcher is a lightweight process run in a goroutine by the slinky client. +// Its purpose is to periodically query the prices module for MarketParams and create +// an easily indexed mapping between Slinky's CurrencyPair type and the corresponding ID +// in the x/prices module. +type MarketPairFetcher struct { + logger log.Logger + queryConn *grpc.ClientConn + pricesQueryClient pricetypes.QueryClient + + // compatMappings stores a mapping between CurrencyPair and the corresponding market(param|price) ID + compatMappings map[oracletypes.CurrencyPair]uint32 + compatMu sync.RWMutex +} + +func NewMarketPairFetcher(logger log.Logger) *MarketPairFetcher { + return &MarketPairFetcher{ + logger: logger, + compatMappings: make(map[oracletypes.CurrencyPair]uint32), + } +} + +// Start opens the grpc connections for the fetcher. +func (m *MarketPairFetcher) Start(ctx context.Context, appFlags appflags.Flags, grpcClient daemontypes.GrpcClient) error { + // Create the query client connection + queryConn, err := grpcClient.NewTcpConnection(ctx, appFlags.GrpcAddress) + if err != nil { + m.logger.Error( + "Failed to establish gRPC connection", + "gRPC address", appFlags.GrpcAddress, + "error", err, + ) + return err + } + m.pricesQueryClient = pricetypes.NewQueryClient(queryConn) + return nil +} + +// Stop closes all existing connections. +func (m *MarketPairFetcher) Stop() { + if m.queryConn != nil { + _ = m.queryConn.Close() + } + return +} + +// GetIDForPair returns the ID corresponding to the currency pair in the x/prices module. +// If the currency pair is not found it will return an error. +func (m *MarketPairFetcher) GetIDForPair(cp oracletypes.CurrencyPair) (uint32, error) { + var id uint32 + m.compatMu.RLock() + defer m.compatMu.RUnlock() + id, found := m.compatMappings[cp] + if !found { + return id, fmt.Errorf("pair %s not found in compatMappings", cp.String()) + } + return id, nil +} + +// FetchIdMappings is run periodically to refresh the cache of known mappings between +// CurrencyPair and MarketParam ID. +func (m *MarketPairFetcher) FetchIdMappings(ctx context.Context) error { + // fetch all market params + resp, err := m.pricesQueryClient.AllMarketParams(ctx, &pricetypes.QueryAllMarketParamsRequest{}) + if err != nil { + return err + } + // Exit early if there are no changes + // This assumes there will not be an addition and a removal of markets in the same block + if len(resp.MarketParams) == len(m.compatMappings) { + return nil + } + var compatMappings = make(map[oracletypes.CurrencyPair]uint32, len(resp.MarketParams)) + for _, mp := range resp.MarketParams { + cp, err := slinky.MarketPairToCurrencyPair(mp.Pair) + if err != nil { + return err + } + m.logger.Info("Mapped market to pair", "market id", mp.Id, "currency pair", cp.String()) + compatMappings[cp] = mp.Id + } + m.compatMu.Lock() + defer m.compatMu.Unlock() + m.compatMappings = compatMappings + return nil +} diff --git a/protocol/daemons/slinky/client/price_fetcher.go b/protocol/daemons/slinky/client/price_fetcher.go new file mode 100644 index 0000000000..ebe0b395e0 --- /dev/null +++ b/protocol/daemons/slinky/client/price_fetcher.go @@ -0,0 +1,133 @@ +package client + +import ( + "context" + "fmt" + "github.com/skip-mev/slinky/service/servers/oracle/types" + "strconv" + + "cosmossdk.io/log" + "google.golang.org/grpc" + + oracleclient "github.com/skip-mev/slinky/service/clients/oracle" + oracletypes "github.com/skip-mev/slinky/x/oracle/types" + + "github.com/dydxprotocol/v4-chain/protocol/daemons/pricefeed/api" + daemontypes "github.com/dydxprotocol/v4-chain/protocol/daemons/types" +) + +// PriceFetcher is responsible for pulling prices from the slinky sidecar and sending them to the pricefeed server. +type PriceFetcher struct { + marketPairFetcher *MarketPairFetcher + priceFeedServiceClient api.PriceFeedServiceClient + grpcClient daemontypes.GrpcClient + pricesSocket string + pricesConn *grpc.ClientConn + slinky oracleclient.OracleClient + logger log.Logger +} + +// NewPriceFetcher creates a PriceFetcher. +func NewPriceFetcher( + marketPairFetcher *MarketPairFetcher, + grpcClient daemontypes.GrpcClient, + pricesSocket string, + slinky oracleclient.OracleClient, + logger log.Logger) *PriceFetcher { + return &PriceFetcher{ + marketPairFetcher: marketPairFetcher, + grpcClient: grpcClient, + pricesSocket: pricesSocket, + slinky: slinky, + logger: logger, + } +} + +// Start initializes the underlying connections of the PriceFetcher. +func (p *PriceFetcher) Start(ctx context.Context) error { + cancelCtx, cf := context.WithTimeout(ctx, SlinkyPriceServerConnectionTimeout) + defer cf() + pricesConn, err := p.grpcClient.NewGrpcConnection(cancelCtx, p.pricesSocket) + if err != nil { + return err + } + p.pricesConn = pricesConn + p.priceFeedServiceClient = api.NewPriceFeedServiceClient(p.pricesConn) + return p.slinky.Start(ctx) +} + +// Stop closes all open connections. +func (p *PriceFetcher) Stop() { + if p.pricesConn != nil { + _ = p.grpcClient.CloseConnection(p.pricesConn) + } + _ = p.slinky.Stop() +} + +// FetchPrices pulls prices from Slinky, translates the returned data format to dydx-compatible types, +// and sends the price updates to the index price cache via the pricefeed server. +// It uses the MarketPairFetcher to efficiently map between Slinky's CurrencyPair primary key and dydx's +// MarketParam (or MarketPrice) ID. +// +// The markets in the index price cache will only have a single index price (from slinky). +// This is because the sidecar pre-aggregates market data. +func (p *PriceFetcher) FetchPrices(ctx context.Context) error { + // get prices from slinky sidecar via GRPC + slinkyResponse, err := p.slinky.Prices(ctx, &types.QueryPricesRequest{}) + if err != nil { + return err + } + + // update the prices keeper w/ the most recent prices for the relevant markets + var updates []*api.MarketPriceUpdate + for currencyPairString, priceString := range slinkyResponse.Prices { + // convert currency-pair string (index) into currency-pair object + currencyPair, err := oracletypes.CurrencyPairFromString(currencyPairString) + if err != nil { + return err + } + p.logger.Info("turned price pair to currency pair", "string", currencyPairString, "currency pair", currencyPair.String()) + + // get the market id for the currency pair + id, err := p.marketPairFetcher.GetIDForPair(currencyPair) + if err != nil { + p.logger.Info("slinky client returned currency pair not found in MarketPairFetcher", "currency pair", currencyPairString, "error", err) + continue + } + + // parse the price string into a uint64 + price, err := strconv.ParseUint(priceString, 10, 64) + if err != nil { + return fmt.Errorf("slinky client returned price %s not parsable as uint64", priceString) + } + p.logger.Info("parsed update for", "market id", id, "price", price) + + // append the update to the list of MarketPriceUpdates to be sent to the app's price-feed service + updates = append(updates, &api.MarketPriceUpdate{ + MarketId: id, + ExchangePrices: []*api.ExchangePrice{ + { + ExchangeId: "slinky", + Price: price, + LastUpdateTime: &slinkyResponse.Timestamp, + }, + }, + }) + } + + // send the updates to the app's price-feed service -> these will then be piped to the x/prices indexPriceCache via the price + // feed service + if p.priceFeedServiceClient == nil { + p.logger.Error("nil price feed service client") + } + if len(updates) == 0 { + p.logger.Info("Slinky returned 0 valid market price updates") + return nil + } + _, err = p.priceFeedServiceClient.UpdateMarketPrices(ctx, &api.UpdateMarketPricesRequest{MarketPriceUpdates: updates}) + if err != nil { + p.logger.Error(err.Error()) + return err + } + return nil +} diff --git a/protocol/docker-compose.yml b/protocol/docker-compose.yml index 04d3a2fb23..d5a2b384ff 100644 --- a/protocol/docker-compose.yml +++ b/protocol/docker-compose.yml @@ -112,6 +112,20 @@ services: - DAEMON_HOME=/dydxprotocol/chain/.dave volumes: - ./localnet/dydxprotocol3:/dydxprotocol/chain/.dave/data + slinky0: + image: local:dydxprotocol + entrypoint: + - slinky + - -oracle-config-path + - /etc/oracle.json + - -market-config-path + - /etc/market.json + - -host + - "0.0.0.0" + - -port + - "8080" + ports: + - "8080:8080" datadog-agent: image: public.ecr.aws/datadog/agent:7 diff --git a/protocol/go.mod b/protocol/go.mod index b74a78fdbd..9648182b84 100644 --- a/protocol/go.mod +++ b/protocol/go.mod @@ -1,6 +1,8 @@ module github.com/dydxprotocol/v4-chain/protocol -go 1.21 +go 1.22 + +toolchain go1.22.0 require ( cosmossdk.io/api v0.7.3 @@ -17,7 +19,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 - github.com/golangci/golangci-lint v1.55.1 + github.com/golangci/golangci-lint v1.55.2 github.com/google/go-cmp v0.6.0 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -29,11 +31,11 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 - github.com/vektra/mockery/v2 v2.23.1 + github.com/vektra/mockery/v2 v2.40.1 github.com/zyedidia/generic v1.0.0 golang.org/x/exp v0.0.0-20240213143201-ec583247a57a google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.61.0 gopkg.in/DataDog/dd-trace-go.v1 v1.48.0 gopkg.in/typ.v4 v4.1.0 ) @@ -44,12 +46,12 @@ require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.3.1 cosmossdk.io/store v1.0.2 - cosmossdk.io/tools/confix v0.1.0 + cosmossdk.io/tools/confix v0.1.1 cosmossdk.io/x/circuit v0.1.0 cosmossdk.io/x/evidence v0.1.0 cosmossdk.io/x/feegrant v0.1.0 cosmossdk.io/x/tx v0.13.0 - cosmossdk.io/x/upgrade v0.1.0 + cosmossdk.io/x/upgrade v0.1.1 github.com/burdiyan/kafkautil v0.0.0-20190131162249-eaf83ed22d5b github.com/cosmos/cosmos-db v1.0.0 github.com/cosmos/iavl v1.0.1 @@ -64,8 +66,9 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/rs/zerolog v1.32.0 github.com/shopspring/decimal v1.3.1 + github.com/skip-mev/slinky v0.2.2 github.com/spf13/viper v1.18.2 - google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f + google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 google.golang.org/protobuf v1.32.0 ) @@ -112,14 +115,14 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect - github.com/bits-and-blooms/bitset v1.8.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect github.com/bombsimon/wsl/v3 v3.4.0 // indirect github.com/breml/bidichk v0.2.7 // indirect github.com/breml/errchkjson v0.3.6 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/butuzov/ireturn v0.2.1 // indirect + github.com/butuzov/ireturn v0.2.2 // indirect github.com/butuzov/mirror v1.1.0 // indirect github.com/catenacyber/perfsprint v0.2.0 // indirect github.com/ccojocar/zxcvbn-go v1.0.1 // indirect @@ -129,7 +132,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/charithe/durationcheck v0.0.10 // indirect github.com/chavacava/garif v0.1.0 // indirect - github.com/chigopher/pathlib v0.12.0 // indirect + github.com/chigopher/pathlib v0.19.1 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect @@ -227,7 +230,7 @@ require ( github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -242,6 +245,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect github.com/huandu/skiplist v1.2.0 // indirect + github.com/huandu/xstrings v1.4.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect @@ -253,7 +257,7 @@ require ( github.com/jcmturner/rpc/v2 v2.0.3 // indirect github.com/jgautheron/goconst v1.6.0 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect - github.com/jinzhu/copier v0.3.5 // indirect + github.com/jinzhu/copier v0.4.0 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect @@ -284,7 +288,7 @@ require ( github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.10 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.3.4 // indirect github.com/minio/highwayhash v1.0.2 // indirect @@ -297,14 +301,14 @@ require ( github.com/nakabonne/nestif v0.3.1 // indirect github.com/nishanths/exhaustive v0.11.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.14.0 // indirect + github.com/nunnatsa/ginkgolinter v0.14.1 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/runc v1.1.5 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -344,7 +348,7 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect @@ -376,10 +380,8 @@ require ( go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect go.tmz.dev/musttag v0.7.2 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/goleak v1.1.12 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.24.0 // indirect + go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.19.0 // indirect golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect golang.org/x/mod v0.15.0 // indirect @@ -401,7 +403,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect honnef.co/go/tools v0.4.6 // indirect - mvdan.cc/gofumpt v0.5.0 // indirect + mvdan.cc/gofumpt v0.6.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect diff --git a/protocol/go.sum b/protocol/go.sum index 4a81428cfd..c539ef4081 100644 --- a/protocol/go.sum +++ b/protocol/go.sum @@ -204,8 +204,8 @@ cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= -cosmossdk.io/tools/confix v0.1.0 h1:2OOZTtQsDT5e7P3FM5xqM0bPfluAxZlAwxqaDmYBE+E= -cosmossdk.io/tools/confix v0.1.0/go.mod h1:TdXKVYs4gEayav5wM+JHT+kTU2J7fozFNqoVaN+8CdY= +cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= +cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= @@ -214,8 +214,8 @@ cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= -cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= -cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -288,12 +288,12 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= -github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/assert/v2 v2.5.0 h1:OJKYg53BQx06/bMRBSPDCO49CbCDNiUQXwdoNrt6x5w= +github.com/alecthomas/assert/v2 v2.5.0/go.mod h1:fw5suVxB+wfYJ3291t0hRTqtGzFYdSwstnRQdaQx2DM= github.com/alecthomas/go-check-sumtype v0.1.3 h1:M+tqMxB68hcgccRXBMVCPI4UJ+QUfdSx0xdbypKCqA8= github.com/alecthomas/go-check-sumtype v0.1.3/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= -github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= -github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8= +github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -325,7 +325,6 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -336,8 +335,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= -github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= @@ -358,8 +357,8 @@ github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28 github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= github.com/burdiyan/kafkautil v0.0.0-20190131162249-eaf83ed22d5b h1:gRFujk0F/KYFDEalhpaAbLIwmeiDH53ZgdllJ7UHxyQ= github.com/burdiyan/kafkautil v0.0.0-20190131162249-eaf83ed22d5b/go.mod h1:5hrpM9I1h0fZlTk8JhqaaBaCs76EbCGvFcPtm5SxcCU= -github.com/butuzov/ireturn v0.2.1 h1:w5Ks4tnfeFDZskGJ2x1GAkx5gaQV+kdU3NKNr3NEBzY= -github.com/butuzov/ireturn v0.2.1/go.mod h1:RfGHUvvAuFFxoHKf4Z8Yxuh6OjlCw1KvR2zM1NFHeBk= +github.com/butuzov/ireturn v0.2.2 h1:jWI36dxXwVrI+RnXDwux2IZOewpmfv930OuIRfaBUJ0= +github.com/butuzov/ireturn v0.2.2/go.mod h1:RfGHUvvAuFFxoHKf4Z8Yxuh6OjlCw1KvR2zM1NFHeBk= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= @@ -389,8 +388,8 @@ github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAc github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chigopher/pathlib v0.12.0 h1:1GM7fN/IwXXmOHbd1jkMqHD2wUhYqUvafgxTwmLT/q8= -github.com/chigopher/pathlib v0.12.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= +github.com/chigopher/pathlib v0.19.1 h1:RoLlUJc0CqBGwq239cilyhxPNLXTK+HXoASGyGznx5A= +github.com/chigopher/pathlib v0.19.1/go.mod h1:tzC1dZLW8o33UQpWkNkhvPwL5n4yyFRFm/jL1YGWFvY= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= @@ -737,8 +736,8 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g= github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= -github.com/golangci/golangci-lint v1.55.1 h1:DL2j9Eeapg1N3WEkKnQFX5L40SYtjZZJjGVdyEgNrDc= -github.com/golangci/golangci-lint v1.55.1/go.mod h1:z00biPRqjo5MISKV1+RWgONf2KvrPDmfqxHpHKB6bI4= +github.com/golangci/golangci-lint v1.55.2 h1:yllEIsSJ7MtlDBwDJ9IMBkyEUz2fYE0b5B8IUgO1oP8= +github.com/golangci/golangci-lint v1.55.2/go.mod h1:H60CZ0fuqoTwlTvnbyjhpZPWp7KmsjwV2yupIMiMXbM= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -882,8 +881,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -938,6 +937,8 @@ github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3 github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= @@ -973,8 +974,8 @@ github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFo github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= -github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= -github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -1021,7 +1022,6 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -1093,8 +1093,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= -github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= @@ -1151,8 +1151,8 @@ github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8p github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.14.0 h1:XQPNmw+kZz5cC/HbFK3mQutpjzAQv1dHregRA+4CGGg= -github.com/nunnatsa/ginkgolinter v0.14.0/go.mod h1:cm2xaqCUCRd7qcP4DqbVvpcyEMkuLM9CF0wY6VASohk= +github.com/nunnatsa/ginkgolinter v0.14.1 h1:khx0CqR5U4ghsscjJ+lZVthp3zjIFytRXPTaQ/TMiyA= +github.com/nunnatsa/ginkgolinter v0.14.1/go.mod h1:nY0pafUSst7v7F637e7fymaMlQqI9c0Wka2fGsDkzWg= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1215,8 +1215,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= @@ -1235,7 +1235,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1295,7 +1294,6 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 h1:Qp27Idfgi6ACvFQat5+VJvlYToylpM/hcyLBI3WaKPA= github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+uGV8BrTv8W/SIwk= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1361,6 +1359,8 @@ github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/skip-mev/slinky v0.2.2 h1:LlJDfmr45l3G+3GJhNRyWS72+FKAWjQxDfhZkzOC0/w= +github.com/skip-mev/slinky v0.2.2/go.mod h1:HBzskXU/8d7cNthgmksHp+KZHQ7vZbGazfsnT2SqQhI= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1375,7 +1375,6 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -1405,8 +1404,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= +github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1475,8 +1475,8 @@ github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bC github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= -github.com/vektra/mockery/v2 v2.23.1 h1:N59FENM2d/gWE6Ns5JPuf9a7jqQWeheGefZqvuvb1dM= -github.com/vektra/mockery/v2 v2.23.1/go.mod h1:Zh3Kv1ckKs6FokhlVLcCu6UTyzfS3M8mpROz1lBNp+w= +github.com/vektra/mockery/v2 v2.40.1 h1:8D01rBqloDLDHKZGXkyUD9Yj5Z+oDXBqDZ+tRXYM/oA= +github.com/vektra/mockery/v2 v2.40.1/go.mod h1:dPzGtjT0/Uu4hqpF6QNHwz+GLago7lq1bxdj9wHbGKo= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= @@ -1538,11 +1538,9 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1552,8 +1550,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 h1:FyBZqvoA/jbNzuAWLQE2kG820zMAkcilx6BMjGbL/E4= @@ -1567,7 +1565,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -2151,8 +2148,8 @@ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o= +google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2196,8 +2193,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2274,8 +2271,8 @@ honnef.co/go/tools v0.4.6 h1:oFEHCKeID7to/3autwsWfnuv69j3NsfcXbvJKuIcep8= honnef.co/go/tools v0.4.6/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= inet.af/netaddr v0.0.0-20220617031823-097006376321 h1:B4dC8ySKTQXasnjDTMsoCMf1sQG4WsMej0WXaHxunmU= inet.af/netaddr v0.0.0-20220617031823-097006376321/go.mod h1:OIezDfdzOgFhuw4HuWapWq2e9l0H9tK4F1j+ETRtF3k= -mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= -mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= +mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= +mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= diff --git a/protocol/lib/slinky/utils.go b/protocol/lib/slinky/utils.go new file mode 100644 index 0000000000..b86c60b0b2 --- /dev/null +++ b/protocol/lib/slinky/utils.go @@ -0,0 +1,28 @@ +package slinky + +import ( + "fmt" + "github.com/skip-mev/slinky/x/oracle/types" + "strings" +) + +/* + * Slinky utility functions + * + * This file contains functions for converting between x/prices types and slinky's x/oracle equivalents. + */ + +// MarketPairToCurrencyPair converts a base and quote pair from MarketPrice format (for example BTC-ETH) +// to a currency pair type. Returns an error if unable to convert. +func MarketPairToCurrencyPair(marketPair string) (types.CurrencyPair, error) { + split := strings.Split(marketPair, "-") + if len(split) != 2 { + return types.CurrencyPair{}, fmt.Errorf("incorrectly formatted CurrencyPair: %s", marketPair) + } + cp := types.CurrencyPair{ + Base: strings.ToUpper(split[0]), + Quote: strings.ToUpper(split[1]), + } + + return cp, cp.ValidateBasic() +} diff --git a/protocol/testing/genesis.sh b/protocol/testing/genesis.sh index a782047697..7911764acb 100755 --- a/protocol/testing/genesis.sh +++ b/protocol/testing/genesis.sh @@ -476,7 +476,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[0].pair' -v 'BTC-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[0].id' -v '0' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[0].exponent' -v '-5' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[0].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[0].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[0].min_price_change_ppm' -v '1000' # 0.1% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[0].id' -v '0' @@ -491,7 +491,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[1].pair' -v 'ETH-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[1].id' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[1].exponent' -v '-6' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[1].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[1].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[1].min_price_change_ppm' -v '1000' # 0.1% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[1].id' -v '1' @@ -506,7 +506,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[2].pair' -v 'LINK-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[2].id' -v '2' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[2].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[2].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[2].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[2].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[2].id' -v '2' @@ -521,7 +521,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[3].pair' -v 'MATIC-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[3].id' -v '3' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[3].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[3].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[3].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[3].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[3].id' -v '3' @@ -536,7 +536,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[4].pair' -v 'CRV-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[4].id' -v '4' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[4].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[4].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[4].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[4].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[4].id' -v '4' @@ -551,7 +551,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[5].pair' -v 'SOL-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[5].id' -v '5' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[5].exponent' -v '-8' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[5].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[5].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[5].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[5].id' -v '5' @@ -566,7 +566,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[6].pair' -v 'ADA-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[6].id' -v '6' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[6].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[6].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[6].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[6].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[6].id' -v '6' @@ -581,7 +581,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[7].pair' -v 'AVAX-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[7].id' -v '7' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[7].exponent' -v '-8' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[7].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[7].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[7].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[7].id' -v '7' @@ -596,7 +596,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[8].pair' -v 'FIL-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[8].id' -v '8' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[8].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[8].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[8].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[8].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[8].id' -v '8' @@ -611,7 +611,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[9].pair' -v 'LTC-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[9].id' -v '9' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[9].exponent' -v '-8' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[9].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[9].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[9].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[9].id' -v '9' @@ -626,7 +626,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[10].pair' -v 'DOGE-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[10].id' -v '10' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[10].exponent' -v '-11' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[10].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[10].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[10].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[10].id' -v '10' @@ -641,7 +641,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[11].pair' -v 'ATOM-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[11].id' -v '11' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[11].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[11].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[11].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[11].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[11].id' -v '11' @@ -656,7 +656,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[12].pair' -v 'DOT-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[12].id' -v '12' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[12].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[12].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[12].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[12].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[12].id' -v '12' @@ -671,7 +671,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[13].pair' -v 'UNI-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[13].id' -v '13' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[13].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[13].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[13].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[13].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[13].id' -v '13' @@ -686,7 +686,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[14].pair' -v 'BCH-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[14].id' -v '14' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[14].exponent' -v '-7' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[14].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[14].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[14].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[14].id' -v '14' @@ -701,7 +701,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[15].pair' -v 'TRX-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[15].id' -v '15' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[15].exponent' -v '-11' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[15].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[15].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[15].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[15].id' -v '15' @@ -716,7 +716,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[16].pair' -v 'NEAR-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[16].id' -v '16' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[16].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[16].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[16].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[16].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[16].id' -v '16' @@ -731,7 +731,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[17].pair' -v 'MKR-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[17].id' -v '17' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[17].exponent' -v '-6' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[17].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[17].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[17].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[17].id' -v '17' @@ -746,7 +746,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[18].pair' -v 'XLM-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[18].id' -v '18' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[18].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[18].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[18].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[18].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[18].id' -v '18' @@ -761,7 +761,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[19].pair' -v 'ETC-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[19].id' -v '19' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[19].exponent' -v '-8' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[19].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[19].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[19].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[19].id' -v '19' @@ -776,7 +776,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[20].pair' -v 'COMP-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[20].id' -v '20' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[20].exponent' -v '-8' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[20].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[20].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[20].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[20].id' -v '20' @@ -791,7 +791,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[21].pair' -v 'WLD-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[21].id' -v '21' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[21].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[21].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[21].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[21].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[21].id' -v '21' @@ -806,7 +806,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[22].pair' -v 'APE-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[22].id' -v '22' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[22].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[22].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[22].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[22].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[22].id' -v '22' @@ -821,7 +821,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[23].pair' -v 'APT-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[23].id' -v '23' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[23].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[23].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[23].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[23].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[23].id' -v '23' @@ -836,7 +836,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[24].pair' -v 'ARB-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[24].id' -v '24' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[24].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[24].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[24].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[24].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[24].id' -v '24' @@ -851,7 +851,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[25].pair' -v 'BLUR-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[25].id' -v '25' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[25].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[25].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[25].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[25].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[25].id' -v '25' @@ -866,7 +866,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[26].pair' -v 'LDO-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[26].id' -v '26' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[26].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[26].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[26].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[26].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[26].id' -v '26' @@ -881,7 +881,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[27].pair' -v 'OP-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[27].id' -v '27' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[27].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[27].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[27].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[27].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[27].id' -v '27' @@ -896,7 +896,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[28].pair' -v 'PEPE-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[28].id' -v '28' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[28].exponent' -v '-16' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[28].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[28].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[28].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[28].id' -v '28' @@ -911,7 +911,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[29].pair' -v 'SEI-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[29].id' -v '29' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[29].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[29].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[29].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[29].min_price_change_ppm' -v '4000' # 0.4% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[29].id' -v '29' @@ -926,7 +926,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[30].pair' -v 'SHIB-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[30].id' -v '30' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[30].exponent' -v '-15' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[30].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[30].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[30].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[30].id' -v '30' @@ -941,7 +941,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[31].pair' -v 'SUI-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[31].id' -v '31' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[31].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[31].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[31].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[31].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[31].id' -v '31' @@ -956,7 +956,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[32].pair' -v 'XRP-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[32].id' -v '32' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[32].exponent' -v '-10' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[32].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[32].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[32].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[32].id' -v '32' @@ -971,7 +971,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[33].pair' -v 'USDT-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[33].id' -v '1000000' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[33].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[33].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[33].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[33].min_price_change_ppm' -v '1000' # 0.100% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[33].id' -v '1000000' @@ -986,7 +986,7 @@ function edit_genesis() { dasel put -t string -f "$GENESIS" '.app_state.prices.market_params.[34].pair' -v 'DYDX-USD' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[34].id' -v '1000001' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[34].exponent' -v '-9' - dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[34].min_exchanges' -v '3' + dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[34].min_exchanges' -v '1' dasel put -t int -f "$GENESIS" '.app_state.prices.market_params.[34].min_price_change_ppm' -v '2500' # 0.25% dasel put -t json -f "$GENESIS" '.app_state.prices.market_prices.[]' -v "{}" dasel put -t int -f "$GENESIS" '.app_state.prices.market_prices.[34].id' -v '1000001' diff --git a/protocol/testing/testnet-local/local.sh b/protocol/testing/testnet-local/local.sh index edb7112c18..6898682118 100755 --- a/protocol/testing/testnet-local/local.sh +++ b/protocol/testing/testnet-local/local.sh @@ -95,6 +95,7 @@ create_validators() { cat <<<"$new_file" >"$VAL_CONFIG_DIR"/node_key.json edit_config "$VAL_CONFIG_DIR" + use_slinky "$VAL_CONFIG_DIR" # Using "*" as a subscript results in a single arg: "dydx1... dydx1... dydx1..." # Using "@" as a subscript results in separate args: "dydx1..." "dydx1..." "dydx1..." @@ -153,6 +154,15 @@ setup_cosmovisor() { done } +use_slinky() { + CONFIG_FOLDER=$1 + # Disable pricefeed-daemon + dasel put -t bool -f "$CONFIG_FOLDER"/app.toml 'price-daemon-enabled' -v false + # Enable slinky daemon + dasel put -t bool -f "$CONFIG_FOLDER"/app.toml 'slinky-daemon-enabled' -v true + dasel put -t string -f "$VAL_CONFIG_DIR"/app.toml '.oracle.oracle_address' -v 'slinky0:8080' +} + # TODO(DEC-1894): remove this function once we migrate off of persistent peers. # Note: DO NOT add more config modifications in this method. Use `cmd/config.go` to configure # the default config values.