From 4ec5b29bafb4b7d51d148e022239f54b8d9b1596 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Fri, 16 Dec 2022 16:57:40 +0000 Subject: [PATCH 1/3] [price-service] Update docs + compose-file --- third_party/pyth/price-service/.env.sample | 8 --- third_party/pyth/price-service/README.md | 70 ++++++++++--------- .../price-service/docker-compose.mainnet.yaml | 50 +++++++++++++ .../price-service/docker-compose.testnet.yaml | 50 +++++++++++++ .../pyth/price-service/docker-compose.yaml | 40 ----------- 5 files changed, 137 insertions(+), 81 deletions(-) create mode 100644 third_party/pyth/price-service/docker-compose.mainnet.yaml create mode 100644 third_party/pyth/price-service/docker-compose.testnet.yaml delete mode 100644 third_party/pyth/price-service/docker-compose.yaml diff --git a/third_party/pyth/price-service/.env.sample b/third_party/pyth/price-service/.env.sample index bbcfd1d873..b7526873ad 100644 --- a/third_party/pyth/price-service/.env.sample +++ b/third_party/pyth/price-service/.env.sample @@ -4,14 +4,6 @@ SPY_SERVICE_HOST=0.0.0.0:7072 ## Filters (if provided) should be valid JSON like below: SPY_SERVICE_FILTERS=[{"chain_id":1,"emitter_address":"71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b"}] -# TestNet: -#SPY_SERVICE_HOST=0.0.0.0:7073 -#SPY_SERVICE_FILTERS=[{"chain_id":1,"emitter_address":"f346195ac02f37d60d4db8ffa6ef74cb1be3550047543a4a9ee9acf4d78697b0"}] - -# MainNet: -#SPY_SERVICE_HOST=0.0.0.0:7074 -#SPY_SERVICE_FILTERS=[{"chain_id":1,"emitter_address":"6bb14509a612f01fbbc4cffeebd4bbfb492a86df717ebe92eb6df432a3f00a25"}] - # Number of seconds to sync with spy to be sure to have latest messages READINESS_SPY_SYNC_TIME_SECONDS=60 READINESS_NUM_LOADED_SYMBOLS=5 diff --git a/third_party/pyth/price-service/README.md b/third_party/pyth/price-service/README.md index 6cd0a930b9..51394d2dce 100644 --- a/third_party/pyth/price-service/README.md +++ b/third_party/pyth/price-service/README.md @@ -1,54 +1,58 @@ # Pyth Price Service -This service exposes a REST and WS api to provide latest attestation message for a price feed id. +Pyth price service is a webservice that listens to the Wormhole Network for Pyth price updates and serves them via a +convenient web API. The service allows users to easily query for recent price updates via a REST API, or subscribe to +a websocket for streaming updates. [The Pyth Network Javascript SDKs](https://github.com/pyth-network/pyth-js) connect +to an instance of the price service in order to fetch on-demand price updates. -## Build +## Public Endpoints -First, build the wasm container from the repo root: +The Pyth Data Association operates two public endpoints for the price service, for mainnet and testnet respectively. +These endpoints can be used to test integrations with Pyth Network: -``` -docker buildx build -f Dockerfile.wasm -o type=local,dest=. . -``` +| network | url | +| ------- | ------------------------------- | +| mainnet | https://xc-mainnet.pyth.network | +| testnet | https://xc-testnet.pyth.network | -Then, build the pyth_price_service docker container from the repo root: +For production deployments, developers integrating with Pyth Network are **strongly encouraged** to host their own instance of the price service for maximum resilience and decentralization. +By running an independent instance of this service, developers tap directly into Wormhole's peer-to-peer network to stream Pyth price updates. +This peer-to-peer network has built-in redundancy and is therefore inherently more reliable than a centralized service operated by the PDA. -``` -$ docker buildx build -f third_party/pyth/price-service/Dockerfile.price_service -t pyth_price_service . -``` +## Wormhole Spy -Run the spy_guardian docker container in TestNet: +Price service depends on a Wormhole spy to stream Pyth messages from the Wormhole Network to it. +[Spy](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go) is a component of a +Wormhole guardian node that joins the Wormhole Network peer-to-peer network and listens to the Wormhole verified +messages and streams the messages that are coming from certain emitters (e.g., Pyth data emitters) to its subscribers. -``` -$ docker run --platform linux/amd64 --network=host ghcr.io/certusone/guardiand:v2.8.8.1 spy \ ---nodeKey /node.key --spyRPC "[::]:7073" \ ---bootstrap /dns4/wormhole-testnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWBY9ty9CXLBXGQzMuqkziLntsVcyz4pk1zWaJRvJn6Mmt \ ---network /wormhole/testnet/2/1 -``` +## Run -Or run the spy_guardian docker container in MainNet: -For the MainNet gossip network parameters, see https://github.com/wormhole-foundation/wormhole-networks/blob/master/mainnetv2/info.md +To run Pyth price service, you need to have Wormhole spy running. You can simply run both price service +and spy using provided mainnet and testnet docker compose files. To run the mainnet docker +compose file run the following command: ``` -$ docker run --platform linux/amd64 -d --network=host ghcr.io/certusone/guardiand:v2.8.8.1 spy \ ---nodeKey /node.key --spyRPC "[::]:7073" \ ---bootstrap \ ---network \ +docker-compose up -f docker-compose.mainnet.yaml ``` -Then to run the pyth_price_service docker container using a config file called `${HOME}/pyth_price_service/env` and logging to directory `${HOME}/pyth_price_service/logs`, do the -following: +The compose files use a public release of Pyth price service and spy. If you wish to change the +price service, you need to build an image for using it first. + +## Build an image + +First, build the wasm files from the repo root like below. This command generates the wasm files necessary +for parsing Pyth messages coming from Wormhole. ``` -$ docker run \ ---volume=${HOME}/pyth_price_service:/var/pyth_price_service \ --e PYTH_PRICE_SERVICE_CONFIG=/var/pyth_price_service/env \ ---network=host \ -pyth_price_service +docker buildx build -f Dockerfile.wasm -o type=local,dest=. . ``` -Or, run docker compose in the `third_party/pyth/price-service` directory using the commands below. It will run a spy listening to the Wormhole testnet network and a price service that connects to it. Then the price service will serve the Pyth prices published to the Wormhole testnet network. +Then, build the pyth_price_service docker container from the repo root like so: ``` -$ cd third_party/pyth/price-service -$ docker compose up +$ docker buildx build -f third_party/pyth/price-service/Dockerfile.price_service -t pyth_price_service . ``` + +If you wish to build price service without docker, please follow the instruction of the price service +[`Dockerfile`](./Dockerfile.price_service) diff --git a/third_party/pyth/price-service/docker-compose.mainnet.yaml b/third_party/pyth/price-service/docker-compose.mainnet.yaml new file mode 100644 index 0000000000..16f652bf97 --- /dev/null +++ b/third_party/pyth/price-service/docker-compose.mainnet.yaml @@ -0,0 +1,50 @@ +services: + spy: + # Find latest Guardian images in https://github.com/wormhole-foundation/wormhole/pkgs/container/guardiand + image: ghcr.io/wormhole-foundation/guardiand:v.2.14.5 + command: + - "spy" + - "--nodeKey" + - "/node.key" + - "--spyRPC" + - "[::]:7072" + - "--bootstrap" + - "/dns4/wormhole-mainnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWQp644DK27fd3d4Km3jr7gHiuJJ5ZGmy8hH4py7fP4FP7" + - "--network" + - "/wormhole/mainnet/2" + - "--logLevel" + - "warn" + price-service: + # Find latest price service images https://gallery.ecr.aws/pyth-network/xc-server + image: public.ecr.aws/pyth-network/xc-server:v2.2.3 + environment: + SPY_SERVICE_HOST: "spy:7072" + SPY_SERVICE_FILTERS: | + [ + { + "chain_id": 1, + "emitter_address": "6bb14509a612f01fbbc4cffeebd4bbfb492a86df717ebe92eb6df432a3f00a25" + }, + { + "chain_id": 26, + "emitter_address": "f8cd23c2ab91237730770bbea08d61005cdda0984348f3f6eecb559638c0bba0" + } + ] + REST_PORT: "4200" + PROM_PORT: "8081" + READINESS_SPY_SYNC_TIME_SECONDS: "20" + READINESS_NUM_LOADED_SYMBOLS: "50" + LOG_LEVEL: warning + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:4200/ready", + ] + start_period: 20s + depends_on: + - spy diff --git a/third_party/pyth/price-service/docker-compose.testnet.yaml b/third_party/pyth/price-service/docker-compose.testnet.yaml new file mode 100644 index 0000000000..70a963928a --- /dev/null +++ b/third_party/pyth/price-service/docker-compose.testnet.yaml @@ -0,0 +1,50 @@ +services: + spy: + # Find latest Guardian images in https://github.com/wormhole-foundation/wormhole/pkgs/container/guardiand + image: ghcr.io/wormhole-foundation/guardiand:v.2.14.5 + command: + - "spy" + - "--nodeKey" + - "/node.key" + - "--spyRPC" + - "[::]:7072" + - "--bootstrap" + - "/dns4/wormhole-testnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWAkB9ynDur1Jtoa97LBUp8RXdhzS5uHgAfdTquJbrbN7i" + - "--network" + - "/wormhole/testnet/2/1" + - "--logLevel" + - "warn" + price-service: + # Find latest price service images https://gallery.ecr.aws/pyth-network/xc-server + image: public.ecr.aws/pyth-network/xc-server:v2.2.3 + environment: + SPY_SERVICE_HOST: "spy:7072" + SPY_SERVICE_FILTERS: | + [ + { + "chain_id": 1, + "emitter_address": "f346195ac02f37d60d4db8ffa6ef74cb1be3550047543a4a9ee9acf4d78697b0" + }, + { + "chain_id": 26, + "emitter_address": "a27839d641b07743c0cb5f68c51f8cd31d2c0762bec00dc6fcd25433ef1ab5b6" + } + ] + REST_PORT: "4200" + PROM_PORT: "8081" + READINESS_SPY_SYNC_TIME_SECONDS: "20" + READINESS_NUM_LOADED_SYMBOLS: "50" + LOG_LEVEL: warning + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://localhost:4200/ready", + ] + start_period: 20s + depends_on: + - spy diff --git a/third_party/pyth/price-service/docker-compose.yaml b/third_party/pyth/price-service/docker-compose.yaml deleted file mode 100644 index d858adbd2f..0000000000 --- a/third_party/pyth/price-service/docker-compose.yaml +++ /dev/null @@ -1,40 +0,0 @@ -services: - spy: - image: ghcr.io/certusone/guardiand:v2.8.8.1 - command: - - "spy" - - "--nodeKey" - - "/node.key" - - "--spyRPC" - - "[::]:7072" - - "--bootstrap" - - "/dns4/wormhole-testnet-v2-bootstrap.certus.one/udp/8999/quic/p2p/12D3KooWBY9ty9CXLBXGQzMuqkziLntsVcyz4pk1zWaJRvJn6Mmt" - - "--network" - - "/wormhole/testnet/2/1" - - "--logLevel" - - "debug" - price-service: - image: pyth_price_service - ports: - - "4200:4200" - environment: - - SPY_SERVICE_HOST=spy:7072 - - SPY_SERVICE_FILTERS=[{"chain_id":1,"emitter_address":"f346195ac02f37d60d4db8ffa6ef74cb1be3550047543a4a9ee9acf4d78697b0"}] - - REST_PORT=4200 - - PROM_PORT=8081 - - READINESS_SPY_SYNC_TIME_SECONDS=60 - - READINESS_NUM_LOADED_SYMBOLS=8 - - LOG_LEVEL=debug - healthcheck: - test: - [ - "CMD", - "wget", - "--no-verbose", - "--tries=1", - "--spider", - "http://localhost:4200/ready", - ] - start_period: 60s - depends_on: - - spy From dd498567da1781035c19f43408a297438c711850 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Mon, 19 Dec 2022 14:36:23 +0100 Subject: [PATCH 2/3] Address reviews --- third_party/pyth/price-service/README.md | 29 +++++++++++-------- .../price-service/docker-compose.mainnet.yaml | 2 ++ .../price-service/docker-compose.testnet.yaml | 2 ++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/third_party/pyth/price-service/README.md b/third_party/pyth/price-service/README.md index 51394d2dce..4287791ce3 100644 --- a/third_party/pyth/price-service/README.md +++ b/third_party/pyth/price-service/README.md @@ -1,6 +1,6 @@ # Pyth Price Service -Pyth price service is a webservice that listens to the Wormhole Network for Pyth price updates and serves them via a +The Pyth price service is a webservice that listens to the Wormhole Network for Pyth price updates and serves them via a convenient web API. The service allows users to easily query for recent price updates via a REST API, or subscribe to a websocket for streaming updates. [The Pyth Network Javascript SDKs](https://github.com/pyth-network/pyth-js) connect to an instance of the price service in order to fetch on-demand price updates. @@ -21,34 +21,39 @@ This peer-to-peer network has built-in redundancy and is therefore inherently mo ## Wormhole Spy -Price service depends on a Wormhole spy to stream Pyth messages from the Wormhole Network to it. -[Spy](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go) is a component of a -Wormhole guardian node that joins the Wormhole Network peer-to-peer network and listens to the Wormhole verified -messages and streams the messages that are coming from certain emitters (e.g., Pyth data emitters) to its subscribers. +The price service depends on a Wormhole Spy to stream Pyth messages from the Wormhole Network to it. The +[spy](https://github.com/wormhole-foundation/wormhole/blob/main/node/cmd/spy/spy.go) is a Wormhole component that listens to the Wormhole verified +messages from the Wormhole Network peer-to-peer network; then, it streams the messages that are coming from certain emitters (e.g., Pyth data emitters) to its subscribers. + +The price service subscribes to the spy to fetch all verified prices coming from the Pyth data sources. The Pyth data sources should +be defined in `SPY_SERVICE_FILTERS` environment variable as a JSON array. ## Run -To run Pyth price service, you need to have Wormhole spy running. You can simply run both price service -and spy using provided mainnet and testnet docker compose files. To run the mainnet docker -compose file run the following command: +This repository contains testnet and mainnet docker-compose files to run +both the price service and spy. To run the mainnet docker compose file run +the following command: ``` docker-compose up -f docker-compose.mainnet.yaml ``` The compose files use a public release of Pyth price service and spy. If you wish to change the -price service, you need to build an image for using it first. +price service you should: +1. Build an image for using it first according to the section below. +2. Change the price service image to your local docker image (e.g., `pyth_price_service`) ## Build an image -First, build the wasm files from the repo root like below. This command generates the wasm files necessary -for parsing Pyth messages coming from Wormhole. +First, build the wasm files from [the repo root](../../../) like below. This command generates the wasm files necessary +for parsing Pyth messages coming from Wormhole and stores them on [this](../p2w-sdk/js/src/solana/p2w-core) directory. ``` docker buildx build -f Dockerfile.wasm -o type=local,dest=. . ``` -Then, build the pyth_price_service docker container from the repo root like so: +Then, build the image from [the repo root](../../../) like below. It will create a +local image named `pyth_price_service`. ``` $ docker buildx build -f third_party/pyth/price-service/Dockerfile.price_service -t pyth_price_service . diff --git a/third_party/pyth/price-service/docker-compose.mainnet.yaml b/third_party/pyth/price-service/docker-compose.mainnet.yaml index 16f652bf97..736a48a3b9 100644 --- a/third_party/pyth/price-service/docker-compose.mainnet.yaml +++ b/third_party/pyth/price-service/docker-compose.mainnet.yaml @@ -17,6 +17,8 @@ services: price-service: # Find latest price service images https://gallery.ecr.aws/pyth-network/xc-server image: public.ecr.aws/pyth-network/xc-server:v2.2.3 + # Or alternatively use a locally built image + # image: pyth_price_service environment: SPY_SERVICE_HOST: "spy:7072" SPY_SERVICE_FILTERS: | diff --git a/third_party/pyth/price-service/docker-compose.testnet.yaml b/third_party/pyth/price-service/docker-compose.testnet.yaml index 70a963928a..296ebbe14c 100644 --- a/third_party/pyth/price-service/docker-compose.testnet.yaml +++ b/third_party/pyth/price-service/docker-compose.testnet.yaml @@ -17,6 +17,8 @@ services: price-service: # Find latest price service images https://gallery.ecr.aws/pyth-network/xc-server image: public.ecr.aws/pyth-network/xc-server:v2.2.3 + # Or alternatively use a locally built image + # image: pyth_price_service environment: SPY_SERVICE_HOST: "spy:7072" SPY_SERVICE_FILTERS: | From bac48f65d809beb64b96af25231d7f468320875d Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Mon, 19 Dec 2022 13:54:53 +0000 Subject: [PATCH 3/3] Fix pre-commit issues --- third_party/pyth/price-service/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/pyth/price-service/README.md b/third_party/pyth/price-service/README.md index 4287791ce3..7f0ddea154 100644 --- a/third_party/pyth/price-service/README.md +++ b/third_party/pyth/price-service/README.md @@ -40,6 +40,7 @@ docker-compose up -f docker-compose.mainnet.yaml The compose files use a public release of Pyth price service and spy. If you wish to change the price service you should: + 1. Build an image for using it first according to the section below. 2. Change the price service image to your local docker image (e.g., `pyth_price_service`)