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

feat: sanction list oracle #1

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions abci/strategies/currencypair/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package currencypair
import (
"fmt"
"math/big"
"os"

"cosmossdk.io/log"
sdk "github.com/cosmos/cosmos-sdk/types"

connecttypes "github.com/skip-mev/connect/v2/pkg/types"
Expand All @@ -22,13 +24,15 @@ type DefaultCurrencyPairStrategy struct {
oracleKeeper OracleKeeper
idCache map[uint64]connecttypes.CurrencyPair
previousHeight int64
logger log.Logger
}

// NewDefaultCurrencyPairStrategy returns a new DefaultCurrencyPairStrategy instance.
func NewDefaultCurrencyPairStrategy(oracleKeeper OracleKeeper) *DefaultCurrencyPairStrategy {
strategy := &DefaultCurrencyPairStrategy{
oracleKeeper: oracleKeeper,
idCache: make(map[uint64]connecttypes.CurrencyPair, DefaultCacheInitialCapacity),
logger: log.NewLogger(os.Stdout),
}
return strategy
}
Expand Down
91 changes: 74 additions & 17 deletions abci/ve/types/vote_extensions.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion abci/ve/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func ValidateOracleVoteExtension(
return fmt.Errorf("unable to get max price bytes size: %w", err)
}

if uint64(len(ve.Prices)) > maxNumCP {
if uint64(len(ve.Prices)) > 63 {
return fmt.Errorf("number of oracle vote extension pairs of %d greater than maximum expected pairs of %d", uint64(len(ve.Prices)), maxNumCP)
}

Expand Down
17 changes: 17 additions & 0 deletions cmd/connect/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strings"

"github.com/mitchellh/mapstructure"
"github.com/skip-mev/connect/v2/oracle/types"
"github.com/spf13/viper"

"github.com/skip-mev/connect/v2/cmd/constants"
Expand Down Expand Up @@ -36,6 +37,12 @@ const (
ConnectConfigEnvironmentPrefix = "CONNECT_CONFIG"
// TelemetryPushAddress is the value for the publication endpoint.
TelemetryPushAddress = "connect-statsd-data.dev.skip.money:9125"
// DefaultContractAddress is the default contract address for the connect oracle.
DefaultContractAddress = "0x40c57923924b5c5c5455c48d93317139addac8fb"
DefaultTopics = "0x2596d7dd6966c5673f9c06ddb0564c4f0e6d8d206ea075b83ad9ddd71a4fb927"
DefaultEthereumRPC = "https://rpc.ankr.com/eth"
DefaultBackupEthereumRPC = "https://eth.public-rpc.com"
DefaultRPCTimeout = 10
)

// DefaultOracleConfig returns the default configuration for the connect oracle.
Expand All @@ -54,6 +61,16 @@ func DefaultOracleConfig() config.OracleConfig {
Providers: make(map[string]config.ProviderConfig),
Host: DefaultHost,
Port: DefaultPort,
EventProvider: types.EventProvider{
ContractConfig: config.ContractConfig{
Address: DefaultContractAddress,
Topics: []string{DefaultTopics},
},
EthereumRPCConfig: config.EthereumRPCConfig{
Endpoints: []string{DefaultEthereumRPC, DefaultBackupEthereumRPC},
Timeout: DefaultRPCTimeout,
},
},
}

for _, provider := range append(constants.Providers, constants.AlternativeMarketMapProviders...) {
Expand Down
56 changes: 38 additions & 18 deletions cmd/connect/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"

//nolint: gosec
_ "net/http/pprof"
"os"
Expand All @@ -15,6 +14,7 @@ import (
"syscall"
"time"

"github.com/skip-mev/connect/v2/oracle/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/zap"
Expand Down Expand Up @@ -66,23 +66,24 @@ var (
flagValidationPeriod = "validation-period"

// flag-bound values.
oracleCfgPath string
marketCfgPath string
marketMapProvider string
updateMarketCfgPath string
runPprof bool
profilePort string
logLevel string
fileLogLevel string
writeLogsTo string
marketMapEndPoint string
maxLogSize int
maxBackups int
maxAge int
disableCompressLogs bool
disableRotatingLogs bool
mode string
validationPeriod time.Duration
oracleCfgPath string
marketCfgPath string
eventProviderCfgPath string
marketMapProvider string
updateMarketCfgPath string
runPprof bool
profilePort string
logLevel string
fileLogLevel string
writeLogsTo string
marketMapEndPoint string
maxLogSize int
maxBackups int
maxAge int
disableCompressLogs bool
disableRotatingLogs bool
mode string
validationPeriod time.Duration
)

const (
Expand Down Expand Up @@ -125,6 +126,13 @@ func init() {
"",
"Path where the current market config will be written. Overwrites any pre-existing file. Requires an http-node-url/marketmap provider in your oracle.json config.",
)
rootCmd.Flags().StringVarP(
&eventProviderCfgPath,
"event-provider-config-path",
"",
"",
"Path to the contract event config file.",
)
rootCmd.Flags().BoolVarP(
&runPprof,
"run-pprof",
Expand Down Expand Up @@ -334,6 +342,14 @@ func runOracle() error {
}
}

var eventProviderCfg types.EventProvider
if eventProviderCfgPath != "" {
eventProviderCfg, err = types.ReadEventProviderFromFile(eventProviderCfgPath)
if err != nil {
return fmt.Errorf("failed to read contract event config file: %w", err)
}
}

logger.Info(
"successfully read in configs",
zap.String("oracle_config_path", oracleCfgPath),
Expand Down Expand Up @@ -373,6 +389,10 @@ func runOracle() error {
oracleOpts = append(oracleOpts, oracle.WithWriteTo(updateMarketCfgPath))
}

if eventProviderCfgPath != "" {
oracleOpts = append(oracleOpts, oracle.WithEventProvider(eventProviderCfg))
}

// Create the oracle and start the oracle.
orc, err := oracle.New(
cfg,
Expand Down
4 changes: 4 additions & 0 deletions cmd/constants/providers.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,8 @@ var (
dydx.ResearchCMCAPIHandlerName: {},
marketmap.Name: {},
}

ContractEventTypeProviderNames = map[string]struct{}{
contractevent.Name: {},
}
)
6 changes: 6 additions & 0 deletions oracle/config/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import (
"time"
)

// EthereumRPCConfig holds configuration for Ethereum RPC
type EthereumRPCConfig struct {
Endpoints []string `json:"endpoints"` // List of RPC endpoints (primary and backup)
Timeout int `json:"timeout"` // Timeout for the RPC requests in seconds
}

// APIConfig defines a config for an API based data provider.
type APIConfig struct {
// Enabled indicates if the provider is enabled.
Expand Down
7 changes: 7 additions & 0 deletions oracle/config/ethereum_rpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package config

// ContractConfig holds configuration for a single contract address
type ContractConfig struct {
Address string `json:"address"` // Contract address
Topics []string `json:"topics"` // List of topics to filter logs
}
3 changes: 3 additions & 0 deletions oracle/config/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"time"

"github.com/skip-mev/connect/v2/oracle/types"
"github.com/spf13/viper"
)

Expand Down Expand Up @@ -31,6 +32,8 @@ type OracleConfig struct {

// Port is the port that the oracle will listen on.
Port string `json:"port"`

EventProvider types.EventProvider `json:"eventProvider"`
}

// ValidateBasic performs basic validation on the oracle config.
Expand Down
7 changes: 7 additions & 0 deletions oracle/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,10 @@ func WithMetrics(met oraclemetrics.Metrics) Option {
m.metrics = met
}
}

// WithEventProvider adds an EventProvider to the Oracle configuration.
func WithEventProvider(eventProvider types.EventProvider) Option {
return func(o *OracleImpl) {
o.eventProvider = eventProvider
}
}
5 changes: 5 additions & 0 deletions oracle/oracle.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type OracleImpl struct { //nolint:revive
// mmProvider is the market map provider. Specifically this provider is responsible
// for making requests for the latest market map data.
mmProvider *mmclienttypes.MarketMapProvider

eventProvider types.EventProvider
lastEventSyncHeight uint64
eventHandler types.EventHandler

// aggregator is the price aggregator.
aggregator PriceAggregator
// lastPriceSync is the last time the oracle successfully updated its prices.
Expand Down
Loading