Skip to content

Commit

Permalink
Merge branch 'main' into gateio_feeder
Browse files Browse the repository at this point in the history
  • Loading branch information
k-yang authored Feb 24, 2024
2 parents d9e8d3b + 80f4212 commit b469b66
Show file tree
Hide file tree
Showing 23 changed files with 1,485 additions and 461 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CHAIN_ID="nibiru-localnet-0"
GRPC_ENDPOINT="localhost:9090"
WEBSOCKET_ENDPOINT="ws://localhost:26657/websocket"
FEEDER_MNEMONIC="guard cream sadness conduct invite crumble clock pudding hole grit liar hotel maid produce squeeze return argue turtle know drive eight casino maze host"
EXCHANGE_SYMBOLS_MAP='{"bitfinex": {"ubtc:unusd": "tBTCUSD", "ueth:unusd": "tETHUSD", "uusd:unusd": "tUSTUSD"}}'
DATASOURCE_CONFIG_MAP='{"coingecko": {"api_key": "0123456789"}}'
VALIDATOR_ADDRESS="nibi1zaavvzxez0elundtn32qnk9lkm8kmcsz44g7xl"
14 changes: 14 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,17 @@ jobs:

- name: Run all tests.
run: make test

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.19
cache: true

- name: Run all tests.
run: make build
11 changes: 7 additions & 4 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ builds:
- id: darwin
main: ./cmd/feeder
binary: pricefeeder
hooks:
pre:
- wget https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0/libwasmvmstatic_darwin.a -O /osxcross/target/SDK/MacOSX12.0.sdk/usr/lib/libwasmvmstatic_darwin.a
goos:
- darwin
goarch:
Expand All @@ -18,7 +21,7 @@ builds:
- -mod=readonly
- -trimpath
ldflags:
- -s -w -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X github.com/cosmos/cosmos-sdk/version.Name=nibiru -X github.com/cosmos/cosmos-sdk/version.AppName=nibid -X github.com/cosmos/cosmos-sdk/version.Version={{ .Version }} -X github.com/cosmos/cosmos-sdk/version.Commit={{ .Commit }} -X github.com/tendermint/tendermint/version.TMCoreSemVer={{ .Env.TM_VERSION }}
- -s -w -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X github.com/cosmos/cosmos-sdk/version.Name=nibiru -X github.com/cosmos/cosmos-sdk/version.AppName=nibid -X github.com/cosmos/cosmos-sdk/version.Version={{ .Version }} -X github.com/cosmos/cosmos-sdk/version.Commit={{ .Commit }}
- -linkmode=external
tags:
- netgo
Expand All @@ -36,8 +39,8 @@ builds:
binary: pricefeeder
hooks:
pre:
- wget https://github.com/CosmWasm/wasmvm/releases/download/v1.1.1/libwasmvm_muslc.x86_64.a -O /usr/lib/x86_64-linux-gnu/libwasmvm_muslc.a
- wget https://github.com/CosmWasm/wasmvm/releases/download/v1.1.1/libwasmvm_muslc.aarch64.a -O /usr/lib/aarch64-linux-gnu/libwasmvm_muslc.a
- wget https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0/libwasmvm_muslc.x86_64.a -O /usr/lib/x86_64-linux-gnu/libwasmvm_muslc.a
- wget https://github.com/CosmWasm/wasmvm/releases/download/v1.3.0/libwasmvm_muslc.aarch64.a -O /usr/lib/aarch64-linux-gnu/libwasmvm_muslc.a
goos:
- linux
goarch:
Expand All @@ -49,7 +52,7 @@ builds:
- -mod=readonly
- -trimpath
ldflags:
- -s -w -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X github.com/cosmos/cosmos-sdk/version.Name=nibiru -X github.com/cosmos/cosmos-sdk/version.AppName=nibid -X github.com/cosmos/cosmos-sdk/version.Version={{ .Version }} -X github.com/cosmos/cosmos-sdk/version.Commit={{ .Commit }} -X github.com/tendermint/tendermint/version.TMCoreSemVer={{ .Env.TM_VERSION }}
- -s -w -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X github.com/cosmos/cosmos-sdk/version.Name=nibiru -X github.com/cosmos/cosmos-sdk/version.AppName=nibid -X github.com/cosmos/cosmos-sdk/version.Version={{ .Version }} -X github.com/cosmos/cosmos-sdk/version.Commit={{ .Commit }}
- -linkmode=external
- -extldflags '-Wl,-z,muldefs -static -lm'
tags:
Expand Down
17 changes: 14 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
FROM golang:1.19
FROM golang:alpine AS builder

WORKDIR /feeder

COPY go.sum go.mod ./
RUN go mod download
COPY . .
RUN go build -o ./build/feeder ./cmd/feeder/.
ENTRYPOINT ["./build/feeder"]
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
go build -o ./build/feeder ./cmd/feeder/

FROM gcr.io/distroless/static:nonroot

WORKDIR /
COPY --from=builder /feeder/build/feeder .
USER nonroot:nonroot
ENTRYPOINT ["/feeder"]
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,9 @@ release:
docker run \
--rm \
--platform=linux/amd64 \
--privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$(CURDIR)":/go/src/$(PACKAGE_NAME) \
-w /go/src/$(PACKAGE_NAME) \
-e CGO_ENABLED=1 \
-e TM_VERSION=$(shell go list -m github.com/tendermint/tendermint | sed 's:.* ::') \
-e GITHUB_TOKEN=${GITHUB_TOKEN} \
goreleaser/goreleaser-cross:${GOLANG_CROSS_VERSION} \
release --rm-dist
106 changes: 81 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
# Nibiru x/oracle Price Feeder
# NibiruChain/pricefeeder for the Oracle Module

Submits prices to the nibiru decentralized oracle.
<img src="./repo-banner.png">

## Configuration using `.env`
The `pricefeeder` is a tool developed for Nibiru's [Oracle Module consensus](https://nibiru.fi/docs/ecosystem/oracle/) that runs a process to pull data from various external sources and then broadcasts transactions to vote on exchange rates.

Feeder requires the following environment variables to run:
- [NibiruChain/pricefeeder for the Oracle Module](#nibiruchainpricefeeder-for-the-oracle-module)
- [Quick Start - Local Development](#quick-start---local-development)
- [Configuration for the `.env`](#configuration-for-the-env)
- [Run](#run)
- [Hacking](#hacking)
- [Build](#build)
- [Delegating "feeder" consent](#delegating-feeder-consent)
- [Enabling TLS](#enabling-tls)
- [Configuring specific exchanges](#configuring-specific-exchanges)

## Quick Start - Local Development

### Configuration for the `.env`

Running a `feeder` requires the setting environment variables in your `.env` in like the following:

```ini
CHAIN_ID="nibiru-localnet-0"
Expand All @@ -14,46 +28,88 @@ FEEDER_MNEMONIC="guard cream sadness conduct invite crumble clock pudding hole g
EXCHANGE_SYMBOLS_MAP='{"bitfinex": {"ubtc:unusd": "tBTCUSD", "ueth:unusd": "tETHUSD", "uusd:unusd": "tUSTUSD"}}'
```

### Delegating post pricing
This would allow you to run `pricefeeder` using a local instance of the network. To set up a local network, you can run:

In order to be able to delegate the post pricing you need to set the
env variable for the validator that delegated you the post pricing:
```bash
git clone [email protected]:NibiruChain/nibiru.git
cd nibiru
git checkout v0.19.2
make localnet
```

```ini
VALIDATOR_ADDRESS="nibiruvaloper1..."
### Run

With your environment set to a live network, you can now run the price feeder:
```sh
make run
```

And from your validator node, you need to delegate responsibilites to the feeder address
#### Or, to run the tool as a daemon:

1. Build a docker image for use with docker compose.
```bash
make build-docker
```

2. Run the 'price_feeder' service defined in the `docker-compose.yaml`.
```bash
make docker-compose up -d price_feeder
```

## Hacking

Connecters for data sources like Binance and Bitfinex are defined in the `feeder/priceprovider/sources` directory. Each of these sources must implement a `FetchPricesFunc` function for querying external data.

### Build

Builds the binary for the package:

```sh
nibid tx oracle set-feeder <feeder address> --from validator
make build
```

### Configuring specific exchanges
### Delegating "feeder" consent

#### CoinGecko
Votes for exhange rates in the [Oracle Module](https://nibiru.fi/docs/ecosystem/oracle/) are posted by validator nodes, however a validator can give consent a `feeder` account to post prices on its behalf. This way, the validator won't have to use their validator's mnemonic to send transactions.

Coingecko source allows to use paid api key to get more requests per minute. In order to configure it,
you need to set env var:
In order to be able to delegate consent to post prices, you need to set the
`VALIDATOR_ADDRESS` env variable to the "valoper" address the `feeder` will represent.

```ini
DATASOURCE_CONFIG_MAP='{"coingecko": {"api_key": "0123456789"}}'
VALIDATOR_ADDRESS="nibivaloper1..."
```

## Build
To delegate consent from a validator node to some `feeder` address, you must execute a `MsgDelegateFeedConsent` message:
```go
type MsgDelegateFeedConsent struct {
Operator string
Delegate string
}
```

```sh
make build-feeder
This is possible using the `set-feeder` subcommand of the `nibid` CLI:

```bash
nibid tx oracle set-feeder [feeder-address] --from validator
```

## Run
### Enabling TLS

```sh
make run
To enable TLS, you need to set the following env vars:

```ini
TLS_ENABLED="true"
```

or to run as a daemon:

```sh
make docker-compose up -d price_feeder
### Configuring specific exchanges

#### CoinGecko

Coingecko source allows to use paid api key to get more requests per minute. In order to configure it,
you need to set env var:

```ini
DATASOURCE_CONFIG_MAP='{"coingecko": {"api_key": "0123456789"}}'
```

4 changes: 2 additions & 2 deletions cmd/feeder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func main() {

c := config.MustGet()

eventStream := eventstream.Dial(c.WebsocketEndpoint, c.GRPCEndpoint, logger)
eventStream := eventstream.Dial(c.WebsocketEndpoint, c.GRPCEndpoint, c.EnableTLS, logger)
priceProvider := priceprovider.NewAggregatePriceProvider(c.ExchangesToPairToSymbolMap, c.DataSourceConfigMap, logger)
kb, valAddr, feederAddr := config.GetAuth(c.FeederMnemonic)

if c.ValidatorAddr != nil {
valAddr = *c.ValidatorAddr
}
pricePoster := priceposter.Dial(c.GRPCEndpoint, c.ChainID, kb, valAddr, feederAddr, logger)
pricePoster := priceposter.Dial(c.GRPCEndpoint, c.ChainID, c.EnableTLS, kb, valAddr, feederAddr, logger)

f := feeder.NewFeeder(eventStream, priceProvider, pricePoster, logger)
f.Run()
Expand Down
27 changes: 22 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@ import (
"github.com/joho/godotenv"
)

var defaultExchangeSymbolsMap = map[string]map[asset.Pair]types.Symbol{
"coingecko": {
"ubtc:uusd": "bitcoin",
"ueth:uusd": "ethereum",
"uusdt:uusd": "tether",
"uusdc:uusd": "usd-coin",
"uatom:uusd": "cosmos",
},
"bitfinex": {
"ubtc:uusd": "tBTCUSD",
"ueth:uusd": "tETHUSD",
"uusdc:uusd": "tUDCUSD",
},
}

func MustGet() *Config {
conf, err := Get()
if err != nil {
Expand All @@ -35,15 +50,16 @@ func Get() (*Config, error) {
conf.GRPCEndpoint = os.Getenv("GRPC_ENDPOINT")
conf.WebsocketEndpoint = os.Getenv("WEBSOCKET_ENDPOINT")
conf.FeederMnemonic = os.Getenv("FEEDER_MNEMONIC")
exchangeSymbolsMapJson := os.Getenv("EXCHANGE_SYMBOLS_MAP")
exchangeSymbolsMap := map[string]map[string]string{}
err := json.Unmarshal([]byte(exchangeSymbolsMapJson), &exchangeSymbolsMap)
conf.EnableTLS = os.Getenv("ENABLE_TLS") == "true"
overrideExchangeSymbolsMapJson := os.Getenv("EXCHANGE_SYMBOLS_MAP")
overrideExchangeSymbolsMap := map[string]map[string]string{}
err := json.Unmarshal([]byte(overrideExchangeSymbolsMapJson), &overrideExchangeSymbolsMap)
if err != nil {
return nil, fmt.Errorf("failed to parse EXCHANGE_SYMBOLS_MAP: invalid json")
}

conf.ExchangesToPairToSymbolMap = map[string]map[asset.Pair]types.Symbol{}
for exchange, symbolMap := range exchangeSymbolsMap {
conf.ExchangesToPairToSymbolMap = defaultExchangeSymbolsMap
for exchange, symbolMap := range overrideExchangeSymbolsMap {
conf.ExchangesToPairToSymbolMap[exchange] = map[asset.Pair]types.Symbol{}
for nibiAssetPair, tickerSymbol := range symbolMap {
conf.ExchangesToPairToSymbolMap[exchange][asset.MustNewPair(nibiAssetPair)] = types.Symbol(tickerSymbol)
Expand Down Expand Up @@ -82,6 +98,7 @@ type Config struct {
FeederMnemonic string
ChainID string
ValidatorAddr *sdk.ValAddress
EnableTLS bool
}

func (c *Config) Validate() error {
Expand Down
Loading

0 comments on commit b469b66

Please sign in to comment.