publisher.rs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //! WebSocket JSON protocol types for API the publisher provides to the router.
  2. //! Publisher data sourcing may also be implemented in the router process,
  3. //! eliminating WebSocket overhead.
  4. use {
  5. super::router::{Price, PriceFeedId, Rate},
  6. crate::time::TimestampUs,
  7. derive_more::derive::From,
  8. serde::{Deserialize, Serialize},
  9. };
  10. /// Represents a binary (bincode-serialized) stream update sent
  11. /// from the publisher to the router.
  12. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  13. #[serde(rename_all = "camelCase")]
  14. pub struct PriceFeedDataV2 {
  15. pub price_feed_id: PriceFeedId,
  16. /// Timestamp of the last update provided by the source of the prices
  17. /// (like an exchange). If unavailable, this value is set to `publisher_timestamp_us`.
  18. pub source_timestamp_us: TimestampUs,
  19. /// Timestamp of the last update provided by the publisher.
  20. pub publisher_timestamp_us: TimestampUs,
  21. /// Last known value of the best executable price of this price feed.
  22. /// `None` if no value is currently available.
  23. pub price: Option<Price>,
  24. /// Last known value of the best bid price of this price feed.
  25. /// `None` if no value is currently available.
  26. pub best_bid_price: Option<Price>,
  27. /// Last known value of the best ask price of this price feed.
  28. /// `None` if no value is currently available.
  29. pub best_ask_price: Option<Price>,
  30. /// Last known value of the funding rate of this feed.
  31. /// `None` if no value is currently available.
  32. pub funding_rate: Option<Rate>,
  33. }
  34. /// Old Represents a binary (bincode-serialized) stream update sent
  35. /// from the publisher to the router.
  36. /// Superseded by `PriceFeedData`.
  37. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  38. #[serde(rename_all = "camelCase")]
  39. pub struct PriceFeedDataV1 {
  40. pub price_feed_id: PriceFeedId,
  41. /// Timestamp of the last update provided by the source of the prices
  42. /// (like an exchange). If unavailable, this value is set to `publisher_timestamp_us`.
  43. pub source_timestamp_us: TimestampUs,
  44. /// Timestamp of the last update provided by the publisher.
  45. pub publisher_timestamp_us: TimestampUs,
  46. /// Last known value of the best executable price of this price feed.
  47. /// `None` if no value is currently available.
  48. #[serde(with = "crate::serde_price_as_i64")]
  49. pub price: Option<Price>,
  50. /// Last known value of the best bid price of this price feed.
  51. /// `None` if no value is currently available.
  52. #[serde(with = "crate::serde_price_as_i64")]
  53. pub best_bid_price: Option<Price>,
  54. /// Last known value of the best ask price of this price feed.
  55. /// `None` if no value is currently available.
  56. #[serde(with = "crate::serde_price_as_i64")]
  57. pub best_ask_price: Option<Price>,
  58. }
  59. impl From<PriceFeedDataV1> for PriceFeedDataV2 {
  60. fn from(v0: PriceFeedDataV1) -> Self {
  61. Self {
  62. price_feed_id: v0.price_feed_id,
  63. source_timestamp_us: v0.source_timestamp_us,
  64. publisher_timestamp_us: v0.publisher_timestamp_us,
  65. price: v0.price,
  66. best_bid_price: v0.best_bid_price,
  67. best_ask_price: v0.best_ask_price,
  68. funding_rate: None,
  69. }
  70. }
  71. }
  72. /// A response sent from the server to the publisher client.
  73. /// Currently only serde errors are reported back to the client.
  74. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, From)]
  75. #[serde(tag = "type")]
  76. #[serde(rename_all = "camelCase")]
  77. pub enum ServerResponse {
  78. UpdateDeserializationError(UpdateDeserializationErrorResponse),
  79. }
  80. /// Sent to the publisher if the binary data could not be parsed
  81. #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
  82. #[serde(rename_all = "camelCase")]
  83. pub struct UpdateDeserializationErrorResponse {
  84. pub error: String,
  85. }
  86. #[test]
  87. fn price_feed_data_v1_serde() {
  88. let data = [
  89. 1, 0, 0, 0, // price_feed_id
  90. 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
  91. 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
  92. 4, 0, 0, 0, 0, 0, 0, 0, // price
  93. 5, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
  94. 6, 2, 0, 0, 0, 0, 0, 0, // best_ask_price
  95. ];
  96. let expected = PriceFeedDataV1 {
  97. price_feed_id: PriceFeedId(1),
  98. source_timestamp_us: TimestampUs::from_micros(2),
  99. publisher_timestamp_us: TimestampUs::from_micros(3),
  100. price: Some(Price(4.try_into().unwrap())),
  101. best_bid_price: Some(Price(5.try_into().unwrap())),
  102. best_ask_price: Some(Price((2 * 256 + 6).try_into().unwrap())),
  103. };
  104. assert_eq!(
  105. bincode::deserialize::<PriceFeedDataV1>(&data).unwrap(),
  106. expected
  107. );
  108. assert_eq!(bincode::serialize(&expected).unwrap(), data);
  109. let data2 = [
  110. 1, 0, 0, 0, // price_feed_id
  111. 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
  112. 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
  113. 4, 0, 0, 0, 0, 0, 0, 0, // price
  114. 0, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
  115. 0, 0, 0, 0, 0, 0, 0, 0, // best_ask_price
  116. ];
  117. let expected2 = PriceFeedDataV1 {
  118. price_feed_id: PriceFeedId(1),
  119. source_timestamp_us: TimestampUs::from_micros(2),
  120. publisher_timestamp_us: TimestampUs::from_micros(3),
  121. price: Some(Price(4.try_into().unwrap())),
  122. best_bid_price: None,
  123. best_ask_price: None,
  124. };
  125. assert_eq!(
  126. bincode::deserialize::<PriceFeedDataV1>(&data2).unwrap(),
  127. expected2
  128. );
  129. assert_eq!(bincode::serialize(&expected2).unwrap(), data2);
  130. }
  131. #[test]
  132. fn price_feed_data_v2_serde() {
  133. let data = [
  134. 1, 0, 0, 0, // price_feed_id
  135. 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
  136. 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
  137. 1, 4, 0, 0, 0, 0, 0, 0, 0, // price
  138. 1, 5, 0, 0, 0, 0, 0, 0, 0, // best_bid_price
  139. 1, 6, 2, 0, 0, 0, 0, 0, 0, // best_ask_price
  140. 0, // funding_rate
  141. ];
  142. let expected = PriceFeedDataV2 {
  143. price_feed_id: PriceFeedId(1),
  144. source_timestamp_us: TimestampUs::from_micros(2),
  145. publisher_timestamp_us: TimestampUs::from_micros(3),
  146. price: Some(Price(4.try_into().unwrap())),
  147. best_bid_price: Some(Price(5.try_into().unwrap())),
  148. best_ask_price: Some(Price((2 * 256 + 6).try_into().unwrap())),
  149. funding_rate: None,
  150. };
  151. assert_eq!(
  152. bincode::deserialize::<PriceFeedDataV2>(&data).unwrap(),
  153. expected
  154. );
  155. assert_eq!(bincode::serialize(&expected).unwrap(), data);
  156. let data2 = [
  157. 1, 0, 0, 0, // price_feed_id
  158. 2, 0, 0, 0, 0, 0, 0, 0, // source_timestamp_us
  159. 3, 0, 0, 0, 0, 0, 0, 0, // publisher_timestamp_us
  160. 1, 4, 0, 0, 0, 0, 0, 0, 0, // price
  161. 0, // best_bid_price
  162. 0, // best_ask_price
  163. 1, 7, 3, 0, 0, 0, 0, 0, 0, // funding_rate
  164. ];
  165. let expected2 = PriceFeedDataV2 {
  166. price_feed_id: PriceFeedId(1),
  167. source_timestamp_us: TimestampUs::from_micros(2),
  168. publisher_timestamp_us: TimestampUs::from_micros(3),
  169. price: Some(Price(4.try_into().unwrap())),
  170. best_bid_price: None,
  171. best_ask_price: None,
  172. funding_rate: Some(Rate(3 * 256 + 7)),
  173. };
  174. assert_eq!(
  175. bincode::deserialize::<PriceFeedDataV2>(&data2).unwrap(),
  176. expected2
  177. );
  178. assert_eq!(bincode::serialize(&expected2).unwrap(), data2);
  179. }