From 19c475e4a6a4371deccc4988497d5331efb57f4d Mon Sep 17 00:00:00 2001 From: Stan Drozd Date: Mon, 4 Oct 2021 15:51:01 +0200 Subject: [PATCH] pyth2wormhole: share pending attestation information over HTTP Change-Id: I585392f995f3d32b5e8152c08c79a012091c36ed --- third_party/pyth/p2w_autoattest.py | 54 ++++++++++++++++++++++++++++++ third_party/pyth/pyth_publisher.py | 6 ++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/third_party/pyth/p2w_autoattest.py b/third_party/pyth/p2w_autoattest.py index f8bfa247..b2b1ab37 100755 --- a/third_party/pyth/p2w_autoattest.py +++ b/third_party/pyth/p2w_autoattest.py @@ -4,9 +4,11 @@ from pyth_utils import * from http.client import HTTPConnection +from http.server import HTTPServer, BaseHTTPRequestHandler import json import os +import re import subprocess import time import threading @@ -16,12 +18,46 @@ P2W_ADDRESS = "P2WH424242424242424242424242424242424242424" P2W_ATTEST_INTERVAL = float(os.environ.get("P2W_ATTEST_INTERVAL", 5)) P2W_OWNER_KEYPAIR = os.environ.get( "P2W_OWNER_KEYPAIR", f"/usr/src/solana/keys/p2w_owner.json") +P2W_ATTESTATIONS_PORT = int(os.environ.get("P2W_ATTESTATIONS_PORT", 4343)) PYTH_ACCOUNTS_HOST = "pyth" PYTH_ACCOUNTS_PORT = 4242 WORMHOLE_ADDRESS = "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o" +ATTESTATIONS = { + "pendingSeqnos": [], +} + +class P2WAutoattestStatusEndpoint(BaseHTTPRequestHandler): + """ + A dumb endpoint for last attested price metadata. + """ + + def do_GET(self): + print(f"Got path {self.path}") + sys.stdout.flush() + data = json.dumps(ATTESTATIONS).encode("utf-8") + print(f"Sending:\n{data}") + + ATTESTATIONS["pendingSeqnos"] = [] + + self.send_response(200) + self.send_header("Content-Type", "application/json") + self.send_header("Content-Length", str(len(data))) + self.end_headers() + self.wfile.write(data) + self.wfile.flush() + +def serve_attestations(): + """ + Run a barebones HTTP server to share Pyth2wormhole attestation history + """ + server_address = ('', P2W_ATTESTATIONS_PORT) + httpd = HTTPServer(server_address, P2WAutoattestStatusEndpoint) + httpd.serve_forever() + + # Get actor pubkeys P2W_OWNER_ADDRESS = sol_run_or_die( "address", ["--keypair", P2W_OWNER_KEYPAIR], capture_output=True).stdout.strip() @@ -99,10 +135,16 @@ print("p2w_autoattest ready to roll.") print(f"ACCOUNTS: {pyth_accounts}") print(f"Attest Interval: {P2W_ATTEST_INTERVAL}") +# Serve p2w endpoint +endpoint_thread = threading.Thread(target=serve_attestations, daemon=True) +endpoint_thread.start() + # Let k8s know the service is up readiness_thread = threading.Thread(target=readiness, daemon=True) readiness_thread.start() +seqno_regex = re.compile(r"^Sequence number: (\d+)") + nonce = 1 while True: attest_result = run_or_die([ @@ -117,6 +159,18 @@ while True: "--nonce", str(nonce), ], capture_output=True) time.sleep(P2W_ATTEST_INTERVAL) + + matches = seqno_regex.match(attest_result.stdout) + + if matches is not None: + seqno = int(matches.group(1)) + print(f"Got seqno {seqno}") + + ATTESTATIONS["pendingSeqnos"].append(seqno) + + else: + print(f"Warning: Could not get sequence number") + nonce += 1 readiness_thread.join() diff --git a/third_party/pyth/pyth_publisher.py b/third_party/pyth/pyth_publisher.py index 4ffd54f0..2478f9a9 100644 --- a/third_party/pyth/pyth_publisher.py +++ b/third_party/pyth/pyth_publisher.py @@ -11,7 +11,7 @@ import threading import time -class P2WAccEndpoint(BaseHTTPRequestHandler): +class PythAccEndpoint(BaseHTTPRequestHandler): """ A dumb endpoint to respond with a JSON containing Pyth account addresses """ @@ -38,7 +38,7 @@ def publisher_random_update(price_pubkey): Update the specified price with random values """ value = random.randrange(1024) - confidence = 1 + confidence = 5 pyth_run_or_die("upd_price_val", args=[ price_pubkey, str(value), str(confidence), "trading" ]) @@ -51,7 +51,7 @@ def accounts_endpoint(): mapping/product/price account addresses """ server_address = ('', 4242) - httpd = HTTPServer(server_address, P2WAccEndpoint) + httpd = HTTPServer(server_address, PythAccEndpoint) httpd.serve_forever()