@@ -21,22 +21,21 @@ class Publisher:
2121 """
2222 def __init__ (self , config : Config , price_state : PriceState , metrics : Metrics ):
2323 self .publish_interval = float (config .hyperliquid .publish_interval )
24- self .kms_signer = None
25- self .enable_kms = False
2624 self .use_testnet = config .hyperliquid .use_testnet
25+ self .push_urls = [TESTNET_API_URL if self .use_testnet else MAINNET_API_URL ] + config .hyperliquid .backup_push_urls
2726
28- if config .kms .enable_kms :
29- self .enable_kms = True
30- oracle_account = None
31- self .kms_signer = KMSSigner (config )
32- else :
33- oracle_pusher_key_path = config .hyperliquid .oracle_pusher_key_path
34- oracle_pusher_key = Path (oracle_pusher_key_path ).read_text ().strip ()
27+ self .kms_signer = None
28+ self .enable_kms = False
29+ oracle_account = None
30+ if not config .kms .enable_kms :
31+ oracle_pusher_key = Path (config .hyperliquid .oracle_pusher_key_path ).read_text ().strip ()
3532 oracle_account : LocalAccount = Account .from_key (oracle_pusher_key )
3633 logger .info ("oracle pusher local pubkey: {}" , oracle_account .address )
34+ self .publisher_exchanges = [Exchange (wallet = oracle_account , base_url = url ) for url in self .push_urls ]
35+ if config .kms .enable_kms :
36+ self .enable_kms = True
37+ self .kms_signer = KMSSigner (config , self .publisher_exchanges )
3738
38- url = TESTNET_API_URL if self .use_testnet else MAINNET_API_URL
39- self .oracle_publisher_exchange : Exchange = Exchange (wallet = oracle_account , base_url = url )
4039 self .market_name = config .hyperliquid .market_name
4140 self .market_symbol = config .hyperliquid .market_symbol
4241 self .enable_publish = config .hyperliquid .enable_publish
@@ -72,6 +71,7 @@ def publish(self):
7271 # TODO: "Each update can change oraclePx and markPx by at most 1%."
7372 # TODO: "The markPx cannot be updated such that open interest would be 10x the open interest cap."
7473
74+ push_response = None
7575 if self .enable_publish :
7676 if self .enable_kms :
7777 push_response = self .kms_signer .set_oracle (
@@ -81,18 +81,38 @@ def publish(self):
8181 external_perp_pxs = external_perp_pxs ,
8282 )
8383 else :
84- push_response = self .oracle_publisher_exchange .perp_deploy_set_oracle (
85- dex = self .market_name ,
84+ push_response = self ._send_update (
8685 oracle_pxs = oracle_pxs ,
8786 all_mark_pxs = mark_pxs ,
8887 external_perp_pxs = external_perp_pxs ,
8988 )
9089
91- # TODO: Look at specific error responses and log/alert accordingly
92- logger .debug ("publish: push response: {} {}" , push_response , type (push_response ))
93- status = push_response .get ("status" , "" )
94- if status == "ok" :
95- self .metrics .successful_push_counter .add (1 , self .metrics_labels )
96- elif status == "err" :
97- self .metrics .failed_push_counter .add (1 , self .metrics_labels )
98- logger .error ("publish: publish error: {}" , push_response )
90+ self ._handle_response (push_response )
91+
92+ def _send_update (self , oracle_pxs , all_mark_pxs , external_perp_pxs ):
93+ for exchange in self .publisher_exchanges :
94+ try :
95+ return exchange .perp_deploy_set_oracle (
96+ dex = self .market_name ,
97+ oracle_pxs = oracle_pxs ,
98+ all_mark_pxs = all_mark_pxs ,
99+ external_perp_pxs = external_perp_pxs ,
100+ )
101+ except Exception as e :
102+ logger .exception ("perp_deploy_set_oracle exception for endpoint: {} error: {}" , exchange .base_url , e )
103+
104+ return None
105+
106+ def _handle_response (self , response ):
107+ if response is None :
108+ logger .error ("Push API call failed" )
109+ self .metrics .failed_push_counter .add (1 , self .metrics_labels )
110+ return
111+
112+ logger .debug ("publish: push response: {} {}" , response , type (response ))
113+ status = response .get ("status" )
114+ if status == "ok" :
115+ self .metrics .successful_push_counter .add (1 , self .metrics_labels )
116+ elif status == "err" :
117+ self .metrics .failed_push_counter .add (1 , self .metrics_labels )
118+ logger .error ("publish: publish error: {}" , response )
0 commit comments