Explorar o código

add new freshness check to price-service /ready endpoint (#275)

Daniel Chew %!s(int64=3) %!d(string=hai) anos
pai
achega
8c0e9b6e2e

+ 2 - 0
devnet/pyth-price-service.yaml

@@ -70,5 +70,7 @@ spec:
               value: '5'
             - name: READINESS_NUM_LOADED_SYMBOLS
               value: '6'
+            - name: READINESS_FRESHNESS_TIME_SECONDS
+              value: '10'
             - name: LOG_LEVEL
               value: debug

+ 1 - 0
third_party/pyth/price-service/.env.sample

@@ -15,6 +15,7 @@ SPY_SERVICE_FILTERS=[{"chain_id":1,"emitter_address":"71f8dcb863d176e2c420ad6610
 # 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
+READINESS_FRESHNESS_TIME_SECONDS=10
 
 WS_PORT=6200
 REST_PORT=4200

+ 1 - 0
third_party/pyth/price-service/docker-compose.yaml

@@ -24,6 +24,7 @@ services:
       - PROM_PORT=8081
       - READINESS_SPY_SYNC_TIME_SECONDS=60
       - READINESS_NUM_LOADED_SYMBOLS=8
+      - READINESS_FRESHNESS_TIME_SECONDS=10
       - LOG_LEVEL=debug
     healthcheck:
       test:

+ 1 - 0
third_party/pyth/price-service/src/index.ts

@@ -35,6 +35,7 @@ async function run() {
           envOrErr("READINESS_SPY_SYNC_TIME_SECONDS")
         ),
         numLoadedSymbols: parseInt(envOrErr("READINESS_NUM_LOADED_SYMBOLS")),
+        freshnessTimeSeconds: parseInt(envOrErr("READINESS_FRESHNESS_TIME_SECONDS")),
       },
     },
     promClient

+ 13 - 2
third_party/pyth/price-service/src/listen.ts

@@ -43,6 +43,7 @@ export interface PriceStore {
 type ListenerReadinessConfig = {
   spySyncTimeSeconds: number;
   numLoadedSymbols: number;
+  freshnessTimeSeconds: number;
 };
 
 type ListenerConfig = {
@@ -198,7 +199,7 @@ export class Listener implements PriceStore {
           attestationTime: priceAttestation.attestationTime,
           priceFeed,
           emitterChainId: parsedVAA.emitter_chain,
-        }
+        };
         this.priceFeedVaaMap.set(key, priceInfo);
 
         for (let callback of this.updateCallbacks) {
@@ -234,7 +235,7 @@ export class Listener implements PriceStore {
   }
 
   isReady(): boolean {
-    let currentTime: TimestampInSec = new Date().getTime() / 1000;
+    let currentTime: TimestampInSec = Math.floor(Date.now() / 1000);
     if (
       this.spyConnectionTime === undefined ||
       currentTime <
@@ -245,6 +246,16 @@ export class Listener implements PriceStore {
     if (this.priceFeedVaaMap.size < this.readinessConfig.numLoadedSymbols) {
       return false;
     }
+    let priceIds = [...this.getPriceIds()];
+    let arePricesFresh = priceIds.every(
+      (priceId) =>
+        currentTime -
+          this.priceFeedVaaMap.get(priceId)!.priceFeed.publishTime <=
+        this.readinessConfig.freshnessTimeSeconds
+    );
+    if (!arePricesFresh) {
+      return false;
+    }
     return true;
   }
 }