Procházet zdrojové kódy

fix(lazer): Support int/string/null/missing jrpc id field

Mike Rolish před 1 měsícem
rodič
revize
f5355d26b6

+ 5 - 5
Cargo.lock

@@ -5693,7 +5693,7 @@ dependencies = [
 
 [[package]]
 name = "pyth-lazer-client"
-version = "8.2.2"
+version = "8.3.0"
 dependencies = [
  "alloy-primitives 0.8.25",
  "anyhow",
@@ -5711,7 +5711,7 @@ dependencies = [
  "hex",
  "humantime-serde",
  "libsecp256k1 0.7.2",
- "pyth-lazer-protocol 0.16.0",
+ "pyth-lazer-protocol 0.17.0",
  "reqwest 0.12.23",
  "serde",
  "serde_json",
@@ -5746,7 +5746,7 @@ dependencies = [
 
 [[package]]
 name = "pyth-lazer-protocol"
-version = "0.16.0"
+version = "0.17.0"
 dependencies = [
  "alloy-primitives 0.8.25",
  "anyhow",
@@ -5786,13 +5786,13 @@ dependencies = [
 
 [[package]]
 name = "pyth-lazer-publisher-sdk"
-version = "0.14.0"
+version = "0.15.0"
 dependencies = [
  "anyhow",
  "fs-err",
  "protobuf",
  "protobuf-codegen",
- "pyth-lazer-protocol 0.16.0",
+ "pyth-lazer-protocol 0.17.0",
  "serde_json",
 ]
 

+ 1 - 1
lazer/contracts/solana/programs/pyth-lazer-solana-contract/Cargo.toml

@@ -19,7 +19,7 @@ no-log-ix-name = []
 idl-build = ["anchor-lang/idl-build"]
 
 [dependencies]
-pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.16.0" }
+pyth-lazer-protocol = { path = "../../../../sdk/rust/protocol", version = "0.17.0" }
 
 anchor-lang = "0.31.1"
 bytemuck = { version = "1.20.0", features = ["derive"] }

+ 2 - 2
lazer/publisher_sdk/rust/Cargo.toml

@@ -1,13 +1,13 @@
 [package]
 name = "pyth-lazer-publisher-sdk"
-version = "0.14.0"
+version = "0.15.0"
 edition = "2021"
 description = "Pyth Lazer Publisher SDK types."
 license = "Apache-2.0"
 repository = "https://github.com/pyth-network/pyth-crosschain"
 
 [dependencies]
-pyth-lazer-protocol = { version = "0.16.0", path = "../../sdk/rust/protocol" }
+pyth-lazer-protocol = { version = "0.17.0", path = "../../sdk/rust/protocol" }
 anyhow = "1.0.98"
 protobuf = "3.7.2"
 serde_json = "1.0.140"

+ 2 - 2
lazer/sdk/rust/client/Cargo.toml

@@ -1,12 +1,12 @@
 [package]
 name = "pyth-lazer-client"
-version = "8.2.2"
+version = "8.3.0"
 edition = "2021"
 description = "A Rust client for Pyth Lazer"
 license = "Apache-2.0"
 
 [dependencies]
-pyth-lazer-protocol = { path = "../protocol", version = "0.16.0" }
+pyth-lazer-protocol = { path = "../protocol", version = "0.17.0" }
 tokio = { version = "1", features = ["full"] }
 tokio-tungstenite = { version = "0.20", features = ["native-tls"] }
 futures-util = "0.3"

+ 1 - 1
lazer/sdk/rust/protocol/Cargo.toml

@@ -1,6 +1,6 @@
 [package]
 name = "pyth-lazer-protocol"
-version = "0.16.0"
+version = "0.17.0"
 edition = "2021"
 description = "Pyth Lazer SDK - protocol types."
 license = "Apache-2.0"

+ 100 - 8
lazer/sdk/rust/protocol/src/jrpc.rs

@@ -6,12 +6,22 @@ use crate::{api::Channel, price::Price};
 use serde::{Deserialize, Serialize};
 use std::time::Duration;
 
+#[derive(Serialize, Deserialize, Debug, Default, Eq, PartialEq)]
+#[serde(untagged)]
+pub enum JrpcId {
+    String(String),
+    Int(i64),
+    #[default]
+    Null,
+}
+
 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
 pub struct PythLazerAgentJrpcV1 {
     pub jsonrpc: JsonRpcVersion,
     #[serde(flatten)]
     pub params: JrpcCall,
-    pub id: Option<i64>,
+    #[serde(default)]
+    pub id: JrpcId,
 }
 
 #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
@@ -184,7 +194,89 @@ mod tests {
                     best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()),
                 },
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
+        };
+
+        assert_eq!(
+            serde_json::from_str::<PythLazerAgentJrpcV1>(json).unwrap(),
+            expected
+        );
+    }
+
+    #[test]
+    fn test_push_update_price_string_id() {
+        let json = r#"
+        {
+          "jsonrpc": "2.0",
+          "method": "push_update",
+          "params": {
+            "feed_id": 1,
+            "source_timestamp": 124214124124,
+
+            "update": {
+              "type": "price",
+              "price": 1234567890,
+              "best_bid_price": 1234567891,
+              "best_ask_price": 1234567892
+            }
+          },
+          "id": "b6bb54a0-ea8d-439d-97a7-3b06befa0e76"
+        }
+        "#;
+
+        let expected = PythLazerAgentJrpcV1 {
+            jsonrpc: JsonRpcVersion::V2,
+            params: PushUpdate(FeedUpdateParams {
+                feed_id: PriceFeedId(1),
+                source_timestamp: TimestampUs::from_micros(124214124124),
+                update: UpdateParams::PriceUpdate {
+                    price: Price::from_integer(1234567890, 0).unwrap(),
+                    best_bid_price: Some(Price::from_integer(1234567891, 0).unwrap()),
+                    best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()),
+                },
+            }),
+            id: JrpcId::String("b6bb54a0-ea8d-439d-97a7-3b06befa0e76".to_string()),
+        };
+
+        assert_eq!(
+            serde_json::from_str::<PythLazerAgentJrpcV1>(json).unwrap(),
+            expected
+        );
+    }
+
+    #[test]
+    fn test_push_update_price_null_id() {
+        let json = r#"
+        {
+          "jsonrpc": "2.0",
+          "method": "push_update",
+          "params": {
+            "feed_id": 1,
+            "source_timestamp": 124214124124,
+
+            "update": {
+              "type": "price",
+              "price": 1234567890,
+              "best_bid_price": 1234567891,
+              "best_ask_price": 1234567892
+            }
+          },
+          "id": null
+        }
+        "#;
+
+        let expected = PythLazerAgentJrpcV1 {
+            jsonrpc: JsonRpcVersion::V2,
+            params: PushUpdate(FeedUpdateParams {
+                feed_id: PriceFeedId(1),
+                source_timestamp: TimestampUs::from_micros(124214124124),
+                update: UpdateParams::PriceUpdate {
+                    price: Price::from_integer(1234567890, 0).unwrap(),
+                    best_bid_price: Some(Price::from_integer(1234567891, 0).unwrap()),
+                    best_ask_price: Some(Price::from_integer(1234567892, 0).unwrap()),
+                },
+            }),
+            id: JrpcId::Null,
         };
 
         assert_eq!(
@@ -224,7 +316,7 @@ mod tests {
                     best_ask_price: Some(Price::from_integer(5432, 0).unwrap()),
                 },
             }),
-            id: None,
+            id: JrpcId::Null,
         };
 
         assert_eq!(
@@ -263,7 +355,7 @@ mod tests {
                     best_ask_price: None,
                 },
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
         };
 
         assert_eq!(
@@ -304,7 +396,7 @@ mod tests {
                     funding_rate_interval: Duration::from_secs(28800).into(),
                 },
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
         };
 
         assert_eq!(
@@ -342,7 +434,7 @@ mod tests {
                     funding_rate_interval: None,
                 },
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
         };
 
         assert_eq!(
@@ -371,7 +463,7 @@ mod tests {
                 names: Some(vec!["BTC/USD".to_string()]),
                 asset_types: Some(vec!["crypto".to_string()]),
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
         };
 
         assert_eq!(
@@ -397,7 +489,7 @@ mod tests {
                 names: None,
                 asset_types: None,
             }),
-            id: Some(1),
+            id: JrpcId::Int(1),
         };
 
         assert_eq!(