publisher.rs 7.3 KB

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